Skip to content

Commit

Permalink
NFC Place js_flags in separate dict (#3338)
Browse files Browse the repository at this point in the history
  • Loading branch information
hoodmane committed Dec 10, 2022
1 parent 653310a commit 7241496
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 9 deletions.
24 changes: 22 additions & 2 deletions src/core/jsproxy.c
Expand Up @@ -3955,12 +3955,29 @@ JsProxy_init_docstrings()
return success ? 0 : -1;
}

static int
add_flag(PyObject* dict, char* name, int value)
{
PyObject* value_py = NULL;
bool success = false;

value_py = PyLong_FromLong(value);
FAIL_IF_NULL(value_py);
FAIL_IF_MINUS_ONE(PyDict_SetItemString(dict, name, value_py));

success = true;
finally:
Py_CLEAR(value_py);
return success ? 0 : -1;
}

int
JsProxy_init(PyObject* core_module)
{
bool success = false;

PyObject* asyncio_module = NULL;
PyObject* flag_dict = NULL;

collections_abc = PyImport_ImportModule("collections.abc");
FAIL_IF_NULL(collections_abc);
Expand All @@ -3976,8 +3993,10 @@ JsProxy_init(PyObject* core_module)
FAIL_IF_MINUS_ONE(JsProxy_init_docstrings());
FAIL_IF_MINUS_ONE(PyModule_AddFunctions(core_module, methods));

#define AddFlag(flag) \
FAIL_IF_MINUS_ONE(PyModule_AddIntConstant(core_module, #flag, flag))
flag_dict = PyDict_New();
FAIL_IF_NULL(flag_dict);

#define AddFlag(flag) FAIL_IF_MINUS_ONE(add_flag(flag_dict, #flag, flag))

AddFlag(IS_ITERABLE);
AddFlag(IS_ITERATOR);
Expand All @@ -3999,6 +4018,7 @@ JsProxy_init(PyObject* core_module)
AddFlag(IS_ASYNC_GENERATOR);

#undef AddFlag
FAIL_IF_MINUS_ONE(PyObject_SetAttrString(core_module, "js_flags", flag_dict));

asyncio_module = PyImport_ImportModule("asyncio");
FAIL_IF_NULL(asyncio_module);
Expand Down
11 changes: 5 additions & 6 deletions src/py/_pyodide/_core_docs.py
Expand Up @@ -41,16 +41,15 @@ class ConversionError(Exception):
"""An error thrown when conversion between JavaScript and Python fails."""


# We need this to look up the flags
_core_dict: dict[str, Any] = {}
_js_flags: dict[str, int] = {}


def _binor_reduce(l: Iterable[int]) -> int:
return reduce(lambda x, y: x | y, l)


def _process_flag_expression(e: str) -> int:
return _binor_reduce(_core_dict[x.strip()] for x in e.split("|"))
return _binor_reduce(_js_flags[x.strip()] for x in e.split("|"))


class _JsProxyMetaClass(type):
Expand All @@ -70,8 +69,8 @@ def __subclasscheck__(cls, subclass):
if not hasattr(subclass, "_js_type_flags"):
return False
# For the "synthetic" subtypes defined in this file, we define
# _js_type_flags as a string. To convert it to the correct value, we
# exec it in the _core_dict context.
# _js_type_flags as a string. We look these up in the _js_flags dict to
# convert to a number.
cls_flags = cls._js_type_flags # type:ignore[attr-defined]
if isinstance(cls_flags, int):
cls_flags = [cls_flags]
Expand All @@ -80,7 +79,7 @@ def __subclasscheck__(cls, subclass):

subclass_flags = subclass._js_type_flags
if not isinstance(subclass_flags, int):
subclass_flags = _binor_reduce(_core_dict[f] for f in subclass_flags)
subclass_flags = _binor_reduce(_js_flags[f] for f in subclass_flags)

return any(cls_flag & subclass_flags == cls_flag for cls_flag in cls_flags)

Expand Down
2 changes: 1 addition & 1 deletion src/py/pyodide/_core.py
Expand Up @@ -16,7 +16,7 @@

import _pyodide._core_docs

_pyodide._core_docs._core_dict = _pyodide_core.__dict__
_pyodide._core_docs._js_flags = _pyodide_core.js_flags
else:
from _pyodide._core_docs import (
ConversionError,
Expand Down

0 comments on commit 7241496

Please sign in to comment.