Goal
Either fix or remove backlash.tbtools.Frame.eval.
Done when: Frame.eval either works on all supported Python versions with a
test covering it, or is removed as dead code after confirming no external
caller depends on it.
Reproduction:
from backlash.tbtools import get_current_traceback
try:
raise ZeroDivisionError('x')
except Exception:
tb = get_current_traceback()
tb.frames[-1].eval('1+1')
Current behaviour, on every Python 3 version:
TypeError: can only concatenate str (not "bytes") to str
Cause: the method does code = UTF8_COOKIE + code.encode('utf-8'), where
UTF8_COOKIE is a str and code.encode(...) is bytes. The construct is a
leftover from the Python 2 era Werkzeug debugger this module was forked from,
where both operands were byte strings.
Note that the method has no caller inside backlash: the debugger evaluates
expressions through Frame.console (backlash.console.Console), not through
Frame.eval, which is why the breakage has gone unnoticed.
Why
The method is part of a public class and is broken on every supported
interpreter, so any external code calling it fails immediately. Because it is
unreachable from inside backlash, no test or CI run surfaces it, and it will
keep surviving refactors as apparently-live code.
Deciding fix-versus-remove also removes the last reason to keep UTF8_COOKIE
in tbtools.
References
backlash/tbtools.py (Frame.eval, UTF8_COOKIE)
backlash/console.py (Console.eval) is the code path the debugger actually uses
backlash/debugger.py (DebuggerCore.execute_command) shows the live call chain
Goal
Either fix or remove
backlash.tbtools.Frame.eval.Done when:
Frame.evaleither works on all supported Python versions with atest covering it, or is removed as dead code after confirming no external
caller depends on it.
Reproduction:
Current behaviour, on every Python 3 version:
Cause: the method does
code = UTF8_COOKIE + code.encode('utf-8'), whereUTF8_COOKIEis astrandcode.encode(...)isbytes. The construct is aleftover from the Python 2 era Werkzeug debugger this module was forked from,
where both operands were byte strings.
Note that the method has no caller inside backlash: the debugger evaluates
expressions through
Frame.console(backlash.console.Console), not throughFrame.eval, which is why the breakage has gone unnoticed.Why
The method is part of a public class and is broken on every supported
interpreter, so any external code calling it fails immediately. Because it is
unreachable from inside backlash, no test or CI run surfaces it, and it will
keep surviving refactors as apparently-live code.
Deciding fix-versus-remove also removes the last reason to keep
UTF8_COOKIEin
tbtools.References
backlash/tbtools.py(Frame.eval,UTF8_COOKIE)backlash/console.py(Console.eval) is the code path the debugger actually usesbacklash/debugger.py(DebuggerCore.execute_command) shows the live call chain