Repository: HypothesisWorks/hypothesis

Issue:
hypothesis 5.4.0 broken on python3.5.2 on Linux
**hypothesis** version in my virtualenv,
```
$ pip freeze | grep hypo
hypothesis==5.4.0
$ pip freeze | grep pytest
pytest==5.3.5
$ uname -a
Linux erdos 4.15.0-72-generic #81~16.04.1-Ubuntu SMP Tue Nov 26 16:34:21 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
```

**Python** version,
```
$ python --version
Python 3.5.2
```

**repro**,
```
$ pytest --version
Traceback (most recent call last):
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/hypothesis/internal/compat.py", line 78, in <module>
    typing_root_type = (typing._Final, typing._GenericAlias)  # type: ignore
AttributeError: module 'typing' has no attribute '_Final'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/guihao/nightly_build/guicreate/deps/env/bin/pytest", line 8, in <module>
    sys.exit(main())
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/config/__init__.py", line 73, in main
    config = _prepareconfig(args, plugins)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/config/__init__.py", line 224, in _prepareconfig
    pluginmanager=pluginmanager, args=args
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/pluggy/manager.py", line 87, in <lambda>
    firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/pluggy/callers.py", line 203, in _multicall
    gen.send(outcome)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/helpconfig.py", line 89, in pytest_cmdline_parse
    config = outcome.get_result()
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/config/__init__.py", line 794, in pytest_cmdline_parse
    self.parse(args)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/config/__init__.py", line 1000, in parse
    self._preparse(args, addopts=addopts)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/config/__init__.py", line 948, in _preparse
    self.pluginmanager.load_setuptools_entrypoints("pytest11")
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/pluggy/manager.py", line 299, in load_setuptools_entrypoints
    plugin = ep.load()
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/importlib_metadata/__init__.py", line 94, in load
    module = import_module(match.group('module'))
  File "/home/guihao/nightly_build/guicreate/deps/env/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 944, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 944, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 143, in exec_module
    exec(co, module.__dict__)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/hypothesis/__init__.py", line 24, in <module>
    from hypothesis._settings import HealthCheck, Phase, Verbosity, settings
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 143, in exec_module
    exec(co, module.__dict__)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/hypothesis/_settings.py", line 37, in <module>
    from hypothesis.internal.reflection import get_pretty_function_description
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 143, in exec_module
    exec(co, module.__dict__)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/hypothesis/internal/reflection.py", line 29, in <module>
    from hypothesis.internal.compat import (
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 143, in exec_module
    exec(co, module.__dict__)
  File "/home/guihao/nightly_build/guicreate/deps/env/local/lib/python3.5/site-packages/hypothesis/internal/compat.py", line 81, in <module>
    typing_root_type = (typing.TypingMeta, typing.TypeVar, typing._Union)  # type: ignore
AttributeError: module 'typing' has no attribute '_Union'
```


Discussion:
My entire `pip freeze`
```
absl-py==0.9.0
aspy.yaml==1.3.0
astor==0.8.1
atomicwrites==1.3.0
attrs==19.3.0
backports.weakref==1.0.post1
cachetools==3.1.1
certifi==2019.11.28
cffi==1.13.2
cfgv==2.0.1
chardet==3.0.4
comtypes==1.1.7
configparser==4.0.2
contextlib2==0.6.0.post1
coremltools==3.1
cryptography==2.8
Cython==0.29.10
decorator==4.4.0
enum34==1.1.6
funcsigs==1.0.2
functools32==3.2.3.post2
future==0.17.1
futures==3.3.0
gast==0.2.2
google-auth==1.11.0
google-auth-oauthlib==0.4.1
google-pasta==0.1.8
grpcio==1.26.0
h5py==2.10.0
hypothesis==4.24.3
identify==1.4.11
idna==2.8
importlib-metadata==1.5.0
importlib-resources==1.0.2
ipaddress==1.0.23
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.0
llvmlite==0.31.0
Markdown==3.1.1
mock==3.0.5
more-itertools==5.0.0
ndg-httpsclient==0.5.1
nodeenv==1.3.4
numba==0.47.0
numpy==1.16.4
oauthlib==3.1.0
opt-einsum==2.3.2
packaging==20.1
pandas==0.24.2
pathlib2==2.3.5
patsy==0.5.1
Pillow==6.2.0
pluggy==0.13.1
pre-commit==1.21.0
prettytable==0.7.2
protobuf==3.11.2
py==1.8.1
pyasn1==0.4.5
pyasn1-modules==0.2.8
pycparser==2.19
pyOpenSSL==19.0.0
pyparsing==2.4.6
pytest==4.6.3
python-dateutil==2.8.1
pytz==2019.1
PyYAML==5.3
requests==2.22.0
requests-oauthlib==1.3.0
resampy==0.2.1
rsa==4.0
scandir==1.10.0
scikit-learn==0.20.3
scipy==1.2.1
singledispatch==3.4.0.3
six==1.12.0
statsmodels==0.9.0
tensorboard==2.0.2
tensorflow==2.0.0
tensorflow-estimator==2.0.1
termcolor==1.1.0
toml==0.10.0
typing==3.7.4.1
UISoup==2.5.7
urllib3==1.25.8
virtualenv==16.7.9
wcwidth==0.1.8
Werkzeug==0.16.1
wrapt==1.11.2
zipp==1.1.0
```

is `typing==3.7.4.1` accountable for this?
https://github.com/HypothesisWorks/hypothesis/blob/b942262440a7ff22379ff3169b3260bbde66f7af/hypothesis-python/src/hypothesis/internal/compat.py#L75-L82

I think we just need a another try-except block, so it reads:

```python
typing_root_type = (typing.TypingMeta, typing.TypeVar)  # type: ignore
try:
    typing_root_type += (typing._Union,)  # type: ignore
except AttributeError:
    pass
```

Ugly but hopefully effective...  and we should add a Travis job for Python 3.5.2 at the same time.
@guihao-liang if you're interested in making the patch I'd be happy to review it today :slightly_smiling_face: 
Thanks for your prompt reply! Do you have any suggestions to add the unit test for it? Besides that, If I use version `4.57.1`, it won't crash.
What about version `5.3.1`?  I wouldn't bother with a unit test for this; we only support the most recent patch version of each minor version (but are happy to accept fixes otherwise).
@Zac-HD, thanks for the prompt reply! If no unit test is needed, please patch it since you already post the answer! 

for `5.3.1`, I got a different error,

```
Traceback (most recent call last):
  File "/home/guihao/guicreate/deps/env/bin/pytest", line 8, in <module>
    sys.exit(main())
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/config/__init__.py", line 73, in main
    config = _prepareconfig(args, plugins)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/config/__init__.py", line 224, in _prepareconfig
    pluginmanager=pluginmanager, args=args
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/pluggy/manager.py", line 87, in <lambda>
    firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/pluggy/callers.py", line 203, in _multicall
    gen.send(outcome)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/helpconfig.py", line 89, in pytest_cmdline_parse
    config = outcome.get_result()
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/config/__init__.py", line 794, in pytest_cmdline_parse
    self.parse(args)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/config/__init__.py", line 1000, in parse
    self._preparse(args, addopts=addopts)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/config/__init__.py", line 948, in _preparse
    self.pluginmanager.load_setuptools_entrypoints("pytest11")
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/pluggy/manager.py", line 299, in load_setuptools_entrypoints
    plugin = ep.load()
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/importlib_metadata/__init__.py", line 94, in load
    module = import_module(match.group('module'))
  File "/home/guihao/guicreate/deps/env/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 944, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 944, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 143, in exec_module
    exec(co, module.__dict__)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/hypothesis/__init__.py", line 26, in <module>
    from hypothesis.core import example, find, given, reproduce_failure, seed
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 143, in exec_module
    exec(co, module.__dict__)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/hypothesis/core.py", line 35, in <module>
    import hypothesis.strategies as st
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 143, in exec_module
    exec(co, module.__dict__)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/hypothesis/strategies/__init__.py", line 17, in <module>
    from hypothesis.strategies._internal.core import (
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 143, in exec_module
    exec(co, module.__dict__)
  File "/home/guihao/guicreate/deps/env/lib/python3.5/site-packages/hypothesis/strategies/_internal/core.py", line 2182, in <module>
    ) -> SearchStrategy[Callable[..., Any]]:
  File "/usr/lib/python3.5/typing.py", line 1025, in __getitem__
    tvars = _type_vars(params)
  File "/usr/lib/python3.5/typing.py", line 284, in _type_vars
    _get_type_vars(types, tvars)
  File "/usr/lib/python3.5/typing.py", line 279, in _get_type_vars
    t._get_type_vars(tvars)
  File "/usr/lib/python3.5/typing.py", line 786, in _get_type_vars
    _get_type_vars(self.__args__, tvars)
  File "/usr/lib/python3.5/typing.py", line 277, in _get_type_vars
    for t in types:
TypeError: 'ellipsis' object is not iterable
```
For clarity, I'll [link to our Python version policy](https://hypothesis.readthedocs.io/en/latest/supported.html#python-versions): "Hypothesis does not officially support anything except the latest patch release of any version of Python it supports".

So I'm happy to accept a patch for this if anyone wants to write one, and so long as our existing tests keep passing it doesn't need further justification.  However it's a very low priority for me to write, and we plan to drop all versions of Python 3.5 in the next few months regardless.
Okay, let me do it.
> @Zac-HD, thanks for the prompt reply! If no unit test is needed, please patch it since you already post the answer!
> 
> for `5.3.1`, I got a different error,
> 
> ```
> Traceback (most recent call last):
>   File "/home/guihao/guicreate/deps/env/bin/pytest", line 8, in <module>
>     sys.exit(main())
>   ...
>     ) -> SearchStrategy[Callable[..., Any]]:
>   File "/usr/lib/python3.5/typing.py", line 1025, in __getitem__
>     tvars = _type_vars(params)
>   File "/usr/lib/python3.5/typing.py", line 284, in _type_vars
>     _get_type_vars(types, tvars)
>   File "/usr/lib/python3.5/typing.py", line 279, in _get_type_vars
>     t._get_type_vars(tvars)
>   File "/usr/lib/python3.5/typing.py", line 786, in _get_type_vars
>     _get_type_vars(self.__args__, tvars)
>   File "/usr/lib/python3.5/typing.py", line 277, in _get_type_vars
>     for t in types:
> TypeError: 'ellipsis' object is not iterable
> ```

A known issue in 3.5.2. fixed by https://github.com/python/typing/issues/259

Resolving patch:
diff --git a/hypothesis-python/src/hypothesis/internal/compat.py b/hypothesis-python/src/hypothesis/internal/compat.py
--- a/hypothesis-python/src/hypothesis/internal/compat.py
+++ b/hypothesis-python/src/hypothesis/internal/compat.py
@@ -78,7 +78,11 @@ def qualname(f):
     typing_root_type = (typing._Final, typing._GenericAlias)  # type: ignore
     ForwardRef = typing.ForwardRef  # type: ignore
 except AttributeError:
-    typing_root_type = (typing.TypingMeta, typing.TypeVar, typing._Union)  # type: ignore
+    typing_root_type = (typing.TypingMeta, typing.TypeVar)  # type: ignore
+    try:
+        typing_root_type += (typing._Union,)  # type: ignore
+    except AttributeError:
+        pass
     ForwardRef = typing._ForwardRef  # type: ignore
 
 


Test patch: