Skip to content

Commit

Permalink
Fixed explicit checks of PEP 604 unions against types.UnionType
Browse files Browse the repository at this point in the history
Fixes #467.
  • Loading branch information
agronholm committed Nov 3, 2024
1 parent 0a39830 commit b0b20c2
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 10 deletions.
2 changes: 2 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ This library adheres to
- Fixed checking of protocols on the class level (against ``type[SomeProtocol]``)
(`#498 <https://github.com/agronholm/typeguard/pull/498>`_)
- Fixed ``Self`` checks in instance/class methods that have positional-only arguments
- Fixed explicit checks of PEP 604 unions against ``types.UnionType``
(`#467 <https://github.com/agronholm/typeguard/pull/467>`_)

**4.4.0** (2024-10-27)

Expand Down
14 changes: 4 additions & 10 deletions src/typeguard/_checkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ def check_union(
)
finally:
del errors # avoid creating ref cycle

raise TypeCheckError(f"did not match any element in the union:\n{formatted_errors}")


Expand All @@ -431,6 +432,9 @@ def check_uniontype(
args: tuple[Any, ...],
memo: TypeCheckMemo,
) -> None:
if not args:
return check_instance(value, types.UnionType, (), memo)

errors: dict[str, TypeCheckError] = {}
try:
for type_ in args:
Expand Down Expand Up @@ -876,16 +880,6 @@ def check_paramspec(
pass # No-op for now


def check_instanceof(
value: Any,
origin_type: Any,
args: tuple[Any, ...],
memo: TypeCheckMemo,
) -> None:
if not isinstance(value, origin_type):
raise TypeCheckError(f"is not an instance of {qualified_name(origin_type)}")


def check_type_internal(
value: Any,
annotation: Any,
Expand Down
12 changes: 12 additions & 0 deletions tests/test_checkers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import collections.abc
import sys
import types
from contextlib import nullcontext
from functools import partial
from io import BytesIO, StringIO
Expand Down Expand Up @@ -882,6 +883,17 @@ def inner3():
inner3()
assert not leaked

@pytest.mark.skipif(sys.version_info < (3, 10), reason="UnionType requires 3.10")
def test_raw_uniontype_success(self):
check_type(str | int, types.UnionType)

@pytest.mark.skipif(sys.version_info < (3, 10), reason="UnionType requires 3.10")
def test_raw_uniontype_fail(self):
with pytest.raises(
TypeCheckError, match="class str is not an instance of types.UnionType"
):
check_type(str, types.UnionType)


class TestTypevar:
def test_bound(self):
Expand Down

0 comments on commit b0b20c2

Please sign in to comment.