diff --git a/hypothesis-python/RELEASE.rst b/hypothesis-python/RELEASE.rst new file mode 100644 index 00000000000..f7ada998869 --- /dev/null +++ b/hypothesis-python/RELEASE.rst @@ -0,0 +1,16 @@ +RELEASE_TYPE: minor + +This release removes support for Python 3.5.0 and 3.5.1, where the +:mod:`python:typing` module was quite immature (e.g. missing +:func:`~python:typing.overload` and :obj:`~python:typing.Type`). + +.. note:: + ``pip install hypothesis`` should continue to give you the latest compatible version. + If you have somehow ended up with Hypothesis 5.0 on Python 2, you need to update your + packaging stack to ``pip >= 9.0`` and ``setuptools >= 24.2`` - see `here for details + `__. + Then ``pip uninstall hypothesis && pip install hypothesis`` will get you back to + a compatible version. + +Note that Python 3.5 will reach its end-of-life in September 2020, +and new releases of Hypothesis may drop support somewhat earlier. diff --git a/hypothesis-python/setup.py b/hypothesis-python/setup.py index 42882372de4..12f40dbbb36 100644 --- a/hypothesis-python/setup.py +++ b/hypothesis-python/setup.py @@ -19,7 +19,7 @@ import setuptools -if sys.version_info[:2] < (3, 5): +if sys.version_info[:3] < (3, 5, 2): raise Exception( "This version of Python is too old to install new versions of Hypothesis. " "Update `pip` and `setuptools`, try again, and you will automatically " @@ -91,7 +91,7 @@ def local_file(name): zip_safe=False, extras_require=extras, install_requires=["attrs>=19.2.0", "sortedcontainers>=2.1.0,<3.0.0"], - python_requires=">=3.5", + python_requires=">=3.5.2", classifiers=[ "Development Status :: 5 - Production/Stable", "Framework :: Hypothesis", diff --git a/hypothesis-python/src/hypothesis/_error_if_old.py b/hypothesis-python/src/hypothesis/_error_if_old.py index 69ad669b312..1ade7eefc3e 100644 --- a/hypothesis-python/src/hypothesis/_error_if_old.py +++ b/hypothesis-python/src/hypothesis/_error_if_old.py @@ -18,11 +18,11 @@ from hypothesis.version import __version__ message = """ -Hypothesis {} requires Python 3.5 or later. +Hypothesis {} requires Python 3.5.2 or later. This can only happen if your packaging toolchain is older than python_requires. See https://packaging.python.org/guides/distributing-packages-using-setuptools/ """ -if sys.version_info < (3, 5): # pragma: no cover +if sys.version_info[:3] < (3, 5, 2): # pragma: no cover raise Exception(message.format(__version__)) diff --git a/hypothesis-python/src/hypothesis/extra/django/_fields.py b/hypothesis-python/src/hypothesis/extra/django/_fields.py index d2c5ef4ea63..5342afcda5e 100644 --- a/hypothesis-python/src/hypothesis/extra/django/_fields.py +++ b/hypothesis-python/src/hypothesis/extra/django/_fields.py @@ -17,7 +17,7 @@ import string from datetime import timedelta from decimal import Decimal -from typing import Any, Callable, Dict, TypeVar, Union +from typing import Any, Callable, Dict, Type, TypeVar, Union import django import django.db.models as dm @@ -35,12 +35,6 @@ from hypothesis.provisional import urls from hypothesis.strategies import emails -try: - # New in Python 3.5.2; so we only use the string form in annotations - from typing import Type -except ImportError: - pass - AnyField = Union[dm.Field, df.Field] F = TypeVar("F", bound=AnyField) @@ -216,7 +210,7 @@ def _for_form_boolean(field): def register_field_strategy( - field_type: "Type[AnyField]", strategy: st.SearchStrategy + field_type: Type[AnyField], strategy: st.SearchStrategy ) -> None: """Add an entry to the global field-to-strategy lookup used by :func:`~hypothesis.extra.django.from_field`. diff --git a/hypothesis-python/src/hypothesis/internal/compat.py b/hypothesis-python/src/hypothesis/internal/compat.py index 6c1530cb4fb..cfeef15f780 100644 --- a/hypothesis-python/src/hypothesis/internal/compat.py +++ b/hypothesis-python/src/hypothesis/internal/compat.py @@ -79,12 +79,7 @@ def qualname(f): ForwardRef = typing.ForwardRef # type: ignore except AttributeError: typing_root_type = (typing.TypingMeta, typing.TypeVar) # type: ignore - try: - typing_root_type += (typing._Union,) # type: ignore - except AttributeError: - # Under Python 3.5.0, we'll just give up... if users want strategies - # inferred from Union-typed attrs attributes they can try a newer Python. - pass + typing_root_type += (typing._Union,) # type: ignore ForwardRef = typing._ForwardRef # type: ignore diff --git a/hypothesis-python/src/hypothesis/strategies/_internal/core.py b/hypothesis-python/src/hypothesis/strategies/_internal/core.py index a70772b18ed..36a488a8a6d 100644 --- a/hypothesis-python/src/hypothesis/strategies/_internal/core.py +++ b/hypothesis-python/src/hypothesis/strategies/_internal/core.py @@ -39,8 +39,10 @@ Sequence, Set, Tuple, + Type, TypeVar, Union, + overload, ) from uuid import UUID @@ -124,15 +126,6 @@ from hypothesis.types import RandomWithSeed from hypothesis.utils.conventions import InferType, infer, not_set -try: - # New in Python 3.5.2; so we only use the string form in annotations - from typing import Type, overload -except ImportError: - - def overload(f): - return f - - K = TypeVar("K") V = TypeVar("V") UniqueBy = Union[Callable[[Ex], Hashable], Tuple[Callable[[Ex], Hashable], ...]] @@ -629,7 +622,7 @@ def sampled_from(elements: Sequence[T]) -> SearchStrategy[T]: @overload # noqa: F811 -def sampled_from(elements: "Type[enum.Enum]") -> SearchStrategy[Any]: +def sampled_from(elements: Type[enum.Enum]) -> SearchStrategy[Any]: # `SearchStrategy[Enum]` is unreliable due to metaclass issues. pass # pragma: no cover @@ -1247,7 +1240,7 @@ def inner(*args, **kwargs): @cacheable @_defer_from_type -def from_type(thing: "Type[Ex]") -> SearchStrategy[Ex]: +def from_type(thing: Type[Ex]) -> SearchStrategy[Ex]: """Looks up the appropriate search strategy for the given type. ``from_type`` is used internally to fill in missing arguments to @@ -2092,8 +2085,8 @@ def data() -> SearchStrategy[DataObject]: def register_type_strategy( - custom_type: "Type[Ex]", - strategy: Union[SearchStrategy[Ex], Callable[["Type[Ex]"], SearchStrategy[Ex]]], + custom_type: Type[Ex], + strategy: Union[SearchStrategy[Ex], Callable[[Type[Ex]], SearchStrategy[Ex]]], ) -> None: """Add an entry to the global type-to-strategy lookup.