diff --git a/hypothesis-python/RELEASE.rst b/hypothesis-python/RELEASE.rst new file mode 100644 index 0000000000..f77dec91ca --- /dev/null +++ b/hypothesis-python/RELEASE.rst @@ -0,0 +1,6 @@ +RELEASE_TYPE: patch + +This patch fixes :func:`~hypothesis.strategies.from_type` and +:func:`~hypothesis.strategies.register_type_strategy` for +:obj:`python:typing.NewType` on Python 3.10, which changed the +underlying implementation (see :bpo:`44353` for details). diff --git a/hypothesis-python/src/hypothesis/_settings.py b/hypothesis-python/src/hypothesis/_settings.py index 8bf291613d..850fceba3c 100644 --- a/hypothesis-python/src/hypothesis/_settings.py +++ b/hypothesis-python/src/hypothesis/_settings.py @@ -461,8 +461,14 @@ def all(cls) -> List["HealthCheck"]: return list(HealthCheck) data_too_large = 1 - """Check for when the typical size of the examples you are generating - exceeds the maximum allowed size too often.""" + """Checks if too many examples are aborted for being too large. + + This is measured by the number of random choices that Hypothesis makes + in order to generate something, not the size of the generated object. + For example, choosing a 100MB object from a predefined list would take + only a few bits, while generating 10KB of JSON from scratch might trigger + this health check. + """ filter_too_much = 2 """Check for when the test is filtering out too many examples, either diff --git a/hypothesis-python/src/hypothesis/strategies/_internal/core.py b/hypothesis-python/src/hypothesis/strategies/_internal/core.py index ca360bfe07..97499929dd 100644 --- a/hypothesis-python/src/hypothesis/strategies/_internal/core.py +++ b/hypothesis-python/src/hypothesis/strategies/_internal/core.py @@ -1711,7 +1711,7 @@ def register_type_strategy( from hypothesis.strategies._internal import types if not types.is_a_type(custom_type): - raise InvalidArgument("custom_type=%r must be a type") + raise InvalidArgument(f"custom_type={custom_type!r} must be a type") elif not (isinstance(strategy, SearchStrategy) or callable(strategy)): raise InvalidArgument( "strategy=%r must be a SearchStrategy, or a function that takes " diff --git a/hypothesis-python/src/hypothesis/strategies/_internal/types.py b/hypothesis-python/src/hypothesis/strategies/_internal/types.py index 8d11fc56a4..fb4d596771 100644 --- a/hypothesis-python/src/hypothesis/strategies/_internal/types.py +++ b/hypothesis-python/src/hypothesis/strategies/_internal/types.py @@ -98,13 +98,17 @@ def try_issubclass(thing, superclass): def is_a_new_type(thing): - # At runtime, `typing.NewType` returns an identity function rather - # than an actual type, but we can check whether that thing matches. - return ( - hasattr(thing, "__supertype__") - and getattr(thing, "__module__", None) in ("typing", "typing_extensions") - and inspect.isfunction(thing) - ) + if sys.version_info[:2] < (3, 10): + # At runtime, `typing.NewType` returns an identity function rather + # than an actual type, but we can check whether that thing matches. + return ( + hasattr(thing, "__supertype__") + and getattr(thing, "__module__", None) in ("typing", "typing_extensions") + and inspect.isfunction(thing) + ) + # In 3.10 and later, NewType is actually a class - which simplifies things. + # See https://bugs.python.org/issue44353 for links to the various patches. + return isinstance(thing, typing.NewType) # pragma: no cover # on 3.8, anyway def is_a_type(thing): diff --git a/requirements/coverage.txt b/requirements/coverage.txt index abf0a90ea6..7304293bb0 100644 --- a/requirements/coverage.txt +++ b/requirements/coverage.txt @@ -10,7 +10,7 @@ coverage==5.5 # via -r requirements/coverage.in lark-parser==0.11.3 # via -r requirements/coverage.in -numpy==1.21.0 +numpy==1.21.1 # via # -r requirements/coverage.in # pandas diff --git a/requirements/tools.txt b/requirements/tools.txt index 4477338d00..3d1ebb20ea 100644 --- a/requirements/tools.txt +++ b/requirements/tools.txt @@ -155,11 +155,11 @@ packaging==21.0 # tox parso==0.8.2 # via jedi -pathspec==0.8.1 +pathspec==0.9.0 # via black pbr==5.6.0 # via stevedore -pep517==0.10.0 +pep517==0.11.0 # via pip-tools pexpect==4.8.0 # via ipython @@ -215,7 +215,7 @@ pytz==2021.1 # via # babel # django -pyupgrade==2.21.2 +pyupgrade==2.22.0 # via shed pyyaml==5.4.1 # via @@ -290,11 +290,12 @@ toml==0.10.2 # via # -r requirements/tools.in # mypy - # pep517 # pytest # tox -tomli==1.0.4 - # via black +tomli==1.1.0 + # via + # black + # pep517 tox==3.24.0 # via -r requirements/tools.in tqdm==4.61.2 @@ -303,7 +304,7 @@ traitlets==4.3.3 # via # -r requirements/tools.in # ipython -twine==3.4.1 +twine==3.4.2 # via -r requirements/tools.in types-click==7.1.2 # via -r requirements/tools.in