From 9f569d7bfc41b7f74b3044a5d5eedc2339dc552a Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Mon, 22 Dec 2025 17:49:28 +0100 Subject: [PATCH 1/5] Add static data --- mypyc/lib-rt/init.c | 2 ++ mypyc/lib-rt/pythonsupport.h | 1 + mypyc/lib-rt/static_data.c | 58 +++++++++++++++++++++++++++++++++++ mypyc/lib-rt/static_data.h | 59 ++++++++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+) create mode 100644 mypyc/lib-rt/static_data.c create mode 100644 mypyc/lib-rt/static_data.h diff --git a/mypyc/lib-rt/init.c b/mypyc/lib-rt/init.c index 9215c2d59019..567730fd8f56 100644 --- a/mypyc/lib-rt/init.c +++ b/mypyc/lib-rt/init.c @@ -1,5 +1,6 @@ #include #include "CPy.h" +#include "static_data.c" struct ExcDummyStruct _CPy_ExcDummyStruct = { PyObject_HEAD_INIT(NULL) }; PyObject *_CPy_ExcDummy = (PyObject *)&_CPy_ExcDummyStruct; @@ -12,6 +13,7 @@ PyObject * __mypyc_empty_tuple__ = NULL; // other dynamic libraries. This means we need to initialize // things at load time. void CPy_Init(void) { + intern_strings(); _CPy_ExcDummyStruct.ob_base.ob_type = &PyBaseObject_Type; // Initialize system-wide empty tuple constant diff --git a/mypyc/lib-rt/pythonsupport.h b/mypyc/lib-rt/pythonsupport.h index 7019c12cf59a..c93f5606424a 100644 --- a/mypyc/lib-rt/pythonsupport.h +++ b/mypyc/lib-rt/pythonsupport.h @@ -11,6 +11,7 @@ #include "pythoncapi_compat.h" #include #include +#include "static_data.h" #include "mypyc_util.h" #if CPY_3_13_FEATURES diff --git a/mypyc/lib-rt/static_data.c b/mypyc/lib-rt/static_data.c new file mode 100644 index 000000000000..1fc93330bdc1 --- /dev/null +++ b/mypyc/lib-rt/static_data.c @@ -0,0 +1,58 @@ +#ifndef STATIC_DATA +#define STATIC_DATA + +#include "static_data.h" + +// Adopted from numpy 2.4.0: numpy/_core/src/multiarry/npy_static_data.c + +mypyc_interned_str_struct mypyc_interned_str; + +#define INTERN_STRING(struct_member, string) \ + assert(mypyc_interned_str.struct_member == NULL); \ + mypyc_interned_str.struct_member = PyUnicode_InternFromString(string); \ + if (mypyc_interned_str.struct_member == NULL) { \ + return -1; \ + } + +int +intern_strings(void) { + INTERN_STRING(__init_subclass__, "__init_subclass__"); + INTERN_STRING(__mro_entries__, "__mro_entries__"); + INTERN_STRING(__name__, "__name__"); + INTERN_STRING(__radd__, "__radd__"); + INTERN_STRING(__rsub__, "__rsub__"); + INTERN_STRING(__rmul__, "__rmul__"); + INTERN_STRING(__rtruediv__, "__rtruediv__"); + INTERN_STRING(__rmod__, "__rmod__"); + INTERN_STRING(__rdivmod__, "__rdivmod__"); + INTERN_STRING(__rfloordiv__, "__rfloordiv__"); + INTERN_STRING(__rpow__, "__rpow__"); + INTERN_STRING(__rmatmul__, "__rmatmul__"); + INTERN_STRING(__rand__, "__rand__"); + INTERN_STRING(__ror__, "__ror__"); + INTERN_STRING(__rxor__, "__rxor__"); + INTERN_STRING(__rlshift__, "__rlshift__"); + INTERN_STRING(__rrshift__, "__rrshift__"); + INTERN_STRING(__eq__, "__eq__"); + INTERN_STRING(__ne__, "__ne__"); + INTERN_STRING(__gt__, "__gt__"); + INTERN_STRING(__le__, "__le__"); + INTERN_STRING(__lt__, "__lt__"); + INTERN_STRING(__ge__, "__ge__"); + INTERN_STRING(clear, "clear"); + INTERN_STRING(close_, "close"); + INTERN_STRING(copy, "copy"); + INTERN_STRING(keys, "keys"); + INTERN_STRING(items, "items"); + INTERN_STRING(join, "join"); + INTERN_STRING(send, "send"); + INTERN_STRING(setdefault, "setdefault"); + INTERN_STRING(startswith, "startswith"); + INTERN_STRING(throw_, "throw"); + INTERN_STRING(translate, "translate"); + INTERN_STRING(update, "update"); + INTERN_STRING(values, "values"); + return 0; +} + +#endif diff --git a/mypyc/lib-rt/static_data.h b/mypyc/lib-rt/static_data.h new file mode 100644 index 000000000000..f779504b6c20 --- /dev/null +++ b/mypyc/lib-rt/static_data.h @@ -0,0 +1,59 @@ +#ifndef STATIC_DATA_H +#define STATIC_DATA_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Adopted from numpy 2.4.0: numpy/_core/src/multiarry/npy_static_data.h + +int intern_strings(void); + +typedef struct mypyc_interned_str_struct { + PyObject *__init_subclass__; + PyObject *__mro_entries__; + PyObject *__name__; + PyObject *__radd__; + PyObject *__rsub__; + PyObject *__rmul__; + PyObject *__rtruediv__; + PyObject *__rmod__; + PyObject *__rdivmod__; + PyObject *__rfloordiv__; + PyObject *__rpow__; + PyObject *__rmatmul__; + PyObject *__rand__; + PyObject *__ror__; + PyObject *__rxor__; + PyObject *__rlshift__; + PyObject *__rrshift__; + PyObject *__eq__; + PyObject *__ne__; + PyObject *__gt__; + PyObject *__le__; + PyObject *__lt__; + PyObject *__ge__; + PyObject *clear; + PyObject *close_; + PyObject *copy; + PyObject *keys; + PyObject *items; + PyObject *join; + PyObject *send; + PyObject *setdefault; + PyObject *startswith; + PyObject *throw_; + PyObject *translate; + PyObject *update; + PyObject *values; +} mypyc_interned_str_struct; + +extern mypyc_interned_str_struct mypyc_interned_str; + +#ifdef __cplusplus +} +#endif + +#endif From 0e7129f0eca5740c1bd88b03372e8dcf447bdefa Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:25:35 +0100 Subject: [PATCH 2/5] Replace _Py_IDENTIFIER --- mypyc/lib-rt/bytes_extra_ops.c | 7 +-- mypyc/lib-rt/bytes_ops.c | 14 +----- mypyc/lib-rt/dict_ops.c | 84 +++++----------------------------- mypyc/lib-rt/list_ops.c | 15 +----- mypyc/lib-rt/misc_ops.c | 11 +---- 5 files changed, 19 insertions(+), 112 deletions(-) diff --git a/mypyc/lib-rt/bytes_extra_ops.c b/mypyc/lib-rt/bytes_extra_ops.c index b5d2d9996d52..511ac0732976 100644 --- a/mypyc/lib-rt/bytes_extra_ops.c +++ b/mypyc/lib-rt/bytes_extra_ops.c @@ -41,10 +41,5 @@ PyObject *CPyBytes_Translate(PyObject *bytes, PyObject *table) { } // Fallback to Python method call for non-exact types or non-standard tables - _Py_IDENTIFIER(translate); - PyObject *name = _PyUnicode_FromId(&PyId_translate); - if (name == NULL) { - return NULL; - } - return PyObject_CallMethodOneArg(bytes, name, table); + return PyObject_CallMethodOneArg(bytes, mypyc_interned_str.translate, table); } diff --git a/mypyc/lib-rt/bytes_ops.c b/mypyc/lib-rt/bytes_ops.c index 25718b4603b3..a9b694116866 100644 --- a/mypyc/lib-rt/bytes_ops.c +++ b/mypyc/lib-rt/bytes_ops.c @@ -101,12 +101,7 @@ PyObject *CPyBytes_Join(PyObject *sep, PyObject *iter) { if (PyBytes_CheckExact(sep)) { return PyBytes_Join(sep, iter); } else { - _Py_IDENTIFIER(join); - PyObject *name = _PyUnicode_FromId(&PyId_join); /* borrowed */ - if (name == NULL) { - return NULL; - } - return PyObject_CallMethodOneArg(sep, name, iter); + return PyObject_CallMethodOneArg(sep, mypyc_interned_str.join, iter); } } @@ -193,12 +188,7 @@ int CPyBytes_Startswith(PyObject *self, PyObject *subobj) { return memcmp(self_buf, subobj_buf, (size_t)subobj_len) == 0 ? 1 : 0; } - _Py_IDENTIFIER(startswith); - PyObject *name = _PyUnicode_FromId(&PyId_startswith); - if (name == NULL) { - return 2; - } - PyObject *result = PyObject_CallMethodOneArg(self, name, subobj); + PyObject *result = PyObject_CallMethodOneArg(self, mypyc_interned_str.startswith, subobj); if (result == NULL) { return 2; } diff --git a/mypyc/lib-rt/dict_ops.c b/mypyc/lib-rt/dict_ops.c index b102aba57307..a1b1d94efea9 100644 --- a/mypyc/lib-rt/dict_ops.c +++ b/mypyc/lib-rt/dict_ops.c @@ -77,12 +77,7 @@ PyObject *CPyDict_SetDefault(PyObject *dict, PyObject *key, PyObject *value) { Py_XINCREF(ret); return ret; } - _Py_IDENTIFIER(setdefault); - PyObject *name = _PyUnicode_FromId(&PyId_setdefault); /* borrowed */ - if (name == NULL) { - return NULL; - } - return PyObject_CallMethodObjArgs(dict, name, key, value, NULL); + return PyObject_CallMethodObjArgs(dict, mypyc_interned_str.setdefault, key, value, NULL); } PyObject *CPyDict_SetDefaultWithNone(PyObject *dict, PyObject *key) { @@ -136,12 +131,7 @@ static inline int CPy_ObjectToStatus(PyObject *obj) { } static int CPyDict_UpdateGeneral(PyObject *dict, PyObject *stuff) { - _Py_IDENTIFIER(update); - PyObject *name = _PyUnicode_FromId(&PyId_update); /* borrowed */ - if (name == NULL) { - return -1; - } - PyObject *res = PyObject_CallMethodOneArg(dict, name, stuff); + PyObject *res = PyObject_CallMethodOneArg(dict, mypyc_interned_str.update, stuff); return CPy_ObjectToStatus(res); } @@ -207,36 +197,21 @@ PyObject *CPyDict_KeysView(PyObject *dict) { if (PyDict_CheckExact(dict)){ return _CPyDictView_New(dict, &PyDictKeys_Type); } - _Py_IDENTIFIER(keys); - PyObject *name = _PyUnicode_FromId(&PyId_keys); /* borrowed */ - if (name == NULL) { - return NULL; - } - return PyObject_CallMethodNoArgs(dict, name); + return PyObject_CallMethodNoArgs(dict, mypyc_interned_str.keys); } PyObject *CPyDict_ValuesView(PyObject *dict) { if (PyDict_CheckExact(dict)){ return _CPyDictView_New(dict, &PyDictValues_Type); } - _Py_IDENTIFIER(values); - PyObject *name = _PyUnicode_FromId(&PyId_values); /* borrowed */ - if (name == NULL) { - return NULL; - } - return PyObject_CallMethodNoArgs(dict, name); + return PyObject_CallMethodNoArgs(dict, mypyc_interned_str.values); } PyObject *CPyDict_ItemsView(PyObject *dict) { if (PyDict_CheckExact(dict)){ return _CPyDictView_New(dict, &PyDictItems_Type); } - _Py_IDENTIFIER(items); - PyObject *name = _PyUnicode_FromId(&PyId_items); /* borrowed */ - if (name == NULL) { - return NULL; - } - return PyObject_CallMethodNoArgs(dict, name); + return PyObject_CallMethodNoArgs(dict, mypyc_interned_str.items); } PyObject *CPyDict_Keys(PyObject *dict) { @@ -245,12 +220,7 @@ PyObject *CPyDict_Keys(PyObject *dict) { } // Inline generic fallback logic to also return a list. PyObject *list = PyList_New(0); - _Py_IDENTIFIER(keys); - PyObject *name = _PyUnicode_FromId(&PyId_keys); /* borrowed */ - if (name == NULL) { - return NULL; - } - PyObject *view = PyObject_CallMethodNoArgs(dict, name); + PyObject *view = PyObject_CallMethodNoArgs(dict, mypyc_interned_str.keys); if (view == NULL) { return NULL; } @@ -268,12 +238,7 @@ PyObject *CPyDict_Values(PyObject *dict) { } // Inline generic fallback logic to also return a list. PyObject *list = PyList_New(0); - _Py_IDENTIFIER(values); - PyObject *name = _PyUnicode_FromId(&PyId_values); /* borrowed */ - if (name == NULL) { - return NULL; - } - PyObject *view = PyObject_CallMethodNoArgs(dict, name); + PyObject *view = PyObject_CallMethodNoArgs(dict, mypyc_interned_str.values); if (view == NULL) { return NULL; } @@ -291,12 +256,7 @@ PyObject *CPyDict_Items(PyObject *dict) { } // Inline generic fallback logic to also return a list. PyObject *list = PyList_New(0); - _Py_IDENTIFIER(items); - PyObject *name = _PyUnicode_FromId(&PyId_items); /* borrowed */ - if (name == NULL) { - return NULL; - } - PyObject *view = PyObject_CallMethodNoArgs(dict, name); + PyObject *view = PyObject_CallMethodNoArgs(dict, mypyc_interned_str.items); if (view == NULL) { return NULL; } @@ -312,12 +272,7 @@ char CPyDict_Clear(PyObject *dict) { if (PyDict_CheckExact(dict)) { PyDict_Clear(dict); } else { - _Py_IDENTIFIER(clear); - PyObject *name = _PyUnicode_FromId(&PyId_clear); /* borrowed */ - if (name == NULL) { - return 0; - } - PyObject *res = PyObject_CallMethodNoArgs(dict, name); + PyObject *res = PyObject_CallMethodNoArgs(dict, mypyc_interned_str.clear); if (res == NULL) { return 0; } @@ -329,12 +284,7 @@ PyObject *CPyDict_Copy(PyObject *dict) { if (PyDict_CheckExact(dict)) { return PyDict_Copy(dict); } - _Py_IDENTIFIER(copy); - PyObject *name = _PyUnicode_FromId(&PyId_copy); /* borrowed */ - if (name == NULL) { - return NULL; - } - return PyObject_CallMethodNoArgs(dict, name); + return PyObject_CallMethodNoArgs(dict, mypyc_interned_str.copy); } PyObject *CPyDict_GetKeysIter(PyObject *dict) { @@ -352,12 +302,7 @@ PyObject *CPyDict_GetItemsIter(PyObject *dict) { Py_INCREF(dict); return dict; } - _Py_IDENTIFIER(items); - PyObject *name = _PyUnicode_FromId(&PyId_items); /* borrowed */ - if (name == NULL) { - return NULL; - } - PyObject *view = PyObject_CallMethodNoArgs(dict, name); + PyObject *view = PyObject_CallMethodNoArgs(dict, mypyc_interned_str.items); if (view == NULL) { return NULL; } @@ -372,12 +317,7 @@ PyObject *CPyDict_GetValuesIter(PyObject *dict) { Py_INCREF(dict); return dict; } - _Py_IDENTIFIER(values); - PyObject *name = _PyUnicode_FromId(&PyId_values); /* borrowed */ - if (name == NULL) { - return NULL; - } - PyObject *view = PyObject_CallMethodNoArgs(dict, name); + PyObject *view = PyObject_CallMethodNoArgs(dict, mypyc_interned_str.values); if (view == NULL) { return NULL; } diff --git a/mypyc/lib-rt/list_ops.c b/mypyc/lib-rt/list_ops.c index c611907fb601..ebfdafdb2ef4 100644 --- a/mypyc/lib-rt/list_ops.c +++ b/mypyc/lib-rt/list_ops.c @@ -33,12 +33,7 @@ char CPyList_Clear(PyObject *list) { if (PyList_CheckExact(list)) { PyList_Clear(list); } else { - _Py_IDENTIFIER(clear); - PyObject *name = _PyUnicode_FromId(&PyId_clear); - if (name == NULL) { - return 0; - } - PyObject *res = PyObject_CallMethodNoArgs(list, name); + PyObject *res = PyObject_CallMethodNoArgs(list, mypyc_interned_str.clear); if (res == NULL) { return 0; } @@ -50,13 +45,7 @@ PyObject *CPyList_Copy(PyObject *list) { if(PyList_CheckExact(list)) { return PyList_GetSlice(list, 0, PyList_GET_SIZE(list)); } - _Py_IDENTIFIER(copy); - - PyObject *name = _PyUnicode_FromId(&PyId_copy); - if (name == NULL) { - return NULL; - } - return PyObject_CallMethodNoArgs(list, name); + return PyObject_CallMethodNoArgs(list, mypyc_interned_str.copy); } PyObject *CPyList_GetItemShort(PyObject *list, CPyTagged index) { diff --git a/mypyc/lib-rt/misc_ops.c b/mypyc/lib-rt/misc_ops.c index 8e5bfffba759..0241faf6fdd3 100644 --- a/mypyc/lib-rt/misc_ops.c +++ b/mypyc/lib-rt/misc_ops.c @@ -29,12 +29,7 @@ PyObject *CPyIter_Send(PyObject *iter, PyObject *val) if (Py_IsNone(val)) { return CPyIter_Next(iter); } else { - _Py_IDENTIFIER(send); - PyObject *name = _PyUnicode_FromId(&PyId_send); /* borrowed */ - if (name == NULL) { - return NULL; - } - return PyObject_CallMethodOneArg(iter, name, val); + return PyObject_CallMethodOneArg(iter, mypyc_interned_str.send, val); } } @@ -1065,9 +1060,7 @@ PyObject *CPy_GetName(PyObject *obj) { if (PyType_Check(obj)) { return PyType_GetName((PyTypeObject *)obj); } - _Py_IDENTIFIER(__name__); - PyObject *name = _PyUnicode_FromId(&PyId___name__); /* borrowed */ - return PyObject_GetAttr(obj, name); + return PyObject_GetAttr(obj, mypyc_interned_str.__name__); } #endif From 0bc3066d4d642709f76dfbab9302ad7b433bbf0c Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Mon, 22 Dec 2025 17:37:42 +0100 Subject: [PATCH 3/5] A few more --- mypyc/codegen/emitwrapper.py | 3 +-- mypyc/lib-rt/CPy.h | 2 +- mypyc/lib-rt/dict_ops.c | 6 ++---- mypyc/lib-rt/misc_ops.c | 10 ++++------ mypyc/lib-rt/pythonsupport.h | 14 ++++---------- 5 files changed, 12 insertions(+), 23 deletions(-) diff --git a/mypyc/codegen/emitwrapper.py b/mypyc/codegen/emitwrapper.py index 2e5d7efa4e98..9118f0d5bc25 100644 --- a/mypyc/codegen/emitwrapper.py +++ b/mypyc/codegen/emitwrapper.py @@ -452,9 +452,8 @@ def generate_bin_op_reverse_dunder_call(fn: FuncIR, emitter: Emitter, rmethod: s if fn.name in ("__pow__", "__rpow__"): # Ternary pow() will never call the reverse dunder. emitter.emit_line("if (obj_mod == Py_None) {") - emitter.emit_line(f"_Py_IDENTIFIER({rmethod});") emitter.emit_line( - 'return CPy_CallReverseOpMethod(obj_left, obj_right, "{}", &PyId_{});'.format( + 'return CPy_CallReverseOpMethod(obj_left, obj_right, "{}", mypyc_interned_str.{});'.format( op_methods_to_symbols[fn.name], rmethod ) ) diff --git a/mypyc/lib-rt/CPy.h b/mypyc/lib-rt/CPy.h index df251da13fe5..fc4906f41916 100644 --- a/mypyc/lib-rt/CPy.h +++ b/mypyc/lib-rt/CPy.h @@ -938,7 +938,7 @@ int CPyStatics_Initialize(PyObject **statics, const int *frozensets); PyObject *CPy_Super(PyObject *builtins, PyObject *self); PyObject *CPy_CallReverseOpMethod(PyObject *left, PyObject *right, const char *op, - _Py_Identifier *method); + PyObject *method); bool CPyImport_ImportMany(PyObject *modules, CPyModule **statics[], PyObject *globals, PyObject *tb_path, PyObject *tb_function, Py_ssize_t *tb_lines); diff --git a/mypyc/lib-rt/dict_ops.c b/mypyc/lib-rt/dict_ops.c index a1b1d94efea9..b4ae5ad01a38 100644 --- a/mypyc/lib-rt/dict_ops.c +++ b/mypyc/lib-rt/dict_ops.c @@ -159,8 +159,7 @@ int CPyDict_Update(PyObject *dict, PyObject *stuff) { int CPyDict_UpdateFromAny(PyObject *dict, PyObject *stuff) { if (PyDict_CheckExact(dict)) { // Argh this sucks - _Py_IDENTIFIER(keys); - if (PyDict_Check(stuff) || _CPyObject_HasAttrId(stuff, &PyId_keys)) { + if (PyDict_Check(stuff) || _CPyObject_HasAttr(stuff, mypyc_interned_str.keys)) { return PyDict_Update(dict, stuff); } else { return PyDict_MergeFromSeq2(dict, stuff, 1); @@ -179,8 +178,7 @@ PyObject *CPyDict_FromAny(PyObject *obj) { if (!dict) { return NULL; } - _Py_IDENTIFIER(keys); - if (_CPyObject_HasAttrId(obj, &PyId_keys)) { + if (_CPyObject_HasAttr(obj, mypyc_interned_str.keys)) { res = PyDict_Update(dict, obj); } else { res = PyDict_MergeFromSeq2(dict, obj, 1); diff --git a/mypyc/lib-rt/misc_ops.c b/mypyc/lib-rt/misc_ops.c index 0241faf6fdd3..38472b33291f 100644 --- a/mypyc/lib-rt/misc_ops.c +++ b/mypyc/lib-rt/misc_ops.c @@ -45,8 +45,6 @@ PyObject *CPyIter_Send(PyObject *iter, PyObject *val) // Signals an error (2) if the an exception should be propagated. int CPy_YieldFromErrorHandle(PyObject *iter, PyObject **outp) { - _Py_IDENTIFIER(close); - _Py_IDENTIFIER(throw); PyObject *exc_type = (PyObject *)Py_TYPE(CPy_ExcState()->exc_value); PyObject *type, *value, *traceback; PyObject *_m; @@ -54,7 +52,7 @@ int CPy_YieldFromErrorHandle(PyObject *iter, PyObject **outp) *outp = NULL; if (PyErr_GivenExceptionMatches(exc_type, PyExc_GeneratorExit)) { - _m = _PyObject_GetAttrId(iter, &PyId_close); + _m = PyObject_GetAttr(iter, mypyc_interned_str.close_); if (_m) { res = PyObject_CallNoArgs(_m); Py_DECREF(_m); @@ -67,7 +65,7 @@ int CPy_YieldFromErrorHandle(PyObject *iter, PyObject **outp) return 2; } } else { - _m = _PyObject_GetAttrId(iter, &PyId_throw); + _m = PyObject_GetAttr(iter, mypyc_interned_str.throw_); if (_m) { _CPy_GetExcInfo(&type, &value, &traceback); res = PyObject_CallFunctionObjArgs(_m, type, value, traceback, NULL); @@ -872,9 +870,9 @@ PyObject * CPy_CallReverseOpMethod(PyObject *left, PyObject *right, const char *op, - _Py_Identifier *method) { + PyObject *method) { // Look up reverse method - PyObject *m = _PyObject_GetAttrId(right, method); + PyObject *m = PyObject_GetAttr(right, method); if (m == NULL) { // If reverse method not defined, generate TypeError instead AttributeError if (PyErr_ExceptionMatches(PyExc_AttributeError)) { diff --git a/mypyc/lib-rt/pythonsupport.h b/mypyc/lib-rt/pythonsupport.h index c93f5606424a..366d014cca73 100644 --- a/mypyc/lib-rt/pythonsupport.h +++ b/mypyc/lib-rt/pythonsupport.h @@ -36,7 +36,6 @@ extern "C" { ///////////////////////////////////////// // Adapted from bltinmodule.c in Python 3.7.0 -_Py_IDENTIFIER(__mro_entries__); static PyObject* update_bases(PyObject *bases) { @@ -58,7 +57,7 @@ update_bases(PyObject *bases) } continue; } - if (PyObject_GetOptionalAttrString(base, PyId___mro_entries__.string, &meth) < 0) { + if (PyObject_GetOptionalAttrString(base, "__mro_entries__", &meth) < 0) { goto error; } if (!meth) { @@ -111,7 +110,6 @@ update_bases(PyObject *bases) } // From Python 3.7's typeobject.c -_Py_IDENTIFIER(__init_subclass__); static int init_subclass(PyTypeObject *type, PyObject *kwds) { @@ -123,7 +121,7 @@ init_subclass(PyTypeObject *type, PyObject *kwds) return -1; } - func = _PyObject_GetAttrId(super, &PyId___init_subclass__); + func = PyObject_GetAttrString(super, "__init_subclass__"); Py_DECREF(super); if (func == NULL) { return -1; @@ -378,19 +376,15 @@ _CPyDictView_New(PyObject *dict, PyTypeObject *type) } #endif -#if PY_VERSION_HEX >= 0x030A0000 // 3.10 static int -_CPyObject_HasAttrId(PyObject *v, _Py_Identifier *name) { +_CPyObject_HasAttr(PyObject *v, PyObject *name) { PyObject *tmp = NULL; - int result = PyObject_GetOptionalAttrString(v, name->string, &tmp); + int result = PyObject_GetOptionalAttr(v, name, &tmp); if (tmp) { Py_DECREF(tmp); } return result; } -#else -#define _CPyObject_HasAttrId _PyObject_HasAttrId -#endif #if CPY_3_12_FEATURES From 1aeb2c5138736d0e3b0e6235456cfbd98649376a Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Tue, 23 Dec 2025 02:41:22 +0100 Subject: [PATCH 4/5] Update emitmodule --- mypyc/codegen/emitmodule.py | 1 + mypyc/common.py | 1 + mypyc/lib-rt/init.c | 2 -- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mypyc/codegen/emitmodule.py b/mypyc/codegen/emitmodule.py index a56083796e79..d724e7a52cdf 100644 --- a/mypyc/codegen/emitmodule.py +++ b/mypyc/codegen/emitmodule.py @@ -1087,6 +1087,7 @@ def emit_module_exec_func( declaration = f"int CPyExec_{exported_name(module_name)}(PyObject *module)" module_static = self.module_internal_static_name(module_name, emitter) emitter.emit_lines(declaration, "{") + emitter.emit_line("intern_strings();") if self.compiler_options.depends_on_librt_internal: emitter.emit_line("if (import_librt_internal() < 0) {") emitter.emit_line("return -1;") diff --git a/mypyc/common.py b/mypyc/common.py index 4ee004c0dd0f..26d1003a44fc 100644 --- a/mypyc/common.py +++ b/mypyc/common.py @@ -68,6 +68,7 @@ # Runtime C library files that are always included (some ops may bring # extra dependencies via mypyc.ir.SourceDep) RUNTIME_C_FILES: Final = [ + "static_data.c", "init.c", "getargs.c", "getargsfast.c", diff --git a/mypyc/lib-rt/init.c b/mypyc/lib-rt/init.c index 567730fd8f56..9215c2d59019 100644 --- a/mypyc/lib-rt/init.c +++ b/mypyc/lib-rt/init.c @@ -1,6 +1,5 @@ #include #include "CPy.h" -#include "static_data.c" struct ExcDummyStruct _CPy_ExcDummyStruct = { PyObject_HEAD_INIT(NULL) }; PyObject *_CPy_ExcDummy = (PyObject *)&_CPy_ExcDummyStruct; @@ -13,7 +12,6 @@ PyObject * __mypyc_empty_tuple__ = NULL; // other dynamic libraries. This means we need to initialize // things at load time. void CPy_Init(void) { - intern_strings(); _CPy_ExcDummyStruct.ob_base.ob_type = &PyBaseObject_Type; // Initialize system-wide empty tuple constant From 796672f6877669b4941517ba12029f11fb0077ae Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Tue, 23 Dec 2025 02:55:26 +0100 Subject: [PATCH 5/5] Add back include --- mypyc/common.py | 1 - mypyc/lib-rt/init.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/mypyc/common.py b/mypyc/common.py index 26d1003a44fc..4ee004c0dd0f 100644 --- a/mypyc/common.py +++ b/mypyc/common.py @@ -68,7 +68,6 @@ # Runtime C library files that are always included (some ops may bring # extra dependencies via mypyc.ir.SourceDep) RUNTIME_C_FILES: Final = [ - "static_data.c", "init.c", "getargs.c", "getargsfast.c", diff --git a/mypyc/lib-rt/init.c b/mypyc/lib-rt/init.c index 9215c2d59019..4ec2adc79077 100644 --- a/mypyc/lib-rt/init.c +++ b/mypyc/lib-rt/init.c @@ -1,5 +1,6 @@ #include #include "CPy.h" +#include "static_data.c" struct ExcDummyStruct _CPy_ExcDummyStruct = { PyObject_HEAD_INIT(NULL) }; PyObject *_CPy_ExcDummy = (PyObject *)&_CPy_ExcDummyStruct;