Skip to content

Commit 628b0d2

Browse files
hauntsaninjasrinivasreddy
authored andcommitted
pythongh-128030: Avoid error from PyModule_GetFilenameObject for non-module (python#128047)
I missed the extra `PyModule_Check` in python#127660 because I was looking at 3.12 as the base implementation for import from. This meant that I missed the `PyModuleCheck` introduced in python#112661.
1 parent 5e74c97 commit 628b0d2

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

Lib/test/test_import/__init__.py

+23
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,29 @@ def test_frozen_module_from_import_error(self):
851851
stdout, stderr = popen.communicate()
852852
self.assertIn(expected_error, stdout)
853853

854+
def test_non_module_from_import_error(self):
855+
prefix = """
856+
import sys
857+
class NotAModule: ...
858+
nm = NotAModule()
859+
nm.symbol = 123
860+
sys.modules["not_a_module"] = nm
861+
from not_a_module import symbol
862+
"""
863+
scripts = [
864+
prefix + "from not_a_module import missing_symbol",
865+
prefix + "nm.__spec__ = []\nfrom not_a_module import missing_symbol",
866+
]
867+
for script in scripts:
868+
with self.subTest(script=script):
869+
expected_error = (
870+
b"ImportError: cannot import name 'missing_symbol' from "
871+
b"'<unknown module name>' (unknown location)"
872+
)
873+
popen = script_helper.spawn_python("-c", script)
874+
stdout, stderr = popen.communicate()
875+
self.assertIn(expected_error, stdout)
876+
854877
def test_script_shadowing_stdlib(self):
855878
script_errors = [
856879
(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Avoid error from calling ``PyModule_GetFilenameObject`` on a non-module object when importing a non-existent symbol from a non-module object.

Python/ceval.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2860,7 +2860,7 @@ _PyEval_ImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
28602860
}
28612861
}
28622862

2863-
if (origin == NULL) {
2863+
if (origin == NULL && PyModule_Check(v)) {
28642864
// Fall back to __file__ for diagnostics if we don't have
28652865
// an origin that is a location
28662866
origin = PyModule_GetFilenameObject(v);

0 commit comments

Comments
 (0)