pyodide-py 0.26.0.dev0__tar.gz → 0.26.2__tar.gz
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.
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/PKG-INFO +1 -1
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/_pyodide/_base.py +25 -1
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/_pyodide/_core_docs.py +61 -53
- pyodide_py-0.26.2/_pyodide/_future_helper.py +14 -0
- pyodide_py-0.26.2/_pyodide/jsbind.py +228 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/__init__.py +1 -1
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/console.py +42 -13
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/ffi/__init__.py +2 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/webloop.py +13 -15
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide_py.egg-info/PKG-INFO +1 -1
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide_py.egg-info/SOURCES.txt +2 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyproject.toml +1 -1
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/README.md +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/_pyodide/__init__.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/_pyodide/_importhook.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/_pyodide/docs_argspec.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/_pyodide/docstring.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/_pyodide/py.typed +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/_core.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/_package_loader.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/_run_js.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/_state.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/code.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/ffi/wrappers.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/http.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide/py.typed +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide_py.egg-info/dependency_links.txt +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/pyodide_py.egg-info/top_level.txt +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/setup.cfg +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/setup.py +0 -0
- {pyodide-py-0.26.0.dev0 → pyodide_py-0.26.2}/webbrowser.py +0 -0
|
@@ -132,6 +132,8 @@ def _parse_and_compile_gen(
|
|
|
132
132
|
mode: str = "exec",
|
|
133
133
|
filename: str = "<exec>",
|
|
134
134
|
flags: int = 0x0,
|
|
135
|
+
dont_inherit: bool = False,
|
|
136
|
+
optimize: int = -1,
|
|
135
137
|
) -> Generator[ast.Module, ast.Module, CodeType]:
|
|
136
138
|
"""Parse ``source``, then yield the AST, then compile the AST and return the
|
|
137
139
|
code object.
|
|
@@ -160,7 +162,7 @@ def _parse_and_compile_gen(
|
|
|
160
162
|
_last_expr_to_raise(mod)
|
|
161
163
|
|
|
162
164
|
ast.fix_missing_locations(mod)
|
|
163
|
-
return compile(mod, filename, mode, flags
|
|
165
|
+
return compile(mod, filename, mode, flags, dont_inherit, optimize)
|
|
164
166
|
|
|
165
167
|
|
|
166
168
|
ReturnMode = Literal["last_expr", "last_expr_or_assign", "none"]
|
|
@@ -214,6 +216,16 @@ class CodeRunner:
|
|
|
214
216
|
The flags to compile with. See the documentation for the built-in
|
|
215
217
|
:external:py:func:`compile` function.
|
|
216
218
|
|
|
219
|
+
dont_inherit :
|
|
220
|
+
|
|
221
|
+
Whether to inherit ``__future__`` imports from the outer code.
|
|
222
|
+
See the documentation for the built-in :external:py:func:`compile` function.
|
|
223
|
+
|
|
224
|
+
optimize :
|
|
225
|
+
|
|
226
|
+
Specifies the optimization level of the compiler. See the documentation
|
|
227
|
+
for the built-in :external:py:func:`compile` function.
|
|
228
|
+
|
|
217
229
|
Examples
|
|
218
230
|
--------
|
|
219
231
|
>>> source = "1 + 1"
|
|
@@ -254,6 +266,8 @@ class CodeRunner:
|
|
|
254
266
|
quiet_trailing_semicolon: bool = True,
|
|
255
267
|
filename: str = "<exec>",
|
|
256
268
|
flags: int = 0x0,
|
|
269
|
+
dont_inherit: bool = False,
|
|
270
|
+
optimize: int = -1,
|
|
257
271
|
):
|
|
258
272
|
self._compiled = False
|
|
259
273
|
self._source = source
|
|
@@ -264,6 +278,8 @@ class CodeRunner:
|
|
|
264
278
|
quiet_trailing_semicolon=quiet_trailing_semicolon,
|
|
265
279
|
filename=filename,
|
|
266
280
|
flags=flags,
|
|
281
|
+
dont_inherit=dont_inherit,
|
|
282
|
+
optimize=optimize,
|
|
267
283
|
)
|
|
268
284
|
self.ast = next(self._gen)
|
|
269
285
|
|
|
@@ -407,6 +423,8 @@ def eval_code(
|
|
|
407
423
|
quiet_trailing_semicolon: bool = True,
|
|
408
424
|
filename: str = "<exec>",
|
|
409
425
|
flags: int = 0x0,
|
|
426
|
+
dont_inherit: bool = False,
|
|
427
|
+
optimize: int = -1,
|
|
410
428
|
) -> Any:
|
|
411
429
|
"""Runs a string as Python source code.
|
|
412
430
|
|
|
@@ -497,6 +515,8 @@ def eval_code(
|
|
|
497
515
|
quiet_trailing_semicolon=quiet_trailing_semicolon,
|
|
498
516
|
filename=filename,
|
|
499
517
|
flags=flags,
|
|
518
|
+
dont_inherit=dont_inherit,
|
|
519
|
+
optimize=optimize,
|
|
500
520
|
)
|
|
501
521
|
.compile()
|
|
502
522
|
.run(globals, locals)
|
|
@@ -512,6 +532,8 @@ async def eval_code_async(
|
|
|
512
532
|
quiet_trailing_semicolon: bool = True,
|
|
513
533
|
filename: str = "<exec>",
|
|
514
534
|
flags: int = 0x0,
|
|
535
|
+
dont_inherit: bool = False,
|
|
536
|
+
optimize: int = -1,
|
|
515
537
|
) -> Any:
|
|
516
538
|
"""Runs a code string asynchronously.
|
|
517
539
|
|
|
@@ -577,6 +599,8 @@ async def eval_code_async(
|
|
|
577
599
|
quiet_trailing_semicolon=quiet_trailing_semicolon,
|
|
578
600
|
filename=filename,
|
|
579
601
|
flags=flags,
|
|
602
|
+
dont_inherit=dont_inherit,
|
|
603
|
+
optimize=optimize,
|
|
580
604
|
)
|
|
581
605
|
.compile()
|
|
582
606
|
.run_async(globals, locals)
|
|
@@ -116,6 +116,16 @@ class JsProxy(metaclass=_JsProxyMetaClass):
|
|
|
116
116
|
return super().__new__(cls)
|
|
117
117
|
raise TypeError(f"{cls.__name__} cannot be instantiated.")
|
|
118
118
|
|
|
119
|
+
def bind_sig(self, signature: Any) -> "JsProxy":
|
|
120
|
+
"""Creates a copy of the JsProxy with a signature bound to it.
|
|
121
|
+
|
|
122
|
+
.. admonition:: Experimental
|
|
123
|
+
:class: warning
|
|
124
|
+
|
|
125
|
+
This feature is not yet stable, nor really documented.
|
|
126
|
+
"""
|
|
127
|
+
return self
|
|
128
|
+
|
|
119
129
|
@property
|
|
120
130
|
def js_id(self) -> int:
|
|
121
131
|
"""An id number which can be used as a dictionary/set key if you want to
|
|
@@ -365,14 +375,12 @@ class JsPromise(JsProxy, Generic[T]):
|
|
|
365
375
|
@overload
|
|
366
376
|
def then(
|
|
367
377
|
self, onfulfilled: None, onrejected: Callable[[BaseException], Awaitable[S]], /
|
|
368
|
-
) -> "JsPromise[S]":
|
|
369
|
-
...
|
|
378
|
+
) -> "JsPromise[S]": ...
|
|
370
379
|
|
|
371
380
|
@overload
|
|
372
381
|
def then(
|
|
373
382
|
self, onfulfilled: None, onrejected: Callable[[BaseException], S], /
|
|
374
|
-
) -> "JsPromise[S]":
|
|
375
|
-
...
|
|
383
|
+
) -> "JsPromise[S]": ...
|
|
376
384
|
|
|
377
385
|
@overload
|
|
378
386
|
def then(
|
|
@@ -380,8 +388,7 @@ class JsPromise(JsProxy, Generic[T]):
|
|
|
380
388
|
onfulfilled: Callable[[T], Awaitable[S]],
|
|
381
389
|
onrejected: Callable[[BaseException], Awaitable[S]] | None = None,
|
|
382
390
|
/,
|
|
383
|
-
) -> "JsPromise[S]":
|
|
384
|
-
...
|
|
391
|
+
) -> "JsPromise[S]": ...
|
|
385
392
|
|
|
386
393
|
@overload
|
|
387
394
|
def then(
|
|
@@ -389,8 +396,7 @@ class JsPromise(JsProxy, Generic[T]):
|
|
|
389
396
|
onfulfilled: Callable[[T], S],
|
|
390
397
|
onrejected: Callable[[BaseException], S] | None = None,
|
|
391
398
|
/,
|
|
392
|
-
) -> "JsPromise[S]":
|
|
393
|
-
...
|
|
399
|
+
) -> "JsPromise[S]": ...
|
|
394
400
|
|
|
395
401
|
@docs_argspec(
|
|
396
402
|
"(self, onfulfilled: Callable[[T], Awaitable[S] | S] | None, onrejected: Callable[[BaseException], Awaitable[S] | S] | None = None, /) -> 'JsPromise[S]'"
|
|
@@ -410,12 +416,10 @@ class JsPromise(JsProxy, Generic[T]):
|
|
|
410
416
|
@overload
|
|
411
417
|
def catch(
|
|
412
418
|
self, onrejected: Callable[[BaseException], Awaitable[S]], /
|
|
413
|
-
) -> "JsPromise[S]":
|
|
414
|
-
...
|
|
419
|
+
) -> "JsPromise[S]": ...
|
|
415
420
|
|
|
416
421
|
@overload
|
|
417
|
-
def catch(self, onrejected: Callable[[BaseException], S], /) -> "JsPromise[S]":
|
|
418
|
-
...
|
|
422
|
+
def catch(self, onrejected: Callable[[BaseException], S], /) -> "JsPromise[S]": ...
|
|
419
423
|
|
|
420
424
|
@docs_argspec(
|
|
421
425
|
"(self, onrejected: Callable[[BaseException], Awaitable[S] | S], /) -> 'JsPromise[S]'"
|
|
@@ -670,8 +674,7 @@ class JsGenerator(JsIterable[T_co], Generic[T_co, T_contra, V_co]):
|
|
|
670
674
|
val: BaseException | object = ...,
|
|
671
675
|
tb: TracebackType | None = ...,
|
|
672
676
|
/,
|
|
673
|
-
) -> T_co:
|
|
674
|
-
...
|
|
677
|
+
) -> T_co: ...
|
|
675
678
|
|
|
676
679
|
@overload
|
|
677
680
|
def throw(
|
|
@@ -680,8 +683,7 @@ class JsGenerator(JsIterable[T_co], Generic[T_co, T_contra, V_co]):
|
|
|
680
683
|
val: None = ...,
|
|
681
684
|
tb: TracebackType | None = ...,
|
|
682
685
|
/,
|
|
683
|
-
) -> T_co:
|
|
684
|
-
...
|
|
686
|
+
) -> T_co: ...
|
|
685
687
|
|
|
686
688
|
@docs_argspec("(self, error: BaseException, /) -> T_co")
|
|
687
689
|
def throw(
|
|
@@ -801,8 +803,7 @@ class JsAsyncGenerator(JsAsyncIterable[T_co], Generic[T_co, T_contra, V_co]):
|
|
|
801
803
|
val: BaseException | object = ...,
|
|
802
804
|
tb: TracebackType | None = ...,
|
|
803
805
|
/,
|
|
804
|
-
) -> Awaitable[T_co]:
|
|
805
|
-
...
|
|
806
|
+
) -> Awaitable[T_co]: ...
|
|
806
807
|
|
|
807
808
|
@overload
|
|
808
809
|
def athrow(
|
|
@@ -811,8 +812,7 @@ class JsAsyncGenerator(JsAsyncIterable[T_co], Generic[T_co, T_contra, V_co]):
|
|
|
811
812
|
val: None = ...,
|
|
812
813
|
tb: TracebackType | None = ...,
|
|
813
814
|
/,
|
|
814
|
-
) -> Awaitable[T_co]:
|
|
815
|
-
...
|
|
815
|
+
) -> Awaitable[T_co]: ...
|
|
816
816
|
|
|
817
817
|
@docs_argspec("(self, error: BaseException, /) -> T_co")
|
|
818
818
|
def athrow(self, value: Any, *args: Any) -> Awaitable[T_co]:
|
|
@@ -856,23 +856,19 @@ class JsArray(JsIterable[T], Generic[T], MutableSequence[T], metaclass=_ABCMeta)
|
|
|
856
856
|
_js_type_flags = ["IS_ARRAY", "IS_NODE_LIST", "IS_TYPEDARRAY"]
|
|
857
857
|
|
|
858
858
|
@overload
|
|
859
|
-
def __getitem__(self, idx: int) -> T:
|
|
860
|
-
...
|
|
859
|
+
def __getitem__(self, idx: int) -> T: ...
|
|
861
860
|
|
|
862
861
|
@overload
|
|
863
|
-
def __getitem__(self, idx: slice) -> "JsArray[T]":
|
|
864
|
-
...
|
|
862
|
+
def __getitem__(self, idx: slice) -> "JsArray[T]": ...
|
|
865
863
|
|
|
866
864
|
def __getitem__(self, idx):
|
|
867
865
|
raise NotImplementedError
|
|
868
866
|
|
|
869
867
|
@overload
|
|
870
|
-
def __setitem__(self, idx: int, value: T) -> None:
|
|
871
|
-
...
|
|
868
|
+
def __setitem__(self, idx: int, value: T) -> None: ...
|
|
872
869
|
|
|
873
870
|
@overload
|
|
874
|
-
def __setitem__(self, idx: slice, value: Iterable[T]) -> None:
|
|
875
|
-
...
|
|
871
|
+
def __setitem__(self, idx: slice, value: Iterable[T]) -> None: ...
|
|
876
872
|
|
|
877
873
|
def __setitem__(self, idx, value):
|
|
878
874
|
pass
|
|
@@ -999,12 +995,10 @@ class JsMap(JsIterable[KT], Generic[KT, VT_co], Mapping[KT, VT_co], metaclass=_A
|
|
|
999
995
|
raise NotImplementedError
|
|
1000
996
|
|
|
1001
997
|
@overload
|
|
1002
|
-
def get(self, key: KT, /) -> VT_co | None:
|
|
1003
|
-
...
|
|
998
|
+
def get(self, key: KT, /) -> VT_co | None: ...
|
|
1004
999
|
|
|
1005
1000
|
@overload
|
|
1006
|
-
def get(self, key: KT, default: VT_co | T, /) -> VT_co | T:
|
|
1007
|
-
...
|
|
1001
|
+
def get(self, key: KT, default: VT_co | T, /) -> VT_co | T: ...
|
|
1008
1002
|
|
|
1009
1003
|
@docs_argspec("(self, key: KT, default: VT_co | None, /) -> VT_co")
|
|
1010
1004
|
def get(self, key: KT, default: Any = None, /) -> VT_co:
|
|
@@ -1013,11 +1007,9 @@ class JsMap(JsIterable[KT], Generic[KT, VT_co], Mapping[KT, VT_co], metaclass=_A
|
|
|
1013
1007
|
|
|
1014
1008
|
|
|
1015
1009
|
class _SupportsKeysAndGetItem(Protocol[KT, VT_co]):
|
|
1016
|
-
def keys(self) -> Iterable[KT]:
|
|
1017
|
-
...
|
|
1010
|
+
def keys(self) -> Iterable[KT]: ...
|
|
1018
1011
|
|
|
1019
|
-
def __getitem__(self, __key: KT) -> VT_co:
|
|
1020
|
-
...
|
|
1012
|
+
def __getitem__(self, __key: KT) -> VT_co: ...
|
|
1021
1013
|
|
|
1022
1014
|
|
|
1023
1015
|
class JsMutableMap(
|
|
@@ -1037,12 +1029,10 @@ class JsMutableMap(
|
|
|
1037
1029
|
_js_type_flags = ["HAS_GET | HAS_SET | HAS_LENGTH | IS_ITERABLE", "IS_OBJECT_MAP"]
|
|
1038
1030
|
|
|
1039
1031
|
@overload
|
|
1040
|
-
def pop(self, key: KT, /) -> VT:
|
|
1041
|
-
...
|
|
1032
|
+
def pop(self, key: KT, /) -> VT: ...
|
|
1042
1033
|
|
|
1043
1034
|
@overload
|
|
1044
|
-
def pop(self, key: KT, default: VT | T = ..., /) -> VT | T:
|
|
1045
|
-
...
|
|
1035
|
+
def pop(self, key: KT, default: VT | T = ..., /) -> VT | T: ...
|
|
1046
1036
|
|
|
1047
1037
|
@docs_argspec("(self, key: KT, default: VT | None = None, /) -> VT")
|
|
1048
1038
|
def pop(self, key: KT, default: Any = None, /) -> Any:
|
|
@@ -1067,16 +1057,13 @@ class JsMutableMap(
|
|
|
1067
1057
|
"""Empty out the map entirely."""
|
|
1068
1058
|
|
|
1069
1059
|
@overload
|
|
1070
|
-
def update(self, __m: _SupportsKeysAndGetItem[KT, VT], **kwargs: VT) -> None:
|
|
1071
|
-
...
|
|
1060
|
+
def update(self, __m: _SupportsKeysAndGetItem[KT, VT], **kwargs: VT) -> None: ...
|
|
1072
1061
|
|
|
1073
1062
|
@overload
|
|
1074
|
-
def update(self, __m: Iterable[tuple[KT, VT]], **kwargs: VT) -> None:
|
|
1075
|
-
...
|
|
1063
|
+
def update(self, __m: Iterable[tuple[KT, VT]], **kwargs: VT) -> None: ...
|
|
1076
1064
|
|
|
1077
1065
|
@overload
|
|
1078
|
-
def update(self, **kwargs: VT) -> None:
|
|
1079
|
-
...
|
|
1066
|
+
def update(self, **kwargs: VT) -> None: ...
|
|
1080
1067
|
|
|
1081
1068
|
@docs_argspec(
|
|
1082
1069
|
"(self, other : Mapping[KT, VT] | Iterable[tuple[KT, VT]] = None , /, **kwargs) -> None"
|
|
@@ -1209,6 +1196,7 @@ class JsDomElement(JsProxy):
|
|
|
1209
1196
|
# from pyproxy.c
|
|
1210
1197
|
|
|
1211
1198
|
|
|
1199
|
+
@docs_argspec("(obj: Callable[..., Any], /) -> JsOnceCallable")
|
|
1212
1200
|
def create_once_callable(
|
|
1213
1201
|
obj: Callable[..., Any], /, *, _may_syncify: bool = False
|
|
1214
1202
|
) -> JsOnceCallable:
|
|
@@ -1277,8 +1265,7 @@ def to_js(
|
|
|
1277
1265
|
]
|
|
1278
1266
|
| None
|
|
1279
1267
|
) = None,
|
|
1280
|
-
) -> JsArray[Any]:
|
|
1281
|
-
...
|
|
1268
|
+
) -> JsArray[Any]: ...
|
|
1282
1269
|
|
|
1283
1270
|
|
|
1284
1271
|
@overload
|
|
@@ -1296,8 +1283,7 @@ def to_js(
|
|
|
1296
1283
|
]
|
|
1297
1284
|
| None
|
|
1298
1285
|
) = None,
|
|
1299
|
-
) -> JsMap[Any, Any]:
|
|
1300
|
-
...
|
|
1286
|
+
) -> JsMap[Any, Any]: ...
|
|
1301
1287
|
|
|
1302
1288
|
|
|
1303
1289
|
@overload
|
|
@@ -1315,8 +1301,7 @@ def to_js(
|
|
|
1315
1301
|
]
|
|
1316
1302
|
| None
|
|
1317
1303
|
) = None,
|
|
1318
|
-
) -> Any:
|
|
1319
|
-
...
|
|
1304
|
+
) -> Any: ...
|
|
1320
1305
|
|
|
1321
1306
|
|
|
1322
1307
|
def to_js(
|
|
@@ -1496,7 +1481,29 @@ def destroy_proxies(pyproxies: JsArray[Any], /) -> None:
|
|
|
1496
1481
|
|
|
1497
1482
|
|
|
1498
1483
|
def run_sync(x: Awaitable[T]) -> T:
|
|
1499
|
-
"""
|
|
1484
|
+
"""Block until an awaitable is resolved.
|
|
1485
|
+
|
|
1486
|
+
Only works if JS Promise integration is enabled in the runtime and the
|
|
1487
|
+
current Python call stack was entered via :js:func:`pyodide.runPythonAsync`,
|
|
1488
|
+
by calling an async Python function, or via
|
|
1489
|
+
:js:func:`~pyodide.ffi.PyCallable.callPromising`.
|
|
1490
|
+
|
|
1491
|
+
.. admonition:: Experimental
|
|
1492
|
+
:class: warning
|
|
1493
|
+
|
|
1494
|
+
This feature is not yet stable.
|
|
1495
|
+
"""
|
|
1496
|
+
raise NotImplementedError
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
def can_run_sync() -> bool:
|
|
1500
|
+
"""Returns ``True`` if :py:func:`run_sync` is available and ``False`` if not.
|
|
1501
|
+
|
|
1502
|
+
.. admonition:: Experimental
|
|
1503
|
+
:class: warning
|
|
1504
|
+
|
|
1505
|
+
This feature is not yet stable.
|
|
1506
|
+
"""
|
|
1500
1507
|
raise NotImplementedError
|
|
1501
1508
|
|
|
1502
1509
|
|
|
@@ -1525,6 +1532,7 @@ __all__ = [
|
|
|
1525
1532
|
"JsCallable",
|
|
1526
1533
|
"JsTypedArray",
|
|
1527
1534
|
"run_sync",
|
|
1535
|
+
"can_run_sync",
|
|
1528
1536
|
"create_once_callable",
|
|
1529
1537
|
"create_proxy",
|
|
1530
1538
|
"destroy_proxies",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
def set_result(fut, val):
|
|
2
|
+
if fut.done():
|
|
3
|
+
return
|
|
4
|
+
fut.set_result(val)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def set_exception(fut, val):
|
|
8
|
+
if fut.done():
|
|
9
|
+
return
|
|
10
|
+
fut.set_exception(val)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_future_resolvers(fut):
|
|
14
|
+
return (set_result.__get__(fut), set_exception.__get__(fut))
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
from inspect import Parameter, isclass, iscoroutinefunction, signature
|
|
2
|
+
from types import GenericAlias
|
|
3
|
+
from typing import ( # type:ignore[attr-defined]
|
|
4
|
+
Any,
|
|
5
|
+
_AnnotatedAlias,
|
|
6
|
+
_GenericAlias,
|
|
7
|
+
_UnionGenericAlias,
|
|
8
|
+
get_type_hints,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from _pyodide_core import (
|
|
12
|
+
Js2PyConverter,
|
|
13
|
+
JsFuncSignature,
|
|
14
|
+
Py2JsConverter,
|
|
15
|
+
create_promise_converter,
|
|
16
|
+
js2py_deep,
|
|
17
|
+
js2py_default,
|
|
18
|
+
js2py_default_call_result,
|
|
19
|
+
py2js_as_json_adaptor,
|
|
20
|
+
py2js_deep,
|
|
21
|
+
py2js_default,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Py2JsConverterMeta(type):
|
|
26
|
+
def __new__(metaclass, name, bases, namespace):
|
|
27
|
+
result = namespace.get("converter", py2js_default).copy()
|
|
28
|
+
pc1 = namespace["pre_convert"]
|
|
29
|
+
pc2 = getattr(result, "pre_convert", None)
|
|
30
|
+
if pc1 and pc2:
|
|
31
|
+
|
|
32
|
+
def pcfinal(o):
|
|
33
|
+
return pc2(pc1(o))
|
|
34
|
+
else:
|
|
35
|
+
pcfinal = pc1 or pc2 # type:ignore[assignment]
|
|
36
|
+
result.pre_convert = pcfinal
|
|
37
|
+
return result
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class Js2PyConverterMeta(type):
|
|
41
|
+
def __new__(metaclass, name, bases, namespace):
|
|
42
|
+
result = namespace.get("converter", js2py_default).copy()
|
|
43
|
+
pc1 = namespace["post_convert"]
|
|
44
|
+
pc2 = getattr(result, "post_convert", None)
|
|
45
|
+
if pc1 and pc2:
|
|
46
|
+
|
|
47
|
+
def pcfinal(o):
|
|
48
|
+
return pc1(pc2(o))
|
|
49
|
+
else:
|
|
50
|
+
pcfinal = pc1 or pc2 # type:ignore[assignment]
|
|
51
|
+
result.post_convert = pcfinal
|
|
52
|
+
return result
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def js2py_bind(x):
|
|
56
|
+
class Converter(metaclass=Js2PyConverterMeta):
|
|
57
|
+
@staticmethod
|
|
58
|
+
def post_convert(obj):
|
|
59
|
+
return obj.bind_sig(x)
|
|
60
|
+
|
|
61
|
+
return Converter
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class Json:
|
|
65
|
+
py2js = py2js_as_json_adaptor
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class Deep:
|
|
69
|
+
js2py = js2py_deep
|
|
70
|
+
py2js = py2js_deep
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class Default:
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class BindClass:
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class TypeConverter:
|
|
82
|
+
def unpack_generic_alias(self, x: _GenericAlias) -> Any:
|
|
83
|
+
if isinstance(x, _UnionGenericAlias):
|
|
84
|
+
if len(x.__args__) != 2:
|
|
85
|
+
return None
|
|
86
|
+
e0 = x.__args__[0]
|
|
87
|
+
e1 = x.__args__[1]
|
|
88
|
+
e0isNone = e0 == type(None)
|
|
89
|
+
e1isNone = e1 == type(None)
|
|
90
|
+
if (not e0isNone) and (not e1isNone):
|
|
91
|
+
return None
|
|
92
|
+
if e0isNone:
|
|
93
|
+
x = e1
|
|
94
|
+
if e1isNone:
|
|
95
|
+
x = e0
|
|
96
|
+
if isinstance(x, GenericAlias) and x.__name__ in ["Future", "Awaitable"]:
|
|
97
|
+
arg = x.__args__[0]
|
|
98
|
+
return create_promise_converter(self.js2py_annotation(arg))
|
|
99
|
+
if isinstance(x, _AnnotatedAlias):
|
|
100
|
+
return x.__metadata__[0]
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
def js2py_annotation(self, annotation: Any) -> "Js2PyConverter":
|
|
104
|
+
if isinstance(annotation, (_GenericAlias, GenericAlias)): # noqa: UP038
|
|
105
|
+
annotation = self.unpack_generic_alias(annotation)
|
|
106
|
+
if annotation is None:
|
|
107
|
+
return None
|
|
108
|
+
if isinstance(annotation, Js2PyConverter):
|
|
109
|
+
return annotation
|
|
110
|
+
res = getattr(annotation, "js2py", None)
|
|
111
|
+
if res:
|
|
112
|
+
return res
|
|
113
|
+
|
|
114
|
+
if issubclass(annotation, BindClass):
|
|
115
|
+
return js2py_bind(annotation)
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
def py2js_annotation(self, annotation: Any) -> "Py2JsConverter":
|
|
119
|
+
if isinstance(annotation, _GenericAlias):
|
|
120
|
+
annotation = self.unpack_generic_alias(annotation)
|
|
121
|
+
if annotation is None:
|
|
122
|
+
return None
|
|
123
|
+
if isinstance(annotation, Py2JsConverter):
|
|
124
|
+
return annotation
|
|
125
|
+
res = getattr(annotation, "py2js", None)
|
|
126
|
+
if res:
|
|
127
|
+
return res
|
|
128
|
+
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
type_converter = TypeConverter()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def func_to_sig(f):
|
|
136
|
+
res = getattr(f, "_js_sig", None)
|
|
137
|
+
if res:
|
|
138
|
+
return res
|
|
139
|
+
res = func_to_sig_inner(f)
|
|
140
|
+
f._js_sig = res
|
|
141
|
+
return res
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def get_attr_sig(sig, attr):
|
|
145
|
+
if not hasattr(sig, "_type_hints"):
|
|
146
|
+
sig._type_hints = get_type_hints(sig, include_extras=True)
|
|
147
|
+
attr_sig = sig._type_hints.get(attr, None)
|
|
148
|
+
if not attr_sig:
|
|
149
|
+
return (False, getattr(sig, attr, None))
|
|
150
|
+
if isinstance(attr_sig, BindClass):
|
|
151
|
+
return (False, attr_sig)
|
|
152
|
+
converter = type_converter.js2py_annotation(attr_sig)
|
|
153
|
+
if converter:
|
|
154
|
+
return (True, converter)
|
|
155
|
+
return (False, None)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
no_default = Parameter.empty
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def func_to_sig_inner(f):
|
|
162
|
+
sig = signature(f)
|
|
163
|
+
posparams = []
|
|
164
|
+
posparams_defaults = []
|
|
165
|
+
posparams_nmandatory = 0
|
|
166
|
+
varpos = None
|
|
167
|
+
kwparam_names = []
|
|
168
|
+
kwparam_converters = []
|
|
169
|
+
kwparam_defaults = []
|
|
170
|
+
varkwd = None
|
|
171
|
+
types = get_type_hints(f, include_extras=True)
|
|
172
|
+
|
|
173
|
+
for p in sig.parameters.values():
|
|
174
|
+
converter = (
|
|
175
|
+
type_converter.py2js_annotation(types.get(p.name, None)) or py2js_default
|
|
176
|
+
)
|
|
177
|
+
match p.kind:
|
|
178
|
+
case Parameter.POSITIONAL_ONLY:
|
|
179
|
+
posparams.append(converter)
|
|
180
|
+
if p.default == Parameter.empty:
|
|
181
|
+
posparams_nmandatory += 1
|
|
182
|
+
else:
|
|
183
|
+
posparams_defaults.append(p.default)
|
|
184
|
+
case Parameter.POSITIONAL_OR_KEYWORD:
|
|
185
|
+
raise RuntimeError("Don't currently handle POS_OR_KWD args")
|
|
186
|
+
case Parameter.KEYWORD_ONLY:
|
|
187
|
+
kwparam_names.append(p.name)
|
|
188
|
+
kwparam_converters.append(converter)
|
|
189
|
+
kwparam_defaults.append(p.default)
|
|
190
|
+
case Parameter.VAR_POSITIONAL:
|
|
191
|
+
varpos = converter
|
|
192
|
+
case Parameter.VAR_KEYWORD:
|
|
193
|
+
varkwd = converter
|
|
194
|
+
case _:
|
|
195
|
+
raise RuntimeError("Unreachable")
|
|
196
|
+
if len(kwparam_names) > 64:
|
|
197
|
+
# We use a bitflag to check which kwparams have been passed to fill in
|
|
198
|
+
# defaults / raise type error.
|
|
199
|
+
raise RuntimeError("Cannot handle function with more than 64 kwonly args")
|
|
200
|
+
result = type_converter.js2py_annotation(types.get("return", None))
|
|
201
|
+
if iscoroutinefunction(f):
|
|
202
|
+
if result is None:
|
|
203
|
+
result = js2py_default
|
|
204
|
+
result = create_promise_converter(result)
|
|
205
|
+
elif result is None:
|
|
206
|
+
result = js2py_default_call_result
|
|
207
|
+
|
|
208
|
+
should_construct = isclass(f)
|
|
209
|
+
return JsFuncSignature(
|
|
210
|
+
f,
|
|
211
|
+
should_construct,
|
|
212
|
+
posparams_nmandatory,
|
|
213
|
+
tuple(posparams),
|
|
214
|
+
tuple(posparams_defaults),
|
|
215
|
+
varpos,
|
|
216
|
+
tuple(kwparam_names),
|
|
217
|
+
tuple(kwparam_converters),
|
|
218
|
+
tuple(kwparam_defaults),
|
|
219
|
+
varkwd,
|
|
220
|
+
result,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _default_sig_stencil(*args, **kwargs):
|
|
225
|
+
pass
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
default_signature = func_to_sig_inner(_default_sig_stencil)
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# This package is imported by the test suite as well, and currently we don't use
|
|
11
11
|
# pytest mocks for js or pyodide_js, so make sure to test "if IN_BROWSER" before
|
|
12
12
|
# importing from these.
|
|
13
|
-
__version__ = "0.26.
|
|
13
|
+
__version__ = "0.26.2"
|
|
14
14
|
|
|
15
15
|
__all__ = ["__version__", "console", "code", "ffi", "http", "webloop"]
|
|
16
16
|
|
|
@@ -92,11 +92,15 @@ class _Compile(Compile):
|
|
|
92
92
|
return_mode: ReturnMode = "last_expr",
|
|
93
93
|
quiet_trailing_semicolon: bool = True,
|
|
94
94
|
flags: int = 0x0,
|
|
95
|
+
dont_inherit: bool = False,
|
|
96
|
+
optimize: int = -1,
|
|
95
97
|
) -> None:
|
|
96
98
|
super().__init__()
|
|
97
99
|
self.flags |= flags
|
|
98
100
|
self.return_mode = return_mode
|
|
99
101
|
self.quiet_trailing_semicolon = quiet_trailing_semicolon
|
|
102
|
+
self.dont_inherit = dont_inherit
|
|
103
|
+
self.optimize = optimize
|
|
100
104
|
|
|
101
105
|
def __call__( # type: ignore[override]
|
|
102
106
|
self, source: str, filename: str, symbol: str, *, incomplete_input: bool = True
|
|
@@ -119,6 +123,8 @@ class _Compile(Compile):
|
|
|
119
123
|
filename=filename,
|
|
120
124
|
return_mode=return_mode,
|
|
121
125
|
flags=self.flags,
|
|
126
|
+
dont_inherit=self.dont_inherit,
|
|
127
|
+
optimize=self.optimize,
|
|
122
128
|
).compile()
|
|
123
129
|
assert code_runner.code
|
|
124
130
|
for feature in _features:
|
|
@@ -146,11 +152,15 @@ class _CommandCompiler(CommandCompiler):
|
|
|
146
152
|
return_mode: ReturnMode = "last_expr",
|
|
147
153
|
quiet_trailing_semicolon: bool = True,
|
|
148
154
|
flags: int = 0x0,
|
|
155
|
+
dont_inherit: bool = False,
|
|
156
|
+
optimize: int = -1,
|
|
149
157
|
) -> None:
|
|
150
158
|
self.compiler = _Compile(
|
|
151
159
|
return_mode=return_mode,
|
|
152
160
|
quiet_trailing_semicolon=quiet_trailing_semicolon,
|
|
153
161
|
flags=flags,
|
|
162
|
+
dont_inherit=dont_inherit,
|
|
163
|
+
optimize=optimize,
|
|
154
164
|
)
|
|
155
165
|
|
|
156
166
|
def __call__( # type: ignore[override]
|
|
@@ -237,6 +247,16 @@ class Console:
|
|
|
237
247
|
filename :
|
|
238
248
|
|
|
239
249
|
The file name to report in error messages. Defaults to ``"<console>"``.
|
|
250
|
+
|
|
251
|
+
dont_inherit :
|
|
252
|
+
|
|
253
|
+
Whether to inherit ``__future__`` imports from the outer code.
|
|
254
|
+
See the documentation for the built-in :external:py:func:`compile` function.
|
|
255
|
+
|
|
256
|
+
optimize :
|
|
257
|
+
|
|
258
|
+
Specifies the optimization level of the compiler. See the documentation
|
|
259
|
+
for the built-in :external:py:func:`compile` function.
|
|
240
260
|
"""
|
|
241
261
|
|
|
242
262
|
globals: dict[str, Any]
|
|
@@ -270,6 +290,8 @@ class Console:
|
|
|
270
290
|
stderr_callback: Callable[[str], None] | None = None,
|
|
271
291
|
persistent_stream_redirection: bool = False,
|
|
272
292
|
filename: str = "<console>",
|
|
293
|
+
dont_inherit: bool = False,
|
|
294
|
+
optimize: int = -1,
|
|
273
295
|
) -> None:
|
|
274
296
|
if globals is None:
|
|
275
297
|
globals = {"__name__": "__console__", "__doc__": None}
|
|
@@ -283,9 +305,9 @@ class Console:
|
|
|
283
305
|
self.buffer = []
|
|
284
306
|
self._lock = asyncio.Lock()
|
|
285
307
|
self._streams_redirected = False
|
|
286
|
-
self._stream_generator: Generator[
|
|
287
|
-
None
|
|
288
|
-
|
|
308
|
+
self._stream_generator: Generator[None, None, None] | None = (
|
|
309
|
+
None # track persistent stream redirection
|
|
310
|
+
)
|
|
289
311
|
if persistent_stream_redirection:
|
|
290
312
|
self.persistent_redirect_streams()
|
|
291
313
|
self._completer = rlcompleter.Completer(self.globals)
|
|
@@ -294,7 +316,11 @@ class Console:
|
|
|
294
316
|
self.completer_word_break_characters = (
|
|
295
317
|
""" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?"""
|
|
296
318
|
)
|
|
297
|
-
self._compile = _CommandCompiler(
|
|
319
|
+
self._compile = _CommandCompiler(
|
|
320
|
+
flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT,
|
|
321
|
+
dont_inherit=dont_inherit,
|
|
322
|
+
optimize=optimize,
|
|
323
|
+
)
|
|
298
324
|
|
|
299
325
|
def persistent_redirect_streams(self) -> None:
|
|
300
326
|
"""Redirect :py:data:`~sys.stdin`/:py:data:`~sys.stdout`/:py:data:`~sys.stdout` persistently"""
|
|
@@ -379,18 +405,21 @@ class Console:
|
|
|
379
405
|
res.set_result(fut.result())
|
|
380
406
|
res = None
|
|
381
407
|
|
|
382
|
-
ensure_future(self.
|
|
408
|
+
ensure_future(self._runcode_with_lock(source, code)).add_done_callback(done_cb)
|
|
383
409
|
return res
|
|
384
410
|
|
|
411
|
+
async def _runcode_with_lock(self, source: str, code: CodeRunner) -> Any:
|
|
412
|
+
async with self._lock:
|
|
413
|
+
return await self.runcode(source, code)
|
|
414
|
+
|
|
385
415
|
async def runcode(self, source: str, code: CodeRunner) -> Any:
|
|
386
416
|
"""Execute a code object and return the result."""
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
sys.stderr.flush()
|
|
417
|
+
with self.redirect_streams():
|
|
418
|
+
try:
|
|
419
|
+
return await code.run_async(self.globals)
|
|
420
|
+
finally:
|
|
421
|
+
sys.stdout.flush()
|
|
422
|
+
sys.stderr.flush()
|
|
394
423
|
|
|
395
424
|
def formatsyntaxerror(self, e: Exception) -> str:
|
|
396
425
|
"""Format the syntax error that just occurred.
|
|
@@ -409,7 +438,7 @@ class Console:
|
|
|
409
438
|
kept_frames = 0
|
|
410
439
|
# Try to trim out stack frames inside our code
|
|
411
440
|
for frame, _ in traceback.walk_tb(tb):
|
|
412
|
-
keep_frames = keep_frames or frame.f_code.co_filename ==
|
|
441
|
+
keep_frames = keep_frames or frame.f_code.co_filename == self.filename
|
|
413
442
|
keep_frames = keep_frames or frame.f_code.co_filename == "<exec>"
|
|
414
443
|
if keep_frames:
|
|
415
444
|
kept_frames += 1
|
|
@@ -21,6 +21,7 @@ if IN_BROWSER:
|
|
|
21
21
|
for t in [
|
|
22
22
|
"JsException",
|
|
23
23
|
"run_sync",
|
|
24
|
+
"can_run_sync",
|
|
24
25
|
"create_once_callable",
|
|
25
26
|
"create_proxy",
|
|
26
27
|
"destroy_proxies",
|
|
@@ -54,6 +55,7 @@ __all__ = [
|
|
|
54
55
|
"create_proxy",
|
|
55
56
|
"destroy_proxies",
|
|
56
57
|
"to_js",
|
|
58
|
+
"run_sync",
|
|
57
59
|
"IN_BROWSER",
|
|
58
60
|
"register_js_module",
|
|
59
61
|
"unregister_js_module",
|
|
@@ -8,7 +8,7 @@ from asyncio import Future, Task
|
|
|
8
8
|
from collections.abc import Awaitable, Callable
|
|
9
9
|
from typing import Any, TypeVar, overload
|
|
10
10
|
|
|
11
|
-
from .ffi import IN_BROWSER, create_once_callable
|
|
11
|
+
from .ffi import IN_BROWSER, create_once_callable, run_sync
|
|
12
12
|
|
|
13
13
|
if IN_BROWSER:
|
|
14
14
|
from pyodide_js._api import scheduleCallback
|
|
@@ -30,32 +30,28 @@ class PyodideFuture(Future[T]):
|
|
|
30
30
|
self,
|
|
31
31
|
onfulfilled: None,
|
|
32
32
|
onrejected: Callable[[BaseException], Awaitable[S]],
|
|
33
|
-
) -> "PyodideFuture[S]":
|
|
34
|
-
...
|
|
33
|
+
) -> "PyodideFuture[S]": ...
|
|
35
34
|
|
|
36
35
|
@overload
|
|
37
36
|
def then(
|
|
38
37
|
self,
|
|
39
38
|
onfulfilled: None,
|
|
40
39
|
onrejected: Callable[[BaseException], S],
|
|
41
|
-
) -> "PyodideFuture[S]":
|
|
42
|
-
...
|
|
40
|
+
) -> "PyodideFuture[S]": ...
|
|
43
41
|
|
|
44
42
|
@overload
|
|
45
43
|
def then(
|
|
46
44
|
self,
|
|
47
45
|
onfulfilled: Callable[[T], Awaitable[S]],
|
|
48
46
|
onrejected: Callable[[BaseException], Awaitable[S]] | None = None,
|
|
49
|
-
) -> "PyodideFuture[S]":
|
|
50
|
-
...
|
|
47
|
+
) -> "PyodideFuture[S]": ...
|
|
51
48
|
|
|
52
49
|
@overload
|
|
53
50
|
def then(
|
|
54
51
|
self,
|
|
55
52
|
onfulfilled: Callable[[T], S],
|
|
56
53
|
onrejected: Callable[[BaseException], S] | None = None,
|
|
57
|
-
) -> "PyodideFuture[S]":
|
|
58
|
-
...
|
|
54
|
+
) -> "PyodideFuture[S]": ...
|
|
59
55
|
|
|
60
56
|
def then(
|
|
61
57
|
self,
|
|
@@ -128,12 +124,10 @@ class PyodideFuture(Future[T]):
|
|
|
128
124
|
@overload
|
|
129
125
|
def catch(
|
|
130
126
|
self, onrejected: Callable[[BaseException], Awaitable[S]]
|
|
131
|
-
) -> "PyodideFuture[S]":
|
|
132
|
-
...
|
|
127
|
+
) -> "PyodideFuture[S]": ...
|
|
133
128
|
|
|
134
129
|
@overload
|
|
135
|
-
def catch(self, onrejected: Callable[[BaseException], S]) -> "PyodideFuture[S]":
|
|
136
|
-
...
|
|
130
|
+
def catch(self, onrejected: Callable[[BaseException], S]) -> "PyodideFuture[S]": ...
|
|
137
131
|
|
|
138
132
|
def catch(
|
|
139
133
|
self, onrejected: Callable[[BaseException], object]
|
|
@@ -265,6 +259,10 @@ class WebLoop(asyncio.AbstractEventLoop):
|
|
|
265
259
|
do_something_with_result(result)
|
|
266
260
|
```
|
|
267
261
|
"""
|
|
262
|
+
from pyodide_js._api import config
|
|
263
|
+
|
|
264
|
+
if config.enableRunUntilComplete:
|
|
265
|
+
return run_sync(future)
|
|
268
266
|
return asyncio.ensure_future(future)
|
|
269
267
|
|
|
270
268
|
#
|
|
@@ -274,7 +272,7 @@ class WebLoop(asyncio.AbstractEventLoop):
|
|
|
274
272
|
def call_soon(
|
|
275
273
|
self,
|
|
276
274
|
callback: Callable[..., Any],
|
|
277
|
-
*args: Any,
|
|
275
|
+
*args: Any, # type: ignore[override]
|
|
278
276
|
context: contextvars.Context | None = None,
|
|
279
277
|
) -> asyncio.Handle:
|
|
280
278
|
"""Arrange for a callback to be called as soon as possible.
|
|
@@ -290,7 +288,7 @@ class WebLoop(asyncio.AbstractEventLoop):
|
|
|
290
288
|
def call_soon_threadsafe(
|
|
291
289
|
self,
|
|
292
290
|
callback: Callable[..., Any],
|
|
293
|
-
*args: Any,
|
|
291
|
+
*args: Any, # type: ignore[override]
|
|
294
292
|
context: contextvars.Context | None = None,
|
|
295
293
|
) -> asyncio.Handle:
|
|
296
294
|
"""Like ``call_soon()``, but thread-safe.
|
|
@@ -5,9 +5,11 @@ setup.py
|
|
|
5
5
|
./_pyodide/__init__.py
|
|
6
6
|
./_pyodide/_base.py
|
|
7
7
|
./_pyodide/_core_docs.py
|
|
8
|
+
./_pyodide/_future_helper.py
|
|
8
9
|
./_pyodide/_importhook.py
|
|
9
10
|
./_pyodide/docs_argspec.py
|
|
10
11
|
./_pyodide/docstring.py
|
|
12
|
+
./_pyodide/jsbind.py
|
|
11
13
|
./_pyodide/py.typed
|
|
12
14
|
./pyodide/__init__.py
|
|
13
15
|
./pyodide/_core.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyodide-py"
|
|
7
|
-
version = "0.26.
|
|
7
|
+
version = "0.26.2"
|
|
8
8
|
authors = [{name = "Pyodide developers"}]
|
|
9
9
|
description = "A Python package providing core interpreter functionality for Pyodide"
|
|
10
10
|
classifiers = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|