diff -r ddc95a9bc2e0 Objects/typeobject.c --- a/Objects/typeobject.c Wed Sep 07 13:18:40 2016 +0200 +++ b/Objects/typeobject.c Wed Sep 07 21:17:24 2016 +0300 @@ -455,27 +455,48 @@ type_set_qualname(PyTypeObject *type, Py static PyObject * type_module(PyTypeObject *type, void *context) { - char *s; + PyObject *mod; + const char *s; + int setmod = 0; if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { - PyObject *mod = _PyDict_GetItemId(type->tp_dict, &PyId___module__); - if (!mod) { - PyErr_Format(PyExc_AttributeError, "__module__"); - return 0; + mod = _PyDict_GetItemId(type->tp_dict, &PyId___module__); + if (mod != NULL) { + Py_INCREF(mod); + return mod; + } + PyErr_SetString(PyExc_AttributeError, "__module__"); + return NULL; + } + if (type->tp_dict && PyDict_Check(type->tp_dict)) { + mod = _PyDict_GetItemId(type->tp_dict, &PyId___module__); + if (mod != NULL && PyUnicode_Check(mod)) { + Py_INCREF(mod); + return mod; + } + setmod = (mod == NULL); + } + + s = strrchr(type->tp_name, '.'); + if (s != NULL) { + mod = PyUnicode_FromStringAndSize( + type->tp_name, (Py_ssize_t)(s - type->tp_name)); + if (mod == NULL) + return NULL; + PyUnicode_InternInPlace(&mod); + if (setmod) { + PyType_Modified(type); + if (_PyDict_SetItemId(type->tp_dict, &PyId___module__, mod) < 0) + PyErr_Clear(); } Py_INCREF(mod); return mod; } else { - PyObject *name; - s = strrchr(type->tp_name, '.'); - if (s != NULL) - return PyUnicode_FromStringAndSize( - type->tp_name, (Py_ssize_t)(s - type->tp_name)); - name = _PyUnicode_FromId(&PyId_builtins); - Py_XINCREF(name); - return name; - } + mod = _PyUnicode_FromId(&PyId_builtins); + Py_XINCREF(mod); + } + return mod; } static int