Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PEP 604 unions, types.UnionType #184

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Add explicit `__all__` configuration
- Add Python 3.10 and 3.11 support
- Support [PEP 604] unions through `types.UnionType`

[PEP 604]: https://peps.python.org/pep-0604/

### Fixed

Expand Down
10 changes: 9 additions & 1 deletion dacite/types.py
Expand Up @@ -63,7 +63,15 @@ def is_generic(type_: Type) -> bool:


def is_union(type_: Type) -> bool:
return is_generic(type_) and type_.__origin__ == Union
if is_generic(type_) and type_.__origin__ == Union:
return True

try:
from types import UnionType # type: ignore

return isinstance(type_, UnionType)
except ImportError:
return False


def is_literal(type_: Type) -> bool:
Expand Down
1 change: 1 addition & 0 deletions tests/common.py
Expand Up @@ -3,3 +3,4 @@
import pytest

literal_support = init_var_type_support = pytest.mark.skipif(sys.version_info < (3, 8), reason="requires Python 3.8")
pep_604_support = pytest.mark.skipif(sys.version_info < (3, 10), reason="requires Python 3.10")
17 changes: 16 additions & 1 deletion tests/test_types.py
Expand Up @@ -21,7 +21,7 @@
is_type_generic,
is_set,
)
from tests.common import literal_support, init_var_type_support
from tests.common import literal_support, init_var_type_support, pep_604_support


def test_is_union_with_union():
Expand All @@ -32,6 +32,11 @@ def test_is_union_with_non_union():
assert not is_union(int)


@pep_604_support
def test_is_union_with_pep_604_union():
assert is_union(int | float)


@literal_support
def test_is_literal_with_literal():
from typing import Literal
Expand Down Expand Up @@ -63,6 +68,16 @@ def test_is_optional_with_optional_of_union():
assert is_optional(Optional[Union[int, float]])


@pep_604_support
def test_is_optional_with_pep_604_union():
assert is_optional(int | float | None)


@pep_604_support
def test_is_optional_with_non_optional_pep_604_union():
assert not is_optional(int | float)


def test_extract_optional():
assert extract_optional(Optional[int]) == int

Expand Down