diff --git a/hypothesis-python/RELEASE.rst b/hypothesis-python/RELEASE.rst new file mode 100644 index 0000000000..01c2236f3a --- /dev/null +++ b/hypothesis-python/RELEASE.rst @@ -0,0 +1,6 @@ +RELEASE_TYPE: minor + +This release improves Hypothesis' ability to resolve forward references in +type annotations. It fixes a bug that prevented +:func:`~hypothesis.strategies.builds` from being used with `pydantic models that +possess updated forward references `__. See :issue:`3519`. \ No newline at end of file diff --git a/hypothesis-python/src/hypothesis/internal/compat.py b/hypothesis-python/src/hypothesis/internal/compat.py index 2d6fa1d7ad..61b3e30464 100644 --- a/hypothesis-python/src/hypothesis/internal/compat.py +++ b/hypothesis-python/src/hypothesis/internal/compat.py @@ -111,8 +111,13 @@ def get_type_hints(thing): and is_a_type(p.annotation) and p.annotation is not p.empty ): + if isinstance(p.annotation, typing.ForwardRef) and not isinstance( + hints[p.name], typing.ForwardRef + ): + continue + if p.default is None: - hints[p.name] = typing.Optional[p.annotation] + hints[p.name] = typing.Optional[p.annotation] # type: ignore else: hints[p.name] = p.annotation except (AttributeError, TypeError, NameError): # pragma: no cover diff --git a/hypothesis-python/tests/cover/test_compat.py b/hypothesis-python/tests/cover/test_compat.py index 673b19e07a..19577fd038 100644 --- a/hypothesis-python/tests/cover/test_compat.py +++ b/hypothesis-python/tests/cover/test_compat.py @@ -9,7 +9,9 @@ # obtain one at https://mozilla.org/MPL/2.0/. import math -from inspect import Parameter, Signature +from dataclasses import dataclass +from inspect import Parameter, Signature, signature +from typing import ForwardRef import pytest @@ -45,3 +47,24 @@ class WeirdSig: def test_no_type_hints(): assert get_type_hints(WeirdSig) == {} + + +@dataclass +class Foo: + x: "Foo" + + +Foo.__signature__ = signature(Foo).replace( # type: ignore + parameters=[ + Parameter( + "x", + Parameter.POSITIONAL_OR_KEYWORD, + annotation=ForwardRef("Foo"), + ) + ] +) + + +def test_resolve_fwd_refs(): + # See: https://github.com/HypothesisWorks/hypothesis/issues/3519 + assert get_type_hints(Foo)["x"] is Foo