@@ -2763,7 +2763,7 @@ PyObject *
27632763_PyEval_ImportFrom (PyThreadState * tstate , PyObject * v , PyObject * name )
27642764{
27652765 PyObject * x ;
2766- PyObject * fullmodname , * mod_name , * origin , * mod_name_or_unknown , * errmsg ;
2766+ PyObject * fullmodname , * mod_name , * origin , * mod_name_or_unknown , * errmsg , * spec ;
27672767
27682768 if (PyObject_GetOptionalAttr (v , name , & x ) != 0 ) {
27692769 return x ;
@@ -2790,6 +2790,7 @@ _PyEval_ImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
27902790 }
27912791 Py_DECREF (mod_name );
27922792 return x ;
2793+
27932794 error :
27942795 if (mod_name == NULL ) {
27952796 mod_name_or_unknown = PyUnicode_FromString ("<unknown module name>" );
@@ -2799,52 +2800,55 @@ _PyEval_ImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
27992800 } else {
28002801 mod_name_or_unknown = mod_name ;
28012802 }
2803+ // mod_name is no longer an owned reference
2804+ assert (mod_name == NULL || mod_name == mod_name_or_unknown );
28022805
28032806 origin = NULL ;
2804- if (PyModule_Check (v )) {
2805- origin = PyModule_GetFilenameObject (v );
2806- if (origin == NULL ) {
2807- if (!PyErr_ExceptionMatches (PyExc_SystemError )) {
2808- Py_DECREF (mod_name_or_unknown );
2809- return NULL ;
2810- }
2811- // module filename missing
2812- _PyErr_Clear (tstate );
2813- }
2807+ if (PyObject_GetOptionalAttr (v , & _Py_ID (__spec__ ), & spec ) < 0 ) {
2808+ Py_DECREF (mod_name_or_unknown );
2809+ return NULL ;
28142810 }
2815- if (origin == NULL || !PyUnicode_Check (origin )) {
2816- Py_CLEAR (origin );
2811+ if (spec == NULL ) {
28172812 errmsg = PyUnicode_FromFormat (
28182813 "cannot import name %R from %R (unknown location)" ,
28192814 name , mod_name_or_unknown
28202815 );
2816+ goto done_with_errmsg ;
2817+ }
2818+ if (_PyModuleSpec_GetFileOrigin (spec , & origin ) < 0 ) {
2819+ goto done ;
2820+ }
2821+ if (origin == NULL ) {
2822+ errmsg = PyUnicode_FromFormat (
2823+ "cannot import name %R from %R (unknown location)" ,
2824+ name , mod_name_or_unknown
2825+ );
2826+ goto done_with_errmsg ;
28212827 }
2822- else {
2823- PyObject * spec ;
2824- int rc = PyObject_GetOptionalAttr (v , & _Py_ID (__spec__ ), & spec );
2825- if (rc > 0 ) {
2826- rc = _PyModuleSpec_IsInitializing (spec );
2827- Py_DECREF (spec );
2828- }
2829- if (rc < 0 ) {
2830- Py_DECREF (mod_name_or_unknown );
2831- Py_DECREF (origin );
2832- return NULL ;
2833- }
2834- const char * fmt =
2835- rc ?
2836- "cannot import name %R from partially initialized module %R "
2837- "(most likely due to a circular import) (%S)" :
2838- "cannot import name %R from %R (%S)" ;
28392828
2840- errmsg = PyUnicode_FromFormat (fmt , name , mod_name_or_unknown , origin );
2829+ int rc = _PyModuleSpec_IsInitializing (spec );
2830+ if (rc < 0 ) {
2831+ Py_DECREF (mod_name_or_unknown );
2832+ Py_DECREF (origin );
2833+ return NULL ;
28412834 }
2835+ const char * fmt =
2836+ rc ?
2837+ "cannot import name %R from partially initialized module %R "
2838+ "(most likely due to a circular import) (%S)" :
2839+ "cannot import name %R from %R (%S)" ;
2840+
2841+ errmsg = PyUnicode_FromFormat (fmt , name , mod_name_or_unknown , origin );
2842+
2843+ done_with_errmsg :
28422844 /* NULL checks for errmsg and mod_name done by PyErr_SetImportError. */
28432845 _PyErr_SetImportErrorWithNameFrom (errmsg , mod_name , origin , name );
2846+ Py_DECREF (errmsg );
28442847
2845- Py_XDECREF (errmsg );
2846- Py_DECREF (mod_name_or_unknown );
2848+ done :
28472849 Py_XDECREF (origin );
2850+ Py_XDECREF (spec );
2851+ Py_DECREF (mod_name_or_unknown );
28482852 return NULL ;
28492853}
28502854
0 commit comments