diff --git a/Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst b/Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst new file mode 100644 index 00000000000..5385a2d8dce --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst @@ -0,0 +1,2 @@ +The PyType_FromSpec*() functions no longer overwrite the type's "__module__" attribute +if it is set via "Py_tp_members" or "Py_tp_getset". diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1d556e96be5..c8f0d2ee45f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3067,23 +3067,28 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) } /* Set type.__module__ */ - s = strrchr(spec->name, '.'); - if (s != NULL) { - int err; - modname = PyUnicode_FromStringAndSize( - spec->name, (Py_ssize_t)(s - spec->name)); - if (modname == NULL) { + if (_PyDict_GetItemIdWithError(type->tp_dict, &PyId___module__) == NULL) { + if (PyErr_Occurred()) { goto fail; } - err = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname); - Py_DECREF(modname); - if (err != 0) - goto fail; - } else { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "builtin type %.200s has no __module__ attribute", - spec->name)) - goto fail; + s = strrchr(spec->name, '.'); + if (s != NULL) { + int err; + modname = PyUnicode_FromStringAndSize( + spec->name, (Py_ssize_t)(s - spec->name)); + if (modname == NULL) { + goto fail; + } + err = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname); + Py_DECREF(modname); + if (err != 0) + goto fail; + } else { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "builtin type %.200s has no __module__ attribute", + spec->name)) + goto fail; + } } return (PyObject*)res;