rapydscript-ns 0.8.4 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/.agignore +1 -1
  2. package/.github/workflows/ci.yml +38 -38
  3. package/=template.pyj +5 -5
  4. package/CHANGELOG.md +26 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/README.md +716 -169
  8. package/TODO.md +7 -2
  9. package/add-toc-to-readme +2 -2
  10. package/bin/export +75 -75
  11. package/bin/rapydscript +70 -70
  12. package/bin/web-repl-export +102 -102
  13. package/build +2 -2
  14. package/language-service/index.js +36 -27
  15. package/package.json +1 -1
  16. package/publish.py +37 -37
  17. package/release/baselib-plain-pretty.js +2358 -168
  18. package/release/baselib-plain-ugly.js +73 -3
  19. package/release/compiler.js +6283 -3093
  20. package/release/signatures.json +31 -30
  21. package/session.vim +4 -4
  22. package/setup.cfg +2 -2
  23. package/src/ast.pyj +1 -0
  24. package/src/baselib-builtins.pyj +340 -2
  25. package/src/baselib-bytes.pyj +664 -0
  26. package/src/baselib-errors.pyj +1 -1
  27. package/src/baselib-internal.pyj +267 -60
  28. package/src/baselib-itertools.pyj +110 -97
  29. package/src/baselib-str.pyj +22 -4
  30. package/src/compiler.pyj +36 -36
  31. package/src/errors.pyj +30 -30
  32. package/src/lib/abc.pyj +317 -0
  33. package/src/lib/aes.pyj +646 -646
  34. package/src/lib/contextlib.pyj +379 -0
  35. package/src/lib/copy.pyj +120 -120
  36. package/src/lib/dataclasses.pyj +532 -0
  37. package/src/lib/datetime.pyj +712 -0
  38. package/src/lib/elementmaker.pyj +83 -83
  39. package/src/lib/encodings.pyj +126 -126
  40. package/src/lib/enum.pyj +125 -0
  41. package/src/lib/gettext.pyj +569 -569
  42. package/src/lib/io.pyj +500 -0
  43. package/src/lib/itertools.pyj +580 -580
  44. package/src/lib/json.pyj +227 -0
  45. package/src/lib/math.pyj +193 -193
  46. package/src/lib/operator.pyj +11 -11
  47. package/src/lib/pythonize.pyj +20 -20
  48. package/src/lib/random.pyj +118 -118
  49. package/src/lib/re.pyj +504 -470
  50. package/src/lib/react.pyj +74 -74
  51. package/src/lib/traceback.pyj +63 -63
  52. package/src/lib/typing.pyj +577 -0
  53. package/src/lib/uuid.pyj +77 -77
  54. package/src/monaco-language-service/builtins.js +14 -4
  55. package/src/monaco-language-service/diagnostics.js +19 -20
  56. package/src/monaco-language-service/dts.js +550 -550
  57. package/src/output/classes.pyj +62 -26
  58. package/src/output/comments.pyj +45 -45
  59. package/src/output/exceptions.pyj +201 -201
  60. package/src/output/functions.pyj +78 -5
  61. package/src/output/jsx.pyj +164 -164
  62. package/src/output/loops.pyj +5 -2
  63. package/src/output/operators.pyj +100 -34
  64. package/src/output/treeshake.pyj +182 -182
  65. package/src/output/utils.pyj +72 -72
  66. package/src/parse.pyj +80 -16
  67. package/src/string_interpolation.pyj +72 -72
  68. package/src/tokenizer.pyj +10 -5
  69. package/src/unicode_aliases.pyj +576 -576
  70. package/src/utils.pyj +192 -192
  71. package/test/_import_one.pyj +37 -37
  72. package/test/_import_two/__init__.pyj +11 -11
  73. package/test/_import_two/level2/deep.pyj +4 -4
  74. package/test/_import_two/other.pyj +6 -6
  75. package/test/_import_two/sub.pyj +13 -13
  76. package/test/abc.pyj +291 -0
  77. package/test/aes_vectors.pyj +421 -421
  78. package/test/annotations.pyj +80 -80
  79. package/test/arithmetic_nostrict.pyj +88 -0
  80. package/test/arithmetic_types.pyj +169 -0
  81. package/test/baselib.pyj +91 -0
  82. package/test/bytes.pyj +467 -0
  83. package/test/classes.pyj +1 -0
  84. package/test/comparison_ops.pyj +173 -0
  85. package/test/contextlib.pyj +362 -0
  86. package/test/dataclasses.pyj +253 -0
  87. package/test/datetime.pyj +500 -0
  88. package/test/debugger_stmt.pyj +41 -0
  89. package/test/decorators.pyj +77 -77
  90. package/test/docstrings.pyj +39 -39
  91. package/test/elementmaker_test.pyj +45 -45
  92. package/test/enum.pyj +134 -0
  93. package/test/eval_exec.pyj +56 -0
  94. package/test/format.pyj +148 -0
  95. package/test/functions.pyj +151 -151
  96. package/test/generators.pyj +41 -41
  97. package/test/generic.pyj +370 -370
  98. package/test/imports.pyj +72 -72
  99. package/test/internationalization.pyj +73 -73
  100. package/test/io.pyj +316 -0
  101. package/test/json.pyj +196 -0
  102. package/test/lint.pyj +164 -164
  103. package/test/loops.pyj +85 -85
  104. package/test/numpy.pyj +734 -734
  105. package/test/object.pyj +64 -0
  106. package/test/omit_function_metadata.pyj +20 -20
  107. package/test/python_compat.pyj +17 -15
  108. package/test/python_features.pyj +70 -15
  109. package/test/regexp.pyj +83 -55
  110. package/test/repl.pyj +121 -121
  111. package/test/scoped_flags.pyj +76 -76
  112. package/test/tuples.pyj +96 -0
  113. package/test/typing.pyj +469 -0
  114. package/test/unit/index.js +116 -7
  115. package/test/unit/language-service-dts.js +543 -543
  116. package/test/unit/language-service-hover.js +455 -455
  117. package/test/unit/language-service.js +84 -0
  118. package/test/unit/web-repl.js +1337 -1
  119. package/test/vars_locals_globals.pyj +94 -0
  120. package/tools/cli.js +558 -547
  121. package/tools/compile.js +224 -219
  122. package/tools/completer.js +131 -131
  123. package/tools/embedded_compiler.js +262 -251
  124. package/tools/gettext.js +185 -185
  125. package/tools/ini.js +65 -65
  126. package/tools/lint.js +16 -19
  127. package/tools/msgfmt.js +187 -187
  128. package/tools/repl.js +223 -223
  129. package/tools/test.js +118 -118
  130. package/tools/utils.js +128 -128
  131. package/tools/web_repl.js +95 -95
  132. package/try +41 -41
  133. package/web-repl/env.js +196 -196
  134. package/web-repl/index.html +163 -163
  135. package/web-repl/main.js +252 -252
  136. package/web-repl/prism.css +139 -139
  137. package/web-repl/prism.js +113 -113
  138. package/web-repl/rapydscript.js +224 -224
  139. package/web-repl/sha1.js +25 -25
  140. package/PYTHON_DIFFERENCES_REPORT.md +0 -291
  141. package/PYTHON_FEATURE_COVERAGE.md +0 -200
@@ -0,0 +1,577 @@
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD
3
+ # RapydScript implementation of Python's typing standard library.
4
+ #
5
+ # Supported:
6
+ # TYPE_CHECKING, Any, Union, Optional, ClassVar, Final, Literal, NoReturn,
7
+ # List, Dict, Set, FrozenSet, Tuple, Type, Callable,
8
+ # Iterator, Iterable, Generator, Sequence, MutableSequence,
9
+ # Mapping, MutableMapping, Awaitable, Coroutine,
10
+ # AsyncGenerator, AsyncIterator, AsyncIterable,
11
+ # IO, TextIO, BinaryIO, Pattern, Match,
12
+ # TypeVar, Generic, Protocol,
13
+ # cast, overload, no_type_check, no_type_check_decorator,
14
+ # runtime_checkable, get_type_hints,
15
+ # TypedDict, NamedTuple, AnyStr, ByteString, Text
16
+ #
17
+ # Type annotations are not enforced at runtime. All typing constructs
18
+ # transpile to lightweight JavaScript objects that carry the same
19
+ # introspection attributes (__origin__, __args__, _name) as their
20
+ # CPython equivalents, so that annotation-aware code works identically.
21
+
22
+
23
+ # ── Constants ──────────────────────────────────────────────────────────────────
24
+
25
+ # Always False at runtime; True only when a static type-checker is running.
26
+ TYPE_CHECKING = False
27
+
28
+
29
+ # ── Internal representation ────────────────────────────────────────────────────
30
+
31
+ class _GenericAlias:
32
+ """Represents a parameterized generic type such as List[int] or Dict[str, int].
33
+
34
+ Attributes:
35
+ __origin__ The origin type (list, dict, …) or None for abstract types.
36
+ __args__ Tuple of type arguments; empty tuple when not parameterised.
37
+ _name Display name used in repr().
38
+ """
39
+
40
+ def __init__(self, origin, args, name=None):
41
+ self.__origin__ = origin
42
+ if args is None:
43
+ self.__args__ = []
44
+ elif Array.isArray(args):
45
+ self.__args__ = args
46
+ else:
47
+ self.__args__ = [args]
48
+ self._name = name
49
+ # Allow _GenericAlias to be used as a base class in `class Foo(Generic[T])`.
50
+ # ρσ_extends reads parent.prototype, so we proxy it to the origin's prototype.
51
+ if origin and jstype(origin.prototype) is not 'undefined':
52
+ self.prototype = origin.prototype
53
+
54
+ def __repr__(self):
55
+ if self._name:
56
+ base = 'typing.' + self._name
57
+ else:
58
+ base = 'typing._GenericAlias'
59
+ if self.__args__:
60
+ parts = []
61
+ for a in self.__args__:
62
+ if a is None:
63
+ parts.append('None')
64
+ elif jstype(a.__name__) is 'string' and a.__name__:
65
+ parts.append(a.__name__)
66
+ else:
67
+ parts.append(repr(a))
68
+ return base + '[' + parts.join(', ') + ']'
69
+ return base
70
+
71
+
72
+ # ── Special forms ──────────────────────────────────────────────────────────────
73
+
74
+ class Any:
75
+ """Special form: matches any type. Every type is compatible with Any."""
76
+
77
+ def __repr__(self):
78
+ return 'typing.Any'
79
+
80
+
81
+ class Union:
82
+ """Union[X, Y] means either type X or type Y.
83
+
84
+ Example::
85
+
86
+ from typing import Union
87
+ def f(x: Union[str, int]) -> None: ...
88
+ """
89
+
90
+ def __class_getitem__(cls, params):
91
+ if not Array.isArray(params):
92
+ params = [params]
93
+ return _GenericAlias(None, params, 'Union')
94
+
95
+
96
+ class Optional:
97
+ """Optional[X] is shorthand for Union[X, None].
98
+
99
+ Example::
100
+
101
+ from typing import Optional
102
+ def f(x: Optional[str] = None) -> Optional[int]: ...
103
+ """
104
+
105
+ def __class_getitem__(cls, params):
106
+ return _GenericAlias(None, [params, None], 'Optional')
107
+
108
+
109
+ class ClassVar:
110
+ """ClassVar[T] marks that a variable is intended as a class variable."""
111
+
112
+ def __class_getitem__(cls, params):
113
+ if not Array.isArray(params):
114
+ params = [params]
115
+ return _GenericAlias(None, params, 'ClassVar')
116
+
117
+
118
+ class Final:
119
+ """Final[T] marks that a variable may not be reassigned after first assignment."""
120
+
121
+ def __class_getitem__(cls, params):
122
+ if not Array.isArray(params):
123
+ params = [params]
124
+ return _GenericAlias(None, params, 'Final')
125
+
126
+
127
+ class Literal:
128
+ """Literal[v, …] marks a type that may only take one of the given literal values.
129
+
130
+ Example::
131
+
132
+ from typing import Literal
133
+ Mode = Literal['r', 'w', 'a']
134
+ """
135
+
136
+ def __class_getitem__(cls, params):
137
+ if not Array.isArray(params):
138
+ params = [params]
139
+ return _GenericAlias(None, params, 'Literal')
140
+
141
+
142
+ class NoReturn:
143
+ """NoReturn marks a function that never returns normally."""
144
+ pass
145
+
146
+
147
+ # ── Concrete generic aliases ───────────────────────────────────────────────────
148
+
149
+ class List:
150
+ """Generic alias for the built-in list type.
151
+
152
+ Example::
153
+
154
+ from typing import List
155
+ def f(xs: List[int]) -> List[str]: ...
156
+ """
157
+
158
+ def __class_getitem__(cls, params):
159
+ if not Array.isArray(params):
160
+ params = [params]
161
+ return _GenericAlias(list, params, 'List')
162
+
163
+
164
+ class Dict:
165
+ """Generic alias for the built-in dict type."""
166
+
167
+ def __class_getitem__(cls, params):
168
+ if not Array.isArray(params):
169
+ params = [params]
170
+ return _GenericAlias(dict, params, 'Dict')
171
+
172
+
173
+ class Set:
174
+ """Generic alias for the built-in set type."""
175
+
176
+ def __class_getitem__(cls, params):
177
+ if not Array.isArray(params):
178
+ params = [params]
179
+ return _GenericAlias(set, params, 'Set')
180
+
181
+
182
+ class FrozenSet:
183
+ """Generic alias for the built-in frozenset type."""
184
+
185
+ def __class_getitem__(cls, params):
186
+ if not Array.isArray(params):
187
+ params = [params]
188
+ return _GenericAlias(frozenset, params, 'FrozenSet')
189
+
190
+
191
+ class Tuple:
192
+ """Generic alias for the built-in tuple type.
193
+
194
+ Use Tuple[X, Y] for a two-element tuple or Tuple[X, ...] for a
195
+ variable-length homogeneous tuple.
196
+ """
197
+
198
+ def __class_getitem__(cls, params):
199
+ if not Array.isArray(params):
200
+ params = [params]
201
+ return _GenericAlias(tuple, params, 'Tuple')
202
+
203
+
204
+ class Type:
205
+ """Type[C] represents the class C itself rather than an instance of C."""
206
+
207
+ def __class_getitem__(cls, params):
208
+ if not Array.isArray(params):
209
+ params = [params]
210
+ return _GenericAlias(type, params, 'Type')
211
+
212
+
213
+ class Callable:
214
+ """Callable[[ArgType, …], ReturnType] — any callable object.
215
+
216
+ Example::
217
+
218
+ from typing import Callable
219
+ f: Callable[[int, str], bool]
220
+ """
221
+
222
+ def __class_getitem__(cls, params):
223
+ if not Array.isArray(params):
224
+ params = [params]
225
+ return _GenericAlias(None, params, 'Callable')
226
+
227
+
228
+ # ── Abstract-base / protocol aliases ──────────────────────────────────────────
229
+
230
+ class Iterator:
231
+ """Generic alias for an iterator (has __next__)."""
232
+
233
+ def __class_getitem__(cls, params):
234
+ if not Array.isArray(params):
235
+ params = [params]
236
+ return _GenericAlias(None, params, 'Iterator')
237
+
238
+
239
+ class Iterable:
240
+ """Generic alias for an iterable (has __iter__)."""
241
+
242
+ def __class_getitem__(cls, params):
243
+ if not Array.isArray(params):
244
+ params = [params]
245
+ return _GenericAlias(None, params, 'Iterable')
246
+
247
+
248
+ class Generator:
249
+ """Generic alias for a generator (yield / send / throw)."""
250
+
251
+ def __class_getitem__(cls, params):
252
+ if not Array.isArray(params):
253
+ params = [params]
254
+ return _GenericAlias(None, params, 'Generator')
255
+
256
+
257
+ class Sequence:
258
+ """Generic alias for a read-only sequence."""
259
+
260
+ def __class_getitem__(cls, params):
261
+ if not Array.isArray(params):
262
+ params = [params]
263
+ return _GenericAlias(None, params, 'Sequence')
264
+
265
+
266
+ class MutableSequence:
267
+ """Generic alias for a mutable sequence."""
268
+
269
+ def __class_getitem__(cls, params):
270
+ if not Array.isArray(params):
271
+ params = [params]
272
+ return _GenericAlias(None, params, 'MutableSequence')
273
+
274
+
275
+ class Mapping:
276
+ """Generic alias for a read-only key-value mapping."""
277
+
278
+ def __class_getitem__(cls, params):
279
+ if not Array.isArray(params):
280
+ params = [params]
281
+ return _GenericAlias(None, params, 'Mapping')
282
+
283
+
284
+ class MutableMapping:
285
+ """Generic alias for a mutable key-value mapping."""
286
+
287
+ def __class_getitem__(cls, params):
288
+ if not Array.isArray(params):
289
+ params = [params]
290
+ return _GenericAlias(None, params, 'MutableMapping')
291
+
292
+
293
+ class Awaitable:
294
+ """Generic alias for an awaitable object."""
295
+
296
+ def __class_getitem__(cls, params):
297
+ if not Array.isArray(params):
298
+ params = [params]
299
+ return _GenericAlias(None, params, 'Awaitable')
300
+
301
+
302
+ class Coroutine:
303
+ """Generic alias for a coroutine."""
304
+
305
+ def __class_getitem__(cls, params):
306
+ if not Array.isArray(params):
307
+ params = [params]
308
+ return _GenericAlias(None, params, 'Coroutine')
309
+
310
+
311
+ class AsyncGenerator:
312
+ """Generic alias for an async generator."""
313
+
314
+ def __class_getitem__(cls, params):
315
+ if not Array.isArray(params):
316
+ params = [params]
317
+ return _GenericAlias(None, params, 'AsyncGenerator')
318
+
319
+
320
+ class AsyncIterator:
321
+ """Generic alias for an async iterator."""
322
+
323
+ def __class_getitem__(cls, params):
324
+ if not Array.isArray(params):
325
+ params = [params]
326
+ return _GenericAlias(None, params, 'AsyncIterator')
327
+
328
+
329
+ class AsyncIterable:
330
+ """Generic alias for an async iterable."""
331
+
332
+ def __class_getitem__(cls, params):
333
+ if not Array.isArray(params):
334
+ params = [params]
335
+ return _GenericAlias(None, params, 'AsyncIterable')
336
+
337
+
338
+ # ── IO type aliases ────────────────────────────────────────────────────────────
339
+
340
+ class IO:
341
+ """Generic IO type; IO[str] for text or IO[bytes] for binary."""
342
+
343
+ def __class_getitem__(cls, params):
344
+ if not Array.isArray(params):
345
+ params = [params]
346
+ return _GenericAlias(None, params, 'IO')
347
+
348
+
349
+ class TextIO:
350
+ """Text-mode IO stream (IO[str])."""
351
+ pass
352
+
353
+
354
+ class BinaryIO:
355
+ """Binary-mode IO stream (IO[bytes])."""
356
+ pass
357
+
358
+
359
+ # ── Pattern / Match aliases (for re module) ────────────────────────────────────
360
+
361
+ class Pattern:
362
+ """Generic alias for compiled regular-expression pattern objects."""
363
+
364
+ def __class_getitem__(cls, params):
365
+ if not Array.isArray(params):
366
+ params = [params]
367
+ return _GenericAlias(None, params, 'Pattern')
368
+
369
+
370
+ class Match:
371
+ """Generic alias for regular-expression match objects."""
372
+
373
+ def __class_getitem__(cls, params):
374
+ if not Array.isArray(params):
375
+ params = [params]
376
+ return _GenericAlias(None, params, 'Match')
377
+
378
+
379
+ # ── TypeVar ────────────────────────────────────────────────────────────────────
380
+
381
+ class TypeVar:
382
+ """Type variable. Used to parameterise generic classes and functions.
383
+
384
+ Example::
385
+
386
+ from typing import TypeVar
387
+ T = TypeVar('T')
388
+ S = TypeVar('S', str, bytes) # constrained TypeVar
389
+ """
390
+
391
+ def __init__(self, name, *constraints):
392
+ self.__name__ = name
393
+ self.__constraints__ = constraints
394
+ self.__bound__ = None
395
+ self.__covariant__ = False
396
+ self.__contravariant__ = False
397
+
398
+ def __repr__(self):
399
+ return '~' + self.__name__
400
+
401
+
402
+ # ── Generic and Protocol base classes ─────────────────────────────────────────
403
+
404
+ class Generic:
405
+ """Base class for generic classes.
406
+
407
+ Example::
408
+
409
+ from typing import Generic, TypeVar
410
+ T = TypeVar('T')
411
+ class Stack(Generic[T]):
412
+ def push(self, item: T) -> None: ...
413
+ def pop(self) -> T: ...
414
+ """
415
+
416
+ def __class_getitem__(cls, params):
417
+ if not Array.isArray(params):
418
+ params = [params]
419
+ return _GenericAlias(cls, params)
420
+
421
+
422
+ class Protocol:
423
+ """Base class for protocol classes (structural subtyping).
424
+
425
+ Example::
426
+
427
+ from typing import Protocol, runtime_checkable
428
+ @runtime_checkable
429
+ class Drawable(Protocol):
430
+ def draw(self) -> None: ...
431
+ """
432
+
433
+ def __class_getitem__(cls, params):
434
+ if not Array.isArray(params):
435
+ params = [params]
436
+ return _GenericAlias(cls, params)
437
+
438
+
439
+ # ── Utility functions and decorators ──────────────────────────────────────────
440
+
441
+ def cast(typ, val):
442
+ """Cast *val* to type *typ*.
443
+
444
+ At runtime this is a no-op: *val* is returned unchanged. Type checkers
445
+ treat the result as having type *typ*.
446
+ """
447
+ return val
448
+
449
+
450
+ def overload(func):
451
+ """Decorator for overloaded function definitions.
452
+
453
+ Returns *func* unchanged; the last non-``@overload``-decorated definition
454
+ is the one called at runtime.
455
+ """
456
+ return func
457
+
458
+
459
+ def no_type_check(arg):
460
+ """Decorator to opt a function or class out of type checking."""
461
+ return arg
462
+
463
+
464
+ def no_type_check_decorator(decorator):
465
+ """Decorator that disables type checking for the decorated decorator."""
466
+ return decorator
467
+
468
+
469
+ def runtime_checkable(cls):
470
+ """Decorator to mark a Protocol as runtime-checkable via isinstance()."""
471
+ return cls
472
+
473
+
474
+ def get_type_hints(obj, globalns=None, localns=None):
475
+ """Return the type hints for *obj* (a function, method, module, or class).
476
+
477
+ Returns a copy of ``obj.__annotations__``, or an empty dict when the
478
+ object carries no annotations.
479
+ """
480
+ a = obj.__annotations__
481
+ if jstype(a) is 'undefined' or a is None:
482
+ return {}
483
+ result = {}
484
+ keys = Object.keys(a)
485
+ for i in range(keys.length):
486
+ k = keys[i]
487
+ result[k] = a[k]
488
+ return result
489
+
490
+
491
+ # ── TypedDict ──────────────────────────────────────────────────────────────────
492
+
493
+ class TypedDict:
494
+ """Base class for typed dictionaries (class-based syntax).
495
+
496
+ Example::
497
+
498
+ from typing import TypedDict
499
+
500
+ class Movie(TypedDict):
501
+ name: str
502
+ year: int
503
+
504
+ At runtime, TypedDict subclasses are plain classes; no type enforcement
505
+ occurs. Fields are declared via class-body annotations and accessible
506
+ via normal attribute access on instances.
507
+ """
508
+ pass
509
+
510
+
511
+ # ── NamedTuple factory (functional form) ───────────────────────────────────────
512
+
513
+ def NamedTuple(typename, fields):
514
+ """Create a typed named-tuple class (functional form).
515
+
516
+ *fields* is a list of (name, type) pairs::
517
+
518
+ from typing import NamedTuple
519
+ Point = NamedTuple('Point', [('x', float), ('y', float)])
520
+ p = Point(1.0, 2.0)
521
+ print(p.x) # 1.0
522
+ print(p.y) # 2.0
523
+
524
+ The returned class stores fields as plain attributes, carries a
525
+ ``__annotations__`` dict of name → type, and supports positional
526
+ construction.
527
+ """
528
+ field_names = [f[0] for f in fields]
529
+ annotations = {f[0]: f[1] for f in fields}
530
+ n = len(field_names)
531
+
532
+ class _NT:
533
+ def __init__(self, *args):
534
+ for i in range(n):
535
+ name = field_names[i]
536
+ val = args[i] if i < args.length else None
537
+ v'this[name] = val'
538
+
539
+ def __getitem__(self, idx):
540
+ if idx < 0:
541
+ idx = n + idx
542
+ if idx < 0 or idx >= n:
543
+ raise IndexError('tuple index out of range')
544
+ return v'this[field_names[idx]]'
545
+
546
+ def __repr__(self):
547
+ parts = []
548
+ for i in range(n):
549
+ val = v'this[field_names[i]]'
550
+ parts.append(repr(val))
551
+ return typename + '(' + ', '.join(parts) + ')'
552
+
553
+ _NT.__name__ = typename
554
+ _NT.__annotations__ = annotations
555
+ return _NT
556
+
557
+
558
+ # ── ByteString ─────────────────────────────────────────────────────────────────
559
+
560
+ class ByteString:
561
+ """Type covering bytes-like objects: bytes and bytearray.
562
+
563
+ Use as a type annotation when a function accepts any bytes-like object::
564
+
565
+ from typing import ByteString
566
+ def process(data: ByteString) -> None: ...
567
+ """
568
+ pass
569
+
570
+
571
+ # ── Convenience aliases ────────────────────────────────────────────────────────
572
+
573
+ # AnyStr: a TypeVar constrained to str or bytes
574
+ AnyStr = TypeVar('AnyStr', str, bytes)
575
+
576
+ # Python 2 → Python 3 compatibility alias
577
+ Text = str