Skip to content

Commit 634cde9

Browse files
authored
Merge pull request #7745 from asottile/exec_globals_type_problem
Fix INTERNALERROR when accessing locals / globals with faulty `exec`
2 parents ec58ae5 + 96a17b1 commit 634cde9

File tree

3 files changed

+27
-3
lines changed

3 files changed

+27
-3
lines changed

changelog/7742.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix INTERNALERROR when accessing locals / globals with faulty ``exec``.

src/_pytest/_code/code.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,20 @@ def ishidden(self) -> bool:
246246
247247
Mostly for internal use.
248248
"""
249-
f = self.frame
250-
tbh = f.f_locals.get(
251-
"__tracebackhide__", f.f_globals.get("__tracebackhide__", False)
249+
tbh = (
250+
False
252251
) # type: Union[bool, Callable[[Optional[ExceptionInfo[BaseException]]], bool]]
252+
for maybe_ns_dct in (self.frame.f_locals, self.frame.f_globals):
253+
# in normal cases, f_locals and f_globals are dictionaries
254+
# however via `exec(...)` / `eval(...)` they can be other types
255+
# (even incorrect types!).
256+
# as such, we suppress all exceptions while accessing __tracebackhide__
257+
try:
258+
tbh = maybe_ns_dct["__tracebackhide__"]
259+
except Exception:
260+
pass
261+
else:
262+
break
253263
if tbh and callable(tbh):
254264
return tbh(None if self._excinfo is None else self._excinfo())
255265
return tbh

testing/code/test_excinfo.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,19 @@ def unreraise():
13521352
)
13531353
assert out == expected_out
13541354

1355+
def test_exec_type_error_filter(self, importasmod):
1356+
"""See #7742"""
1357+
mod = importasmod(
1358+
"""\
1359+
def f():
1360+
exec("a = 1", {}, [])
1361+
"""
1362+
)
1363+
with pytest.raises(TypeError) as excinfo:
1364+
mod.f()
1365+
# previously crashed with `AttributeError: list has no attribute get`
1366+
excinfo.traceback.filter()
1367+
13551368

13561369
@pytest.mark.parametrize("style", ["short", "long"])
13571370
@pytest.mark.parametrize("encoding", [None, "utf8", "utf16"])

0 commit comments

Comments
 (0)