| old" in y
def test_debug_help(self):
old = sys.stdout
sys.stdout = HTMLStringO()
try:
helper([1, 2, 3])
x = sys.stdout.reset()
finally:
sys.stdout = old
assert "Help on list object" in x
assert "__delitem__" in x
def test_exc_divider_found_on_chained_exception(self):
@Request.application
def app(request):
def do_something():
raise ValueError("inner")
try:
do_something()
except ValueError:
raise KeyError("outer")
debugged = DebuggedApplication(app)
client = Client(debugged)
response = client.get("/")
data = response.get_data(as_text=True)
assert 'raise ValueError("inner")' in data
assert ' ' in data
assert 'raise KeyError("outer")' in data
class TestTraceback:
def test_log(self):
try:
1 / 0
except ZeroDivisionError:
traceback = Traceback(*sys.exc_info())
buffer_ = io.StringIO()
traceback.log(buffer_)
assert buffer_.getvalue().strip() == traceback.plaintext.strip()
def test_sourcelines_encoding(self):
source = (
"# -*- coding: latin1 -*-\n\n"
"def foo():\n"
' """höhö"""\n'
" 1 / 0\n"
"foo()"
).encode("latin1")
code = compile(source, filename="lol.py", mode="exec")
try:
eval(code)
except ZeroDivisionError:
traceback = Traceback(*sys.exc_info())
frames = traceback.frames
assert len(frames) == 3
assert frames[1].filename == "lol.py"
assert frames[2].filename == "lol.py"
class Loader:
def get_source(self, module):
return source
frames[1].loader = frames[2].loader = Loader()
assert frames[1].sourcelines == frames[2].sourcelines
assert [line.code for line in frames[1].get_annotated_lines()] == [
line.code for line in frames[2].get_annotated_lines()
]
assert "höhö" in frames[1].sourcelines[3]
def test_filename_encoding(self, tmpdir, monkeypatch):
moduledir = tmpdir.mkdir("föö")
moduledir.join("bar.py").write("def foo():\n 1/0\n")
monkeypatch.syspath_prepend(str(moduledir))
import bar
try:
bar.foo()
except ZeroDivisionError:
traceback = Traceback(*sys.exc_info())
assert "föö" in "\n".join(frame.render() for frame in traceback.frames)
def test_get_machine_id():
rv = get_machine_id()
assert isinstance(rv, bytes)
@pytest.mark.parametrize("crash", (True, False))
def test_basic(dev_server, crash):
c = dev_server(use_debugger=True)
r = c.request("/crash" if crash else "")
assert r.status == (500 if crash else 200)
if crash:
assert b"The debugger caught an exception in your WSGI application" in r.data
else:
assert r.json["PATH_INFO"] == "/"
def test_console_closure_variables(monkeypatch):
# restore the original display hook
monkeypatch.setattr(sys, "displayhook", console._displayhook)
c = console.Console()
c.eval("y = 5")
c.eval("x = lambda: y")
ret = c.eval("x()")
assert ret == ">>> x()\n5\n"
@pytest.mark.timeout(2)
def test_chained_exception_cycle():
try:
try:
raise ValueError()
except ValueError:
raise TypeError()
except TypeError as e:
# create a cycle and make it available outside the except block
e.__context__.__context__ = error = e
# if cycles aren't broken, this will time out
tb = Traceback(TypeError, error, error.__traceback__)
assert len(tb.groups) == 2
def test_non_hashable_exception():
class MutableException(ValueError):
__hash__ = None
try:
raise MutableException()
except MutableException:
# previously crashed: `TypeError: unhashable type 'MutableException'`
Traceback(*sys.exc_info())
|