Fix INTERNALERROR when accessing locals / globals with faulty `exec`
This commit is contained in:
parent
389e30283c
commit
96a17b1683
|
@ -0,0 +1 @@
|
||||||
|
Fix INTERNALERROR when accessing locals / globals with faulty ``exec``.
|
|
@ -246,10 +246,20 @@ class TracebackEntry:
|
||||||
|
|
||||||
Mostly for internal use.
|
Mostly for internal use.
|
||||||
"""
|
"""
|
||||||
f = self.frame
|
tbh = (
|
||||||
tbh = f.f_locals.get(
|
False
|
||||||
"__tracebackhide__", f.f_globals.get("__tracebackhide__", False)
|
|
||||||
) # type: Union[bool, Callable[[Optional[ExceptionInfo[BaseException]]], bool]]
|
) # type: Union[bool, Callable[[Optional[ExceptionInfo[BaseException]]], bool]]
|
||||||
|
for maybe_ns_dct in (self.frame.f_locals, self.frame.f_globals):
|
||||||
|
# in normal cases, f_locals and f_globals are dictionaries
|
||||||
|
# however via `exec(...)` / `eval(...)` they can be other types
|
||||||
|
# (even incorrect types!).
|
||||||
|
# as such, we suppress all exceptions while accessing __tracebackhide__
|
||||||
|
try:
|
||||||
|
tbh = maybe_ns_dct["__tracebackhide__"]
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
if tbh and callable(tbh):
|
if tbh and callable(tbh):
|
||||||
return tbh(None if self._excinfo is None else self._excinfo())
|
return tbh(None if self._excinfo is None else self._excinfo())
|
||||||
return tbh
|
return tbh
|
||||||
|
|
|
@ -1352,6 +1352,19 @@ raise ValueError()
|
||||||
)
|
)
|
||||||
assert out == expected_out
|
assert out == expected_out
|
||||||
|
|
||||||
|
def test_exec_type_error_filter(self, importasmod):
|
||||||
|
"""See #7742"""
|
||||||
|
mod = importasmod(
|
||||||
|
"""\
|
||||||
|
def f():
|
||||||
|
exec("a = 1", {}, [])
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
with pytest.raises(TypeError) as excinfo:
|
||||||
|
mod.f()
|
||||||
|
# previously crashed with `AttributeError: list has no attribute get`
|
||||||
|
excinfo.traceback.filter()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("style", ["short", "long"])
|
@pytest.mark.parametrize("style", ["short", "long"])
|
||||||
@pytest.mark.parametrize("encoding", [None, "utf8", "utf16"])
|
@pytest.mark.parametrize("encoding", [None, "utf8", "utf16"])
|
||||||
|
|
Loading…
Reference in New Issue