@@ -2763,7 +2763,7 @@ PyObject *
2763
2763
_PyEval_ImportFrom (PyThreadState * tstate , PyObject * v , PyObject * name )
2764
2764
{
2765
2765
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 ;
2767
2767
2768
2768
if (PyObject_GetOptionalAttr (v , name , & x ) != 0 ) {
2769
2769
return x ;
@@ -2790,6 +2790,7 @@ _PyEval_ImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
2790
2790
}
2791
2791
Py_DECREF (mod_name );
2792
2792
return x ;
2793
+
2793
2794
error :
2794
2795
if (mod_name == NULL ) {
2795
2796
mod_name_or_unknown = PyUnicode_FromString ("<unknown module name>" );
@@ -2799,52 +2800,55 @@ _PyEval_ImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
2799
2800
} else {
2800
2801
mod_name_or_unknown = mod_name ;
2801
2802
}
2803
+ // mod_name is no longer an owned reference
2804
+ assert (mod_name == NULL || mod_name == mod_name_or_unknown );
2802
2805
2803
2806
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 ;
2814
2810
}
2815
- if (origin == NULL || !PyUnicode_Check (origin )) {
2816
- Py_CLEAR (origin );
2811
+ if (spec == NULL ) {
2817
2812
errmsg = PyUnicode_FromFormat (
2818
2813
"cannot import name %R from %R (unknown location)" ,
2819
2814
name , mod_name_or_unknown
2820
2815
);
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 ;
2821
2827
}
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)" ;
2839
2828
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 ;
2841
2834
}
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 :
2842
2844
/* NULL checks for errmsg and mod_name done by PyErr_SetImportError. */
2843
2845
_PyErr_SetImportErrorWithNameFrom (errmsg , mod_name , origin , name );
2846
+ Py_DECREF (errmsg );
2844
2847
2845
- Py_XDECREF (errmsg );
2846
- Py_DECREF (mod_name_or_unknown );
2848
+ done :
2847
2849
Py_XDECREF (origin );
2850
+ Py_XDECREF (spec );
2851
+ Py_DECREF (mod_name_or_unknown );
2848
2852
return NULL ;
2849
2853
}
2850
2854
0 commit comments