diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-01-09-58-06.gh-issue-103951.6qduwj.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-01-09-58-06.gh-issue-103951.6qduwj.rst new file mode 100644 index 00000000000..39b54e0b725 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-01-09-58-06.gh-issue-103951.6qduwj.rst @@ -0,0 +1,2 @@ +Relax optimization requirements to allow fast attribute access to module +subclasses. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 04983fd861e..c85b49842da 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2132,7 +2132,7 @@ dummy_func( op(_CHECK_ATTR_MODULE, (dict_version/2, owner -- owner)) { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - DEOPT_IF(!PyModule_CheckExact(owner_o)); + DEOPT_IF(Py_TYPE(owner_o)->tp_getattro != PyModule_Type.tp_getattro); PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict; assert(dict != NULL); DEOPT_IF(dict->ma_keys->dk_version != dict_version); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 494ace1bd85..2c2a09adf28 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -2602,7 +2602,7 @@ owner = stack_pointer[-1]; uint32_t dict_version = (uint32_t)CURRENT_OPERAND0(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - if (!PyModule_CheckExact(owner_o)) { + if (Py_TYPE(owner_o)->tp_getattro != PyModule_Type.tp_getattro) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 77bf6ad3781..15308d6f1f7 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5561,7 +5561,7 @@ owner = stack_pointer[-1]; uint32_t dict_version = read_u32(&this_instr[2].cache); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - DEOPT_IF(!PyModule_CheckExact(owner_o), LOAD_ATTR); + DEOPT_IF(Py_TYPE(owner_o)->tp_getattro != PyModule_Type.tp_getattro, LOAD_ATTR); PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict; assert(dict != NULL); DEOPT_IF(dict->ma_keys->dk_version != dict_version, LOAD_ATTR); diff --git a/Python/specialize.c b/Python/specialize.c index 0699e7be5e6..4c8cf8534b3 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1219,7 +1219,7 @@ _Py_Specialize_LoadAttr(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *nam SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER); fail = true; } - else if (PyModule_CheckExact(owner)) { + else if (Py_TYPE(owner)->tp_getattro == PyModule_Type.tp_getattro) { fail = specialize_module_load_attr(owner, instr, name); } else if (PyType_Check(owner)) {