From 09f396f772504d2a30e721188ae27acd57f0140a Mon Sep 17 00:00:00 2001 From: Zac-HD Date: Sun, 28 Nov 2021 16:32:27 +1100 Subject: [PATCH] Handle unions of builtin generics --- hypothesis-python/RELEASE.rst | 5 +++++ .../src/hypothesis/strategies/_internal/types.py | 1 + hypothesis-python/tests/cover/test_lookup_py39.py | 8 ++++++++ 3 files changed, 14 insertions(+) create mode 100644 hypothesis-python/RELEASE.rst diff --git a/hypothesis-python/RELEASE.rst b/hypothesis-python/RELEASE.rst new file mode 100644 index 0000000000..bac2040a69 --- /dev/null +++ b/hypothesis-python/RELEASE.rst @@ -0,0 +1,5 @@ +RELEASE_TYPE: patch + +This release fixes :issue:`3080`, where :func:`~hypothesis.strategies.from_type` +failed on unions containing :pep:`585` builtin generic types (like ``list[int]``) +in Python 3.9 and later. diff --git a/hypothesis-python/src/hypothesis/strategies/_internal/types.py b/hypothesis-python/src/hypothesis/strategies/_internal/types.py index 2db4fb2e5f..e6496dcd9d 100644 --- a/hypothesis-python/src/hypothesis/strategies/_internal/types.py +++ b/hypothesis-python/src/hypothesis/strategies/_internal/types.py @@ -81,6 +81,7 @@ def type_sorting_key(t): raise InvalidArgument(f"thing={t} must be a type") # pragma: no cover if t is None or t is type(None): # noqa: E721 return (-1, repr(t)) + t = getattr(t, "__origin__", t) if not isinstance(t, type): # pragma: no cover # Some generics in the typing module are not actually types in 3.7 return (2, repr(t)) diff --git a/hypothesis-python/tests/cover/test_lookup_py39.py b/hypothesis-python/tests/cover/test_lookup_py39.py index 8811c00dcc..1a82cb24f2 100644 --- a/hypothesis-python/tests/cover/test_lookup_py39.py +++ b/hypothesis-python/tests/cover/test_lookup_py39.py @@ -20,6 +20,7 @@ from hypothesis import given, strategies as st from hypothesis.errors import InvalidArgument +from tests.common.debug import find_any @pytest.mark.parametrize( @@ -85,3 +86,10 @@ def test_string_forward_ref_message(): s = st.builds(User) with pytest.raises(InvalidArgument, match="`from __future__ import annotations`"): s.example() + + +def test_issue_3080(): + # Check for https://github.com/HypothesisWorks/hypothesis/issues/3080 + s = st.from_type(typing.Union[list[int], int]) + find_any(s, lambda x: isinstance(x, int)) + find_any(s, lambda x: isinstance(x, list))