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 generic types in signature inspection #2640

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
8 changes: 8 additions & 0 deletions hypothesis-python/RELEASE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
RELEASE_TYPE: patch

This patch improves :func:`~hypothesis.strategies.builds` and
:func:`~hypothesis.strategies.from_type` support for explicitly defined ``__signature__``
attributes, from :ref:`version 5.8.3 <v5.8.3>`, to support generic types from the
:mod:`python:typing` module.

Thanks to Rónán Carrigan for identifying and fixing this problem!
4 changes: 3 additions & 1 deletion hypothesis-python/src/hypothesis/internal/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,14 @@ def get_type_hints(thing):
# comprehensive type information from get_type_hints
# See https://github.com/HypothesisWorks/hypothesis/pull/2580
# for more details.
from hypothesis.strategies._internal.types import is_a_type

spec = inspect.getfullargspec(thing)
hints.update(
{
k: v
for k, v in spec.annotations.items()
if k in (spec.args + spec.kwonlyargs) and isinstance(v, type)
if k in (spec.args + spec.kwonlyargs) and is_a_type(v)
}
)
except (AttributeError, TypeError, NameError):
Expand Down
27 changes: 24 additions & 3 deletions hypothesis-python/tests/nocover/test_build_signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# END HEADER

from inspect import signature
from typing import get_type_hints
from typing import List, get_type_hints

from hypothesis import given, strategies as st

Expand Down Expand Up @@ -53,7 +53,9 @@ def use_annotations(
pass


def use_signature(self, testA: int, testB: str = None, *, testX: float, testY: str):
def use_signature(
self, testA: int, testB: str = None, *, testX: float, testY: List[str]
):
pass


Expand All @@ -66,9 +68,28 @@ def __init__(self, **kwargs):
assert set(kwargs) == {"testA", "testX", "testY"}
assert isinstance(kwargs["testA"], int)
assert isinstance(kwargs["testX"], float)
assert isinstance(kwargs["testY"], str)
assert isinstance(kwargs["testY"], list)
assert all(isinstance(elem, str) for elem in kwargs["testY"])


@given(st.builds(ModelWithAlias))
def test_build_using_different_signature_and_annotations(val):
assert isinstance(val, ModelWithAlias)


def use_bad_signature(self, testA: 1, *, testX: float):
pass


class ModelWithBadAliasSignature:
__annotations__ = get_type_hints(use_annotations)
__signature__ = signature(use_bad_signature)

def __init__(self, **kwargs):
assert set(kwargs) == {"testX"}
assert isinstance(kwargs["testX"], float)

rcarriga marked this conversation as resolved.
Show resolved Hide resolved

@given(st.builds(ModelWithBadAliasSignature))
def test_build_with_non_types_in_signature(val):
assert isinstance(val, ModelWithBadAliasSignature)