Skip to content

Commit f320f74

Browse files
[3.13] gh-128030: Avoid error from PyModule_GetFilenameObject for non-module (GH-128047) (#128114)
gh-128030: Avoid error from PyModule_GetFilenameObject for non-module (GH-128047) I missed the extra `PyModule_Check` in GH-127660 because I was looking at 3.12 as the base implementation for import from. This meant that I missed the `PyModuleCheck` introduced in GH-112661. (cherry picked from commit 45e6dd6) Co-authored-by: Shantanu <[email protected]>
1 parent 3a8bdaf commit f320f74

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

Lib/test/test_import/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,29 @@ def test_frozen_module_from_import_error(self):
870870
stdout, stderr = popen.communicate()
871871
self.assertIn(expected_error, stdout)
872872

873+
def test_non_module_from_import_error(self):
874+
prefix = """
875+
import sys
876+
class NotAModule: ...
877+
nm = NotAModule()
878+
nm.symbol = 123
879+
sys.modules["not_a_module"] = nm
880+
from not_a_module import symbol
881+
"""
882+
scripts = [
883+
prefix + "from not_a_module import missing_symbol",
884+
prefix + "nm.__spec__ = []\nfrom not_a_module import missing_symbol",
885+
]
886+
for script in scripts:
887+
with self.subTest(script=script):
888+
expected_error = (
889+
b"ImportError: cannot import name 'missing_symbol' from "
890+
b"'<unknown module name>' (unknown location)"
891+
)
892+
popen = script_helper.spawn_python("-c", script)
893+
stdout, stderr = popen.communicate()
894+
self.assertIn(expected_error, stdout)
895+
873896
def test_script_shadowing_stdlib(self):
874897
script_errors = [
875898
(
Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2781,7 +2781,7 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name)
27812781
}
27822782
}
27832783

2784-
if (origin == NULL) {
2784+
if (origin == NULL && PyModule_Check(v)) {
27852785
// Fall back to __file__ for diagnostics if we don't have
27862786
// an origin that is a location
27872787
origin = PyModule_GetFilenameObject(v);

0 commit comments

Comments
 (0)