Fix an edge case where ExceptionInfo._stringify_exception could crash pytest.raises (#11879)

Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
Co-authored-by: Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
This commit is contained in:
Clément Robert 2024-01-30 16:20:30 +01:00 committed by GitHub
parent 21bec6cfbe
commit 407d984142
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 1 deletions

View File

@ -93,6 +93,7 @@ Christopher Dignam
Christopher Gilling
Claire Cecil
Claudio Madotto
Clément M.T. Robert
CrazyMerlyn
Cristian Vera
Cyrus Maden

View File

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

View File

@ -699,10 +699,21 @@ class ExceptionInfo(Generic[E]):
return fmt.repr_excinfo(self)
def _stringify_exception(self, exc: BaseException) -> str:
try:
notes = getattr(exc, "__notes__", [])
except KeyError:
# Workaround for https://github.com/python/cpython/issues/98778 on
# Python <= 3.9, and some 3.10 and 3.11 patch versions.
HTTPError = getattr(sys.modules.get("urllib.error", None), "HTTPError", ())
if sys.version_info[:2] <= (3, 11) and isinstance(exc, HTTPError):
notes = []
else:
raise
return "\n".join(
[
str(exc),
*getattr(exc, "__notes__", []),
*notes,
]
)

View File

@ -302,3 +302,16 @@ class TestRaises:
with pytest.raises(("hello", NotAnException)): # type: ignore[arg-type]
pass # pragma: no cover
assert "must be a BaseException type, not str" in str(excinfo.value)
def test_issue_11872(self) -> None:
"""Regression test for #11872.
urllib.error.HTTPError on Python<=3.9 raises KeyError instead of
AttributeError on invalid attribute access.
https://github.com/python/cpython/issues/98778
"""
from urllib.error import HTTPError
with pytest.raises(HTTPError, match="Not Found"):
raise HTTPError(code=404, msg="Not Found", fp=None, hdrs=None, url="") # type: ignore [arg-type]