Skip to content

Commit 492e3e6

Browse files
authored
gh-129098: avoid using content of _pyrepl/__main__.py when reporting tracebacks (#130721)
1 parent 5d8e432 commit 492e3e6

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

Lib/_pyrepl/__main__.py

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Important: don't add things to this module, as they will end up in the REPL's
22
# default globals. Use _pyrepl.main instead.
33

4+
# Avoid caching this file by linecache and incorrectly report tracebacks.
5+
# See https://github.com/python/cpython/issues/129098.
6+
__spec__ = __loader__ = None
7+
48
if __name__ == "__main__":
59
from .main import interactive_console as __pyrepl_interactive_console
610
__pyrepl_interactive_console()

Lib/test/test_pyrepl/test_pyrepl.py

+27-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
from unittest import TestCase, skipUnless, skipIf
1212
from unittest.mock import patch
1313
from test.support import force_not_colorized, make_clean_env
14-
from test.support import SHORT_TIMEOUT
14+
from test.support import SHORT_TIMEOUT, STDLIB_DIR
1515
from test.support.import_helper import import_module
16-
from test.support.os_helper import unlink
16+
from test.support.os_helper import EnvironmentVarGuard, unlink
1717

1818
from .support import (
1919
FakeConsole,
@@ -1217,6 +1217,31 @@ def test_python_basic_repl(self):
12171217
self.assertNotIn("Exception", output)
12181218
self.assertNotIn("Traceback", output)
12191219

1220+
@force_not_colorized
1221+
def test_no_pyrepl_source_in_exc(self):
1222+
# Avoid using _pyrepl/__main__.py in traceback reports
1223+
# See https://github.com/python/cpython/issues/129098.
1224+
pyrepl_main_file = os.path.join(STDLIB_DIR, "_pyrepl", "__main__.py")
1225+
self.assertTrue(os.path.exists(pyrepl_main_file), pyrepl_main_file)
1226+
with open(pyrepl_main_file) as fp:
1227+
excluded_lines = fp.readlines()
1228+
excluded_lines = list(filter(None, map(str.strip, excluded_lines)))
1229+
1230+
for filename in ['?', 'unknown-filename', '<foo>', '<...>']:
1231+
self._test_no_pyrepl_source_in_exc(filename, excluded_lines)
1232+
1233+
def _test_no_pyrepl_source_in_exc(self, filename, excluded_lines):
1234+
with EnvironmentVarGuard() as env, self.subTest(filename=filename):
1235+
env.unset("PYTHON_BASIC_REPL")
1236+
commands = (f"eval(compile('spam', {filename!r}, 'eval'))\n"
1237+
f"exit()\n")
1238+
output, _ = self.run_repl(commands, env=env)
1239+
self.assertIn("Traceback (most recent call last)", output)
1240+
self.assertIn("NameError: name 'spam' is not defined", output)
1241+
for line in excluded_lines:
1242+
with self.subTest(line=line):
1243+
self.assertNotIn(line, output)
1244+
12201245
@force_not_colorized
12211246
def test_bad_sys_excepthook_doesnt_crash_pyrepl(self):
12221247
env = os.environ.copy()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix REPL traceback reporting when using :func:`compile` with an inexisting
2+
file. Patch by Bénédikt Tran.

0 commit comments

Comments
 (0)