rapydscript-ns 0.8.3 → 0.9.0
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.
- package/CHANGELOG.md +26 -0
- package/README.md +1351 -141
- package/TODO.md +12 -6
- package/language-service/index.js +184 -26
- package/package.json +1 -1
- package/release/baselib-plain-pretty.js +5895 -1928
- package/release/baselib-plain-ugly.js +140 -3
- package/release/compiler.js +16282 -5408
- package/release/signatures.json +25 -22
- package/src/ast.pyj +94 -1
- package/src/baselib-builtins.pyj +362 -3
- package/src/baselib-bytes.pyj +664 -0
- package/src/baselib-containers.pyj +99 -0
- package/src/baselib-errors.pyj +45 -1
- package/src/baselib-internal.pyj +346 -49
- package/src/baselib-itertools.pyj +17 -4
- package/src/baselib-str.pyj +46 -4
- package/src/lib/abc.pyj +317 -0
- package/src/lib/copy.pyj +120 -0
- package/src/lib/dataclasses.pyj +532 -0
- package/src/lib/enum.pyj +125 -0
- package/src/lib/pythonize.pyj +1 -1
- package/src/lib/re.pyj +35 -1
- package/src/lib/react.pyj +74 -0
- package/src/lib/typing.pyj +577 -0
- package/src/monaco-language-service/builtins.js +19 -4
- package/src/monaco-language-service/diagnostics.js +40 -19
- package/src/output/classes.pyj +161 -25
- package/src/output/codegen.pyj +16 -2
- package/src/output/exceptions.pyj +97 -1
- package/src/output/functions.pyj +87 -5
- package/src/output/jsx.pyj +164 -0
- package/src/output/literals.pyj +28 -2
- package/src/output/loops.pyj +5 -2
- package/src/output/modules.pyj +1 -1
- package/src/output/operators.pyj +108 -36
- package/src/output/statements.pyj +2 -2
- package/src/output/stream.pyj +1 -0
- package/src/parse.pyj +496 -128
- package/src/tokenizer.pyj +38 -4
- package/test/abc.pyj +291 -0
- package/test/arithmetic_nostrict.pyj +88 -0
- package/test/arithmetic_types.pyj +169 -0
- package/test/baselib.pyj +91 -0
- package/test/bytes.pyj +467 -0
- package/test/classes.pyj +1 -0
- package/test/comparison_ops.pyj +173 -0
- package/test/dataclasses.pyj +253 -0
- package/test/enum.pyj +134 -0
- package/test/eval_exec.pyj +56 -0
- package/test/format.pyj +148 -0
- package/test/object.pyj +64 -0
- package/test/python_compat.pyj +17 -15
- package/test/python_features.pyj +89 -21
- package/test/regexp.pyj +29 -1
- package/test/tuples.pyj +96 -0
- package/test/typing.pyj +469 -0
- package/test/unit/index.js +2292 -70
- package/test/unit/language-service.js +674 -4
- package/test/unit/web-repl.js +1106 -0
- package/test/vars_locals_globals.pyj +94 -0
- package/tools/cli.js +11 -0
- package/tools/compile.js +5 -0
- package/tools/embedded_compiler.js +15 -4
- package/tools/lint.js +16 -19
- package/tools/repl.js +1 -1
- package/web-repl/env.js +122 -0
- package/web-repl/main.js +1 -3
- package/web-repl/rapydscript.js +125 -3
- package/PYTHON_DIFFERENCES_REPORT.md +0 -291
- package/PYTHON_FEATURE_COVERAGE.md +0 -200
- package/hack_demo.pyj +0 -112
|
@@ -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
|
|
@@ -79,6 +79,11 @@ const STUBS = [
|
|
|
79
79
|
return_type: 'str',
|
|
80
80
|
doc: 'Return the string representing a character at Unicode code point i.' }),
|
|
81
81
|
|
|
82
|
+
new BuiltinInfo({ name: 'complex', kind: 'class',
|
|
83
|
+
params: [p('real_or_string', { optional: true }), p('imag', { type: 'number', optional: true })],
|
|
84
|
+
return_type: 'complex',
|
|
85
|
+
doc: 'Create a complex number.\n\nForms:\n- `complex()` → `0j`\n- `complex(x)` → `x+0j` (from int/float/bool/complex), or parse Python complex string\n- `complex(real, imag)` → `real + imag*j`\n\nLiteral syntax: `4j` is equivalent to `complex(0, 4)`, and `3+4j` creates a complex number via addition.\n\nAttributes:\n- `.real` — the real part (float)\n- `.imag` — the imaginary part (float)\n\nMethods:\n- `.conjugate()` — return the complex conjugate `(real - imag*j)`\n\nSupports: `+`, `-`, `*`, `/`, `**`, unary `-`/`+`, `abs()`, `bool()`, `==`, `repr()`, `str()`.\n\nExample:\n\n c = complex(3, 4)\n c.real # 3\n c.imag # 4\n abs(c) # 5.0\n c.conjugate() # (3-4j)\n c * complex(1, 2) # (-5+10j)\n 3 + 4j # (3+4j) — literal syntax' }),
|
|
86
|
+
|
|
82
87
|
new BuiltinInfo({ name: 'dict', kind: 'class',
|
|
83
88
|
params: [p('**kwargs', { rest: true })],
|
|
84
89
|
return_type: 'dict',
|
|
@@ -112,7 +117,7 @@ const STUBS = [
|
|
|
112
117
|
new BuiltinInfo({ name: 'float', kind: 'class',
|
|
113
118
|
params: [p('x', { optional: true })],
|
|
114
119
|
return_type: 'float',
|
|
115
|
-
doc: 'Return a floating-point number from x.' }),
|
|
120
|
+
doc: 'Return a floating-point number from x.\n\nInstance method:\n- `.is_integer()` — return `True` if the float has no fractional part (i.e. is a whole number), `False` otherwise. `Infinity` and `NaN` return `False`.\n\nExample:\n\n (1.0).is_integer() # True\n (1.5).is_integer() # False\n (1e10).is_integer() # True' }),
|
|
116
121
|
|
|
117
122
|
new BuiltinInfo({ name: 'getattr',
|
|
118
123
|
params: [p('obj'), p('name', { type: 'str' }), p('default', { optional: true })],
|
|
@@ -142,7 +147,7 @@ const STUBS = [
|
|
|
142
147
|
new BuiltinInfo({ name: 'int', kind: 'class',
|
|
143
148
|
params: [p('x', { optional: true }), p('base', { type: 'int', optional: true })],
|
|
144
149
|
return_type: 'int',
|
|
145
|
-
doc: 'Return an integer from x, optionally in the given base.' }),
|
|
150
|
+
doc: 'Return an integer from x, optionally in the given base.\n\nInstance method:\n- `.bit_length()` — return the number of bits needed to represent the integer in binary, excluding the sign and leading zeros. Equivalent to `floor(log2(abs(n))) + 1` for nonzero `n`; returns `0` for `0`.\n\nExample:\n\n (0).bit_length() # 0\n (1).bit_length() # 1\n (255).bit_length() # 8\n (256).bit_length() # 9\n (-5).bit_length() # 3 (sign ignored)' }),
|
|
146
151
|
|
|
147
152
|
new BuiltinInfo({ name: 'isinstance',
|
|
148
153
|
params: [p('obj'), p('classinfo')],
|
|
@@ -169,6 +174,16 @@ const STUBS = [
|
|
|
169
174
|
return_type: 'list',
|
|
170
175
|
doc: 'Create a list from an iterable, or an empty list.' }),
|
|
171
176
|
|
|
177
|
+
new BuiltinInfo({ name: 'next',
|
|
178
|
+
params: [p('iterator'), p('default', { optional: true })],
|
|
179
|
+
return_type: 'any',
|
|
180
|
+
doc: 'Retrieve the next item from an iterator. If the iterator is exhausted, return default; if default is not given, raise StopIteration.' }),
|
|
181
|
+
|
|
182
|
+
new BuiltinInfo({ name: 'object', kind: 'class',
|
|
183
|
+
params: [],
|
|
184
|
+
return_type: 'object',
|
|
185
|
+
doc: 'Create a new featureless base object instance.\n\nThe base class of all Python classes. Calling `object()` with no arguments returns a new, unique instance useful as a sentinel value:\n\n MISSING = object() # unique sentinel\n if value is MISSING:\n ...\n\nKey behaviours:\n- Each call returns a distinct instance (`object() is not object()`).\n- `isinstance(x, object)` returns `True` for any `object()` instance (and subclasses).\n- `class Foo(object):` works as an explicit base class.\n- `repr()` returns `\'<object object at 0x…>\'`.\n- `hash()` returns a stable identity hash.\n\nNote: unlike Python, you *can* add arbitrary attributes to an `object()` instance in RapydScript (JS objects are open by default).' }),
|
|
186
|
+
|
|
172
187
|
new BuiltinInfo({ name: 'map',
|
|
173
188
|
params: [p('function'), p('iterable'), p('*iterables', { rest: true })],
|
|
174
189
|
return_type: 'iterable',
|
|
@@ -260,9 +275,9 @@ const STUBS = [
|
|
|
260
275
|
doc: 'Return the type of an object.' }),
|
|
261
276
|
|
|
262
277
|
new BuiltinInfo({ name: 'zip',
|
|
263
|
-
params: [p('*iterables', { rest: true })],
|
|
278
|
+
params: [p('*iterables', { rest: true }), p('strict', { optional: true })],
|
|
264
279
|
return_type: 'iterable',
|
|
265
|
-
doc: 'Return an iterator of tuples, where each tuple groups the i-th element from each iterable.' }),
|
|
280
|
+
doc: 'Return an iterator of tuples, where each tuple groups the i-th element from each iterable. With strict=True, raises ValueError if the iterables have different lengths.' }),
|
|
266
281
|
|
|
267
282
|
// ── RapydScript-specific ──────────────────────────────────────────────
|
|
268
283
|
new BuiltinInfo({ name: 'jstype',
|