Skip to content

Commit 407d984

Browse files
neutrinocerosnicoddemusZac-HD
authored
Fix an edge case where ExceptionInfo._stringify_exception could crash pytest.raises (#11879)
Co-authored-by: Bruno Oliveira <[email protected]> Co-authored-by: Zac Hatfield-Dodds <[email protected]>
1 parent 21bec6c commit 407d984

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ Christopher Dignam
9393
Christopher Gilling
9494
Claire Cecil
9595
Claudio Madotto
96+
Clément M.T. Robert
9697
CrazyMerlyn
9798
Cristian Vera
9899
Cyrus Maden

changelog/11879.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix an edge case where ``ExceptionInfo._stringify_exception`` could crash :func:`pytest.raises`.

src/_pytest/_code/code.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -699,10 +699,21 @@ def getrepr(
699699
return fmt.repr_excinfo(self)
700700

701701
def _stringify_exception(self, exc: BaseException) -> str:
702+
try:
703+
notes = getattr(exc, "__notes__", [])
704+
except KeyError:
705+
# Workaround for https://github.com/python/cpython/issues/98778 on
706+
# Python <= 3.9, and some 3.10 and 3.11 patch versions.
707+
HTTPError = getattr(sys.modules.get("urllib.error", None), "HTTPError", ())
708+
if sys.version_info[:2] <= (3, 11) and isinstance(exc, HTTPError):
709+
notes = []
710+
else:
711+
raise
712+
702713
return "\n".join(
703714
[
704715
str(exc),
705-
*getattr(exc, "__notes__", []),
716+
*notes,
706717
]
707718
)
708719

testing/python/raises.py

+13
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,16 @@ class NotAnException:
302302
with pytest.raises(("hello", NotAnException)): # type: ignore[arg-type]
303303
pass # pragma: no cover
304304
assert "must be a BaseException type, not str" in str(excinfo.value)
305+
306+
def test_issue_11872(self) -> None:
307+
"""Regression test for #11872.
308+
309+
urllib.error.HTTPError on Python<=3.9 raises KeyError instead of
310+
AttributeError on invalid attribute access.
311+
312+
https://github.com/python/cpython/issues/98778
313+
"""
314+
from urllib.error import HTTPError
315+
316+
with pytest.raises(HTTPError, match="Not Found"):
317+
raise HTTPError(code=404, msg="Not Found", fp=None, hdrs=None, url="") # type: ignore [arg-type]

0 commit comments

Comments
 (0)