|
23 | 23 | #define HAS_INCLUDES (1 << 2) |
24 | 24 | #define HAS_LENGTH (1 << 3) |
25 | 25 | #define HAS_SET (1 << 4) |
26 | | -#define IS_ARRAY (1 << 5) |
27 | | -#define IS_CALLABLE (1 << 6) |
28 | | -#define IS_ERROR (1 << 7) |
29 | | -#define IS_GENERATOR (1 << 8) |
30 | | -#define IS_ITERABLE (1 << 9) |
31 | | -#define IS_ITERATOR (1 << 10) |
32 | | -#define IS_DOUBLE_PROXY (1 << 11) |
33 | | -#define IS_PY_JSON_DICT (1 << 12) |
34 | | -#define IS_PY_JSON_SEQUENCE (1 << 13) |
| 26 | +#define HAS_DISPOSE (1 << 5) |
| 27 | +#define IS_ARRAY (1 << 6) |
| 28 | +#define IS_CALLABLE (1 << 7) |
| 29 | +#define IS_ERROR (1 << 8) |
| 30 | +#define IS_GENERATOR (1 << 9) |
| 31 | +#define IS_ITERABLE (1 << 10) |
| 32 | +#define IS_ITERATOR (1 << 11) |
| 33 | +#define IS_DOUBLE_PROXY (1 << 12) |
| 34 | +#define IS_PY_JSON_DICT (1 << 13) |
| 35 | +#define IS_PY_JSON_SEQUENCE (1 << 14) |
35 | 36 |
|
36 | 37 | Js_IDENTIFIER(next); |
37 | 38 |
|
@@ -949,6 +950,47 @@ JsProxy_includes(JsProxy* self, PyObject* obj) |
949 | 950 | return result; |
950 | 951 | } |
951 | 952 |
|
| 953 | + |
| 954 | +/*[clinic input] |
| 955 | +_pyodide_core.JsProxy.__enter__ |
| 956 | +
|
| 957 | +If [Symbol.dispose] is present, implement context manager protocol. |
| 958 | +[clinic start generated code]*/ |
| 959 | + |
| 960 | +static PyObject * |
| 961 | +_pyodide_core_JsProxy___enter___impl(PyObject *self) |
| 962 | +/*[clinic end generated code: output=7d0abcbd81673f6b input=3ab21922f5faedaf]*/ |
| 963 | +{ |
| 964 | + return Py_NewRef(self); |
| 965 | +} |
| 966 | + |
| 967 | +EM_JS_NUM(int, JsProxy_exit_js, (JsVal obj), { |
| 968 | + obj[Symbol.dispose](); |
| 969 | +}); |
| 970 | + |
| 971 | +/*[clinic input] |
| 972 | +_pyodide_core.JsProxy.__exit__ |
| 973 | +
|
| 974 | + exc_type: object = None |
| 975 | + exc_value: object = None |
| 976 | + exc_tb: object = None |
| 977 | + / |
| 978 | +
|
| 979 | +If [Symbol.dispose] is present, implement context manager protocol. |
| 980 | +[clinic start generated code]*/ |
| 981 | + |
| 982 | +static PyObject * |
| 983 | +_pyodide_core_JsProxy___exit___impl(PyObject *self, PyObject *exc_type, |
| 984 | + PyObject *exc_value, PyObject *exc_tb) |
| 985 | +/*[clinic end generated code: output=e52ec221b82c0b6f input=40df97659f01cc5a]*/ |
| 986 | +{ |
| 987 | + if (JsProxy_exit_js(JsProxy_VAL(self)) == -1) { |
| 988 | + return NULL; |
| 989 | + } |
| 990 | + Py_RETURN_NONE; |
| 991 | +} |
| 992 | + |
| 993 | + |
952 | 994 | EM_JS_VAL(JsVal, _PyJsMap_GetIter_js, (JsVal obj), { |
953 | 995 | let result; |
954 | 996 | // clang-format off |
@@ -2425,6 +2467,12 @@ JsProxy_create_subtype(int flags, bool is_py_json) |
2425 | 2467 | slots[cur_slot++] = |
2426 | 2468 | (PyType_Slot){ .slot = Py_mp_length, .pfunc = (void*)JsProxy_length }; |
2427 | 2469 | } |
| 2470 | + if (flags & HAS_DISPOSE) { |
| 2471 | + AddMethods( |
| 2472 | + _PYODIDE_CORE_JSPROXY___ENTER___METHODDEF |
| 2473 | + _PYODIDE_CORE_JSPROXY___EXIT___METHODDEF |
| 2474 | + ); |
| 2475 | + } |
2428 | 2476 |
|
2429 | 2477 | if (flags & IS_ARRAY) { |
2430 | 2478 | // If the object is an array (or a HTMLCollection or NodeList), then we want |
@@ -2691,6 +2739,9 @@ EM_JS_NUM(int, JsProxy_compute_typeflags, (JsVal obj, bool is_py_json), { |
2691 | 2739 | SET_FLAG_IF(HAS_LENGTH, |
2692 | 2740 | (hasProperty(obj, "size")) || |
2693 | 2741 | (hasProperty(obj, "length") && typeof obj !== "function")); |
| 2742 | + if (Symbol.asyncDispose) { |
| 2743 | + SET_FLAG_IF_HAS_METHOD(HAS_DISPOSE, Symbol.dispose); |
| 2744 | + } |
2694 | 2745 | SET_FLAG_IF(IS_CALLABLE, typeof obj === "function"); |
2695 | 2746 | SET_FLAG_IF(IS_ARRAY, safeCall(() => Array.isArray(obj))); |
2696 | 2747 | SET_FLAG_IF(IS_DOUBLE_PROXY, API.isPyProxy(obj)); |
|
0 commit comments