@@ -702,7 +702,11 @@ int
702702_PyModuleSpec_IsInitializing(PyObject*spec)
703703{
704704if (spec!=NULL) {
705-PyObject*value=PyObject_GetAttr(spec, &_Py_ID(_initializing));
705+PyObject*value;
706+intok=_PyObject_LookupAttr(spec, &_Py_ID(_initializing), &value);
707+if (ok==0) {
708+return0;
709+ }
706710if (value!=NULL) {
707711intinitializing=PyObject_IsTrue(value);
708712Py_DECREF(value);
@@ -738,19 +742,37 @@ _PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name)
738742returnis_uninitialized;
739743}
740744741-staticPyObject*
742-module_getattro(PyModuleObject*m, PyObject*name)
745+PyObject*
746+_Py_module_getattro_impl(PyModuleObject*m, PyObject*name, intsuppress)
743747{
748+// When suppress=1, this function suppresses AttributeError.
744749PyObject*attr, *mod_name, *getattr;
745-attr=PyObject_GenericGetAttr((PyObject*)m, name);
746-if (attr|| !PyErr_ExceptionMatches(PyExc_AttributeError)) {
750+attr=_PyObject_GenericGetAttrWithDict((PyObject*)m, name, NULL, suppress);
751+if (attr) {
747752returnattr;
748753 }
749-PyErr_Clear();
754+if (suppress==1) {
755+if (PyErr_Occurred()) {
756+// pass up non-AttributeError exception
757+returnNULL;
758+ }
759+ }
760+else {
761+if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
762+// pass up non-AttributeError exception
763+returnNULL;
764+ }
765+PyErr_Clear();
766+ }
750767assert(m->md_dict!=NULL);
751768getattr=PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__));
752769if (getattr) {
753-returnPyObject_CallOneArg(getattr, name);
770+PyObject*result=PyObject_CallOneArg(getattr, name);
771+if (result==NULL&&suppress==1&&PyErr_ExceptionMatches(PyExc_AttributeError)) {
772+// suppress AttributeError
773+PyErr_Clear();
774+ }
775+returnresult;
754776 }
755777if (PyErr_Occurred()) {
756778returnNULL;
@@ -763,37 +785,48 @@ module_getattro(PyModuleObject *m, PyObject *name)
763785Py_DECREF(mod_name);
764786returnNULL;
765787 }
766-Py_XINCREF(spec);
767-if (_PyModuleSpec_IsInitializing(spec)) {
768-PyErr_Format(PyExc_AttributeError,
769-"partially initialized "
770-"module '%U' has no attribute '%U' "
771-"(most likely due to a circular import)",
772-mod_name, name);
773- }
774-elseif (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) {
775-PyErr_Format(PyExc_AttributeError,
776-"cannot access submodule '%U' of module '%U' "
777-"(most likely due to a circular import)",
778-name, mod_name);
779- }
780-else {
781-PyErr_Format(PyExc_AttributeError,
782-"module '%U' has no attribute '%U'",
783-mod_name, name);
788+if (suppress!=1) {
789+Py_XINCREF(spec);
790+if (_PyModuleSpec_IsInitializing(spec)) {
791+PyErr_Format(PyExc_AttributeError,
792+"partially initialized "
793+"module '%U' has no attribute '%U' "
794+"(most likely due to a circular import)",
795+mod_name, name);
796+ }
797+elseif (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) {
798+PyErr_Format(PyExc_AttributeError,
799+"cannot access submodule '%U' of module '%U' "
800+"(most likely due to a circular import)",
801+name, mod_name);
802+ }
803+else {
804+PyErr_Format(PyExc_AttributeError,
805+"module '%U' has no attribute '%U'",
806+mod_name, name);
807+ }
808+Py_XDECREF(spec);
784809 }
785-Py_XDECREF(spec);
786810Py_DECREF(mod_name);
787811returnNULL;
788812 }
789813elseif (PyErr_Occurred()) {
790814returnNULL;
791815 }
792-PyErr_Format(PyExc_AttributeError,
793-"module has no attribute '%U'", name);
816+if (suppress!=1) {
817+PyErr_Format(PyExc_AttributeError,
818+"module has no attribute '%U'", name);
819+ }
794820returnNULL;
795821}
796822823+824+PyObject*
825+_Py_module_getattro(PyModuleObject*m, PyObject*name)
826+{
827+return_Py_module_getattro_impl(m, name, 0);
828+}
829+797830staticint
798831module_traverse(PyModuleObject*m, visitprocvisit, void*arg)
799832{
@@ -951,7 +984,7 @@ PyTypeObject PyModule_Type = {
9519840, /* tp_hash */
9529850, /* tp_call */
9539860, /* tp_str */
954- (getattrofunc)module_getattro, /* tp_getattro */
987+ (getattrofunc)_Py_module_getattro,/* tp_getattro */
955988PyObject_GenericSetAttr, /* tp_setattro */
9569890, /* tp_as_buffer */
957990Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |