Skip to content

Commit

Permalink
changelog and fix
Browse files Browse the repository at this point in the history
  • Loading branch information
hauntsaninja committed Jan 15, 2024
1 parent cf38460 commit 4802b3a
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
5 changes: 5 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Version history
This library adheres to
`Semantic Versioning 2.0 <https://semver.org/#semantic-versioning-200>`_.

**Unreleased**

- Avoid creating reference cycles when type checking unions
(`#408 <https://github.com/agronholm/typeguard/pull/408>`_)

**4.1.5** (2023-09-11)

- Fixed ``Callable`` erroneously rejecting a callable that has the requested amount of
Expand Down
22 changes: 12 additions & 10 deletions src/typeguard/_checkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,17 +395,19 @@ def check_union(
memo: TypeCheckMemo,
) -> None:
errors: dict[str, TypeCheckError] = {}
for type_ in args:
try:
check_type_internal(value, type_, memo)
return
except TypeCheckError as exc:
errors[get_type_name(type_)] = exc
try:
for type_ in args:
try:
check_type_internal(value, type_, memo)
return
except TypeCheckError as exc:
errors[get_type_name(type_)] = exc

formatted_errors = indent(
"\n".join(f"{key}: {error}" for key, error in errors.items()), " "
)
del errors # avoid creating ref cycle
formatted_errors = indent(
"\n".join(f"{key}: {error}" for key, error in errors.items()), " "
)
finally:
del errors # avoid creating ref cycle
raise TypeCheckError(f"did not match any element in the union:\n{formatted_errors}")


Expand Down
13 changes: 11 additions & 2 deletions tests/test_checkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -780,12 +780,21 @@ def __del__(self):
nonlocal leaked
leaked = False

def inner():
def inner1():
leak = Leak() # noqa: F841
check_type(b"asdf", Union[str, bytes])

inner1()
assert not leaked

leaked = True

def inner2():
leak = Leak() # noqa: F841
with pytest.raises(TypeCheckError, match="any element in the union:"):
check_type(1, Union[str, bytes])

inner()
inner2()
assert not leaked


Expand Down

0 comments on commit 4802b3a

Please sign in to comment.