diff options
author | Mark Shannon <mark@hotpy.org> | 2021-04-30 08:50:28 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-30 08:50:28 (GMT) |
commit | 069e81ab3da46c441335ca762c4333b7bd91861d (patch) | |
tree | 02716907f4513a812cf2c72309cc4e6f133b3ab3 /Python | |
parent | 2abbd8f2add5e80b86a965625b9a77ae94a101cd (diff) | |
download | cpython-069e81ab3da46c441335ca762c4333b7bd91861d.zip cpython-069e81ab3da46c441335ca762c4333b7bd91861d.tar.gz cpython-069e81ab3da46c441335ca762c4333b7bd91861d.tar.bz2 |
bpo-43977: Use tp_flags for collection matching (GH-25723)
* Add Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING, add to all relevant standard builtin classes.
* Set relevant flags on collections.abc.Sequence and Mapping.
* Use flags in MATCH_SEQUENCE and MATCH_MAPPING opcodes.
* Inherit Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING.
* Add NEWS
* Remove interpreter-state map_abc and seq_abc fields.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 72 | ||||
-rw-r--r-- | Python/pystate.c | 2 |
2 files changed, 8 insertions, 66 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 326930b..866c57a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3889,76 +3889,20 @@ main_loop: } case TARGET(MATCH_MAPPING): { - // PUSH(isinstance(TOS, _collections_abc.Mapping)) PyObject *subject = TOP(); - // Fast path for dicts: - if (PyDict_Check(subject)) { - Py_INCREF(Py_True); - PUSH(Py_True); - DISPATCH(); - } - // Lazily import _collections_abc.Mapping, and keep it handy on the - // PyInterpreterState struct (it gets cleaned up at exit): - PyInterpreterState *interp = PyInterpreterState_Get(); - if (interp->map_abc == NULL) { - PyObject *abc = PyImport_ImportModule("_collections_abc"); - if (abc == NULL) { - goto error; - } - interp->map_abc = PyObject_GetAttrString(abc, "Mapping"); - if (interp->map_abc == NULL) { - goto error; - } - } - int match = PyObject_IsInstance(subject, interp->map_abc); - if (match < 0) { - goto error; - } - PUSH(PyBool_FromLong(match)); + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; + PyObject *res = match ? Py_True : Py_False; + Py_INCREF(res); + PUSH(res); DISPATCH(); } case TARGET(MATCH_SEQUENCE): { - // PUSH(not isinstance(TOS, (bytearray, bytes, str)) - // and isinstance(TOS, _collections_abc.Sequence)) PyObject *subject = TOP(); - // Fast path for lists and tuples: - if (PyType_FastSubclass(Py_TYPE(subject), - Py_TPFLAGS_LIST_SUBCLASS | - Py_TPFLAGS_TUPLE_SUBCLASS)) - { - Py_INCREF(Py_True); - PUSH(Py_True); - DISPATCH(); - } - // Bail on some possible Sequences that we intentionally exclude: - if (PyType_FastSubclass(Py_TYPE(subject), - Py_TPFLAGS_BYTES_SUBCLASS | - Py_TPFLAGS_UNICODE_SUBCLASS) || - PyByteArray_Check(subject)) - { - Py_INCREF(Py_False); - PUSH(Py_False); - DISPATCH(); - } - // Lazily import _collections_abc.Sequence, and keep it handy on the - // PyInterpreterState struct (it gets cleaned up at exit): - PyInterpreterState *interp = PyInterpreterState_Get(); - if (interp->seq_abc == NULL) { - PyObject *abc = PyImport_ImportModule("_collections_abc"); - if (abc == NULL) { - goto error; - } - interp->seq_abc = PyObject_GetAttrString(abc, "Sequence"); - if (interp->seq_abc == NULL) { - goto error; - } - } - int match = PyObject_IsInstance(subject, interp->seq_abc); - if (match < 0) { - goto error; - } - PUSH(PyBool_FromLong(match)); + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; + PyObject *res = match ? Py_True : Py_False; + Py_INCREF(res); + PUSH(res); DISPATCH(); } diff --git a/Python/pystate.c b/Python/pystate.c index 81bcf68..aeebd6f 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -308,8 +308,6 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) Py_CLEAR(interp->importlib); Py_CLEAR(interp->import_func); Py_CLEAR(interp->dict); - Py_CLEAR(interp->map_abc); - Py_CLEAR(interp->seq_abc); #ifdef HAVE_FORK Py_CLEAR(interp->before_forkers); Py_CLEAR(interp->after_forkers_parent); |