8000 gh-82378 fix sys.tracebacklimit in pyrepl by cfbolz · Pull Request #123062 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-82378 fix sys.tracebacklimit in pyrepl #123062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

10 changes: 5 additions & 5 deletions Lib/_pyrepl/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,11 @@ def __init__(
super().__init__(locals=locals, filename=filename, local_exit=local_exit) # type: ignore[call-arg]
self.can_colorize = _colorize.can_colorize()

def showsyntaxerror(self, filename=None):
super().showsyntaxerror(colorize=self.can_colorize)

def showtraceback(self):
super().showtraceback(colorize=self.can_colorize)
def _showtraceback(self, typ, value, tb, colorize=False, limit=None):
import traceback
return super()._showtraceback(
typ, value, tb, colorize=self.can_colorize,
limit=traceback.BUILTIN_EXCEPTION_LIMIT)

def runsource(self, source, filename="<input>", symbol="single"):
try:
Expand Down
18 changes: 10 additions & 8 deletions Lib/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def runcode(self, code):
except:
self.showtraceback()

def showsyntaxerror(self, filename=None, **kwargs):
def showsyntaxerror(self, filename=None):
"""Display the syntax error that just occurred.

This doesn't display a stack trace because there isn't one.
Expand All @@ -106,7 +106,6 @@ def showsyntaxerror(self, filename=None, **kwargs):
The output is written by self.write(), below.

"""
colorize = kwargs.pop('colorize', False)
try:
typ, value, tb = sys.exc_info()
if filename and typ is SyntaxError:
Expand All @@ -119,32 +118,35 @@ def showsyntaxerror(self, filename=None, **kwargs):
else:
# Stuff in the right filename
value = SyntaxError(msg, (filename, lineno, offset, line))
self._showtraceback(typ, value, None, colorize)
self._showtraceback(typ, value, None)
finally:
typ = value = tb = None

def showtraceback(self, **kwargs):
def showtraceback(self):
"""Display the exception that just occurred.

We remove the first stack item because it is our own code.

The output is written by self.write(), below.

"""
colorize = kwargs.pop('colorize', False)
try:
typ, value, tb = sys.exc_info()
self._showtraceback(typ, value, tb.tb_next, colorize)
self._showtraceback(typ, value, tb.tb_next)
finally:
typ = value = tb = None

def _showtraceback(self, typ, value, tb, colorize):
def _showtraceback(self, typ, value, tb, colorize=False, limit=None):
# This method is being overwritten in
# _pyrepl.console.InteractiveColoredConsole to pass different values of
# colorize and limit
sys.last_type = typ
sys.last_traceback = tb
sys.last_exc = sys.last_value = value = value.with_traceback(tb)
if sys.excepthook is sys.__excepthook__:
lines = traceback.format_exception(typ, value, tb,
colorize=colorize)
colorize=colorize,
limit=limit)
self.write(''.join(lines))
else:
# If someone has set sys.excepthook, we let that take precedence
Expand Down
25 changes: 25 additions & 0 deletions Lib/test/test_pyrepl/test_pyrepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,31 @@ def test_not_wiping_history_file(self):
self.assertIn("spam", output)
self.assertNotEqual(pathlib.Path(hfile.name).stat().st_size, 0)

@force_not_colorized
def test_proper_tracebacklimit(self):
env = os.environ.copy()
commands = ("import sys\n"
"sys.tracebacklimit = 1\n"
"def x1(): 1/0\n\n"
"def x2(): x1()\n\n"
"def x3(): x2()\n\n"
"x3()\n"
"exit()\n")

env.pop("PYTHON_BASIC_REPL", None)
output, exit_code = self.run_repl(commands, env=env)
if "can\'t use pyrepl" in output:
self.skipTest("pyrepl not available")
self.assertIn("in x1", output)
self.assertNotIn("in x3", output)
self.assertNotIn("in <module>", output)

env["PYTHON_BASIC_REPL"] = "1"
output, exit_code = self.run_repl(commands, env=env)
self.assertIn("in x1", output)
self.assertNotIn("in x3", output)
self.assertNotIn("in <module>", output)

def run_repl(
self,
repl_input: str | list[str],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Make sure that the new :term:`REPL` interprets :data:`sys.tracebacklimit` in
the same way that the classic REPL did.
Loading
0