|
|
@@ -375,23 +375,26 @@ static PyObject *Dtool_EnumType_Repr(PyObject *self) {
|
|
|
* should be a tuple of (name, value) pairs.
|
|
|
*/
|
|
|
PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) {
|
|
|
- static PyObject *enum_class = nullptr;
|
|
|
#if PY_VERSION_HEX >= 0x03040000
|
|
|
- static PyObject *enum_meta = nullptr;
|
|
|
- static PyObject *enum_create = nullptr;
|
|
|
- if (enum_meta == nullptr) {
|
|
|
- PyObject *enum_module = PyImport_ImportModule("enum");
|
|
|
- nassertr_always(enum_module != nullptr, nullptr);
|
|
|
+ PyObject *enum_module = PyImport_ImportModule("enum");
|
|
|
+ nassertr_always(enum_module != nullptr, nullptr);
|
|
|
|
|
|
- enum_class = PyObject_GetAttrString(enum_module, "Enum");
|
|
|
- enum_meta = PyObject_GetAttrString(enum_module, "EnumMeta");
|
|
|
- enum_create = PyObject_GetAttrString(enum_meta, "_create_");
|
|
|
- nassertr(enum_meta != nullptr, nullptr);
|
|
|
- }
|
|
|
+ PyObject *enum_meta = PyObject_GetAttrString(enum_module, "EnumMeta");
|
|
|
+ nassertr(enum_meta != nullptr, nullptr);
|
|
|
+
|
|
|
+ PyObject *enum_class = PyObject_GetAttrString(enum_module, "Enum");
|
|
|
+ Py_DECREF(enum_module);
|
|
|
+ nassertr(enum_class != nullptr, nullptr);
|
|
|
+
|
|
|
+ PyObject *enum_create = PyObject_GetAttrString(enum_meta, "_create_");
|
|
|
+ Py_DECREF(enum_meta);
|
|
|
|
|
|
PyObject *result = PyObject_CallFunction(enum_create, (char *)"OsN", enum_class, name, names);
|
|
|
+ Py_DECREF(enum_create);
|
|
|
+ Py_DECREF(enum_class);
|
|
|
nassertr(result != nullptr, nullptr);
|
|
|
#else
|
|
|
+ static PyObject *enum_class = nullptr;
|
|
|
static PyObject *name_str;
|
|
|
static PyObject *name_sunder_str;
|
|
|
static PyObject *value_str;
|
|
|
@@ -528,16 +531,39 @@ PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_class
|
|
|
* Returns a borrowed reference to the global type dictionary.
|
|
|
*/
|
|
|
Dtool_TypeMap *Dtool_GetGlobalTypeMap() {
|
|
|
+#if PY_VERSION_HEX >= 0x030d0000 // 3.13
|
|
|
+ PyObject *istate_dict = PyInterpreterState_GetDict(PyInterpreterState_Get());
|
|
|
+ PyObject *key = PyUnicode_InternFromString("_interrogate_types");
|
|
|
+ PyObject *capsule = PyDict_GetItem(istate_dict, key);
|
|
|
+ if (capsule != nullptr) {
|
|
|
+ Py_DECREF(key);
|
|
|
+ return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
|
|
|
+ }
|
|
|
+#else
|
|
|
PyObject *capsule = PySys_GetObject((char *)"_interrogate_types");
|
|
|
if (capsule != nullptr) {
|
|
|
return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
|
|
|
- } else {
|
|
|
- Dtool_TypeMap *type_map = new Dtool_TypeMap;
|
|
|
- capsule = PyCapsule_New((void *)type_map, nullptr, nullptr);
|
|
|
- PySys_SetObject((char *)"_interrogate_types", capsule);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ Dtool_TypeMap *type_map = new Dtool_TypeMap;
|
|
|
+ capsule = PyCapsule_New((void *)type_map, nullptr, nullptr);
|
|
|
+
|
|
|
+#if PY_VERSION_HEX >= 0x030d0000 // 3.13
|
|
|
+ PyObject *result;
|
|
|
+ if (PyDict_SetDefaultRef(istate_dict, key, capsule, &result) != 0) {
|
|
|
+ // Another thread already beat us to it.
|
|
|
Py_DECREF(capsule);
|
|
|
- return type_map;
|
|
|
+ delete type_map;
|
|
|
+ capsule = result;
|
|
|
+ type_map = (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
|
|
|
}
|
|
|
+ Py_DECREF(key);
|
|
|
+#endif
|
|
|
+
|
|
|
+ PySys_SetObject((char *)"_interrogate_types", capsule);
|
|
|
+ Py_DECREF(capsule);
|
|
|
+ return type_map;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -594,6 +620,10 @@ PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulen
|
|
|
|
|
|
Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
|
|
|
|
|
|
+#ifdef Py_GIL_DISABLED
|
|
|
+ PyMutex_Lock(&type_map->_lock);
|
|
|
+#endif
|
|
|
+
|
|
|
// the module level function inits....
|
|
|
MethodDefmap functions;
|
|
|
for (size_t i = 0; defs[i] != nullptr; i++) {
|
|
|
@@ -627,12 +657,19 @@ PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulen
|
|
|
if (it != type_map->end()) {
|
|
|
types->type = it->second;
|
|
|
} else {
|
|
|
- return PyErr_Format(PyExc_NameError, "name '%s' is not defined", types->name);
|
|
|
+ PyErr_Format(PyExc_NameError, "name '%s' is not defined", types->name);
|
|
|
+#ifdef Py_GIL_DISABLED
|
|
|
+ PyMutex_Unlock(&type_map->_lock);
|
|
|
+#endif
|
|
|
+ return nullptr;
|
|
|
}
|
|
|
++types;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+#ifdef Py_GIL_DISABLED
|
|
|
+ PyMutex_Unlock(&type_map->_lock);
|
|
|
+#endif
|
|
|
|
|
|
PyMethodDef *newdef = new PyMethodDef[functions.size() + 1];
|
|
|
MethodDefmap::iterator mi;
|