summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShantanu <12621235+hauntsaninja@users.noreply.github.com>2024-12-20 08:22:26 (GMT)
committerGitHub <noreply@github.com>2024-12-20 08:22:26 (GMT)
commit45e6dd63b88a782f2ec96ab1da54eb5a074d8f4c (patch)
treefad1d18683f0a9bd13d538c3626bedc0988653d3
parentdaa260ebb1c1b20321e7f26df7c9dbd35d4edcbf (diff)
downloadcpython-45e6dd63b88a782f2ec96ab1da54eb5a074d8f4c.zip
cpython-45e6dd63b88a782f2ec96ab1da54eb5a074d8f4c.tar.gz
cpython-45e6dd63b88a782f2ec96ab1da54eb5a074d8f4c.tar.bz2
gh-128030: Avoid error from PyModule_GetFilenameObject for non-module (#128047)
I missed the extra `PyModule_Check` in #127660 because I was looking at 3.12 as the base implementation for import from. This meant that I missed the `PyModuleCheck` introduced in #112661.
-rw-r--r--Lib/test/test_import/__init__.py23
-rw-r--r--Misc/NEWS.d/next/Core_and_Builtins/2024-12-17-22-28-15.gh-issue-128030.H1ptOD.rst1
-rw-r--r--Python/ceval.c2
3 files changed, 25 insertions, 1 deletions
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index 83efbc1..c2cec64 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -851,6 +851,29 @@ from os import this_will_never_exist
stdout, stderr = popen.communicate()
self.assertIn(expected_error, stdout)
+ def test_non_module_from_import_error(self):
+ prefix = """
+import sys
+class NotAModule: ...
+nm = NotAModule()
+nm.symbol = 123
+sys.modules["not_a_module"] = nm
+from not_a_module import symbol
+"""
+ scripts = [
+ prefix + "from not_a_module import missing_symbol",
+ prefix + "nm.__spec__ = []\nfrom not_a_module import missing_symbol",
+ ]
+ for script in scripts:
+ with self.subTest(script=script):
+ expected_error = (
+ b"ImportError: cannot import name 'missing_symbol' from "
+ b"'<unknown module name>' (unknown location)"
+ )
+ popen = script_helper.spawn_python("-c", script)
+ stdout, stderr = popen.communicate()
+ self.assertIn(expected_error, stdout)
+
def test_script_shadowing_stdlib(self):
script_errors = [
(
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-17-22-28-15.gh-issue-128030.H1ptOD.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-17-22-28-15.gh-issue-128030.H1ptOD.rst
new file mode 100644
index 0000000..93d7863
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-17-22-28-15.gh-issue-128030.H1ptOD.rst
@@ -0,0 +1 @@
+Avoid error from calling ``PyModule_GetFilenameObject`` on a non-module object when importing a non-existent symbol from a non-module object.
diff --git a/Python/ceval.c b/Python/ceval.c
index fd891d7..bfdf568 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2860,7 +2860,7 @@ _PyEval_ImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
}
}
- if (origin == NULL) {
+ if (origin == NULL && PyModule_Check(v)) {
// Fall back to __file__ for diagnostics if we don't have
// an origin that is a location
origin = PyModule_GetFilenameObject(v);