mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
gh-127651: Use __file__ in diagnostics if origin is missing (#127660)
See the left hand side in https://github.com/python/cpython/pull/123929/files#diff-c22186367cbe20233e843261998dc027ae5f1f8c0d2e778abfa454ae74cc59deL2840-L2849
---------
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
(cherry picked from commit 3983527c3a
)
This commit is contained in:
parent
310efdabf5
commit
6441d42f92
3 changed files with 66 additions and 5 deletions
|
@ -826,6 +826,50 @@ class ImportTests(unittest.TestCase):
|
||||||
self.assertIn("Frozen object named 'x' is invalid",
|
self.assertIn("Frozen object named 'x' is invalid",
|
||||||
str(cm.exception))
|
str(cm.exception))
|
||||||
|
|
||||||
|
def test_frozen_module_from_import_error(self):
|
||||||
|
with self.assertRaises(ImportError) as cm:
|
||||||
|
from os import this_will_never_exist
|
||||||
|
self.assertIn(
|
||||||
|
f"cannot import name 'this_will_never_exist' from 'os' ({os.__file__})",
|
||||||
|
str(cm.exception),
|
||||||
|
)
|
||||||
|
with self.assertRaises(ImportError) as cm:
|
||||||
|
from sys import this_will_never_exist
|
||||||
|
self.assertIn(
|
||||||
|
"cannot import name 'this_will_never_exist' from 'sys' (unknown location)",
|
||||||
|
str(cm.exception),
|
||||||
|
)
|
||||||
|
|
||||||
|
scripts = [
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
os.__spec__.has_location = False
|
||||||
|
os.__file__ = []
|
||||||
|
from os import this_will_never_exist
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
os.__spec__.has_location = False
|
||||||
|
del os.__file__
|
||||||
|
from os import this_will_never_exist
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
os.__spec__.origin = []
|
||||||
|
os.__file__ = []
|
||||||
|
from os import this_will_never_exist
|
||||||
|
"""
|
||||||
|
]
|
||||||
|
for script in scripts:
|
||||||
|
with self.subTest(script=script):
|
||||||
|
expected_error = (
|
||||||
|
b"cannot import name 'this_will_never_exist' "
|
||||||
|
b"from 'os' (unknown location)"
|
||||||
|
)
|
||||||
|
popen = script_helper.spawn_python("-c", script)
|
||||||
|
stdout, stderr = popen.communicate()
|
||||||
|
self.assertIn(expected_error, stdout)
|
||||||
|
|
||||||
def test_script_shadowing_stdlib(self):
|
def test_script_shadowing_stdlib(self):
|
||||||
script_errors = [
|
script_errors = [
|
||||||
(
|
(
|
||||||
|
@ -1087,7 +1131,7 @@ try:
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
print(str(e))
|
print(str(e))
|
||||||
|
|
||||||
fractions.__spec__.origin = 0
|
fractions.__spec__.origin = []
|
||||||
try:
|
try:
|
||||||
fractions.Fraction
|
fractions.Fraction
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
|
@ -1111,7 +1155,7 @@ try:
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
print(str(e))
|
print(str(e))
|
||||||
|
|
||||||
fractions.__spec__.origin = 0
|
fractions.__spec__.origin = []
|
||||||
try:
|
try:
|
||||||
from fractions import Fraction
|
from fractions import Fraction
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
When raising :exc:`ImportError` for missing symbols in ``from`` imports, use ``__file__`` in the error message if ``__spec__.origin`` is not a location
|
|
@ -2785,6 +2785,20 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (origin == NULL) {
|
||||||
|
// Fall back to __file__ for diagnostics if we don't have
|
||||||
|
// an origin that is a location
|
||||||
|
origin = PyModule_GetFilenameObject(v);
|
||||||
|
if (origin == NULL) {
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_SystemError)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
// PyModule_GetFilenameObject raised "module filename missing"
|
||||||
|
_PyErr_Clear(tstate);
|
||||||
|
}
|
||||||
|
assert(origin == NULL || PyUnicode_Check(origin));
|
||||||
|
}
|
||||||
|
|
||||||
if (is_possibly_shadowing_stdlib) {
|
if (is_possibly_shadowing_stdlib) {
|
||||||
assert(origin);
|
assert(origin);
|
||||||
errmsg = PyUnicode_FromFormat(
|
errmsg = PyUnicode_FromFormat(
|
||||||
|
@ -2845,9 +2859,11 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
done_with_errmsg:
|
done_with_errmsg:
|
||||||
/* NULL checks for errmsg, mod_name, origin done by PyErr_SetImportError. */
|
if (errmsg != NULL) {
|
||||||
_PyErr_SetImportErrorWithNameFrom(errmsg, mod_name, origin, name);
|
/* NULL checks for mod_name and origin done by _PyErr_SetImportErrorWithNameFrom */
|
||||||
Py_DECREF(errmsg);
|
_PyErr_SetImportErrorWithNameFrom(errmsg, mod_name, origin, name);
|
||||||
|
Py_DECREF(errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
Py_XDECREF(origin);
|
Py_XDECREF(origin);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue