Repository: HypothesisWorks/hypothesis

Issue:
AttributeError: module 'typing' has no attribute '_Final' (or '_Union')
Traceback (most recent call last):
  File "/tmpfs/bazel_tests_virtualenv/lib/python3.5/site-packages/hypothesis/internal/compat.py", line 304, 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 "/tmpfs/tmp/bazel/sandbox/linux-sandbox/725/execroot/tensorflow_probability/bazel-out/k8-opt/bin/tensorflow_probability/python/bijectors/bijector_properties_test_eager.runfiles/tensorflow_probability/tensorflow_probability/python/bijectors/bijector_properties_test.py", line 23, in <module>
    import hypothesis as hp
  File "/tmpfs/bazel_tests_virtualenv/lib/python3.5/site-packages/hypothesis/__init__.py", line 27, in <module>
    from hypothesis._settings import (
  File "/tmpfs/bazel_tests_virtualenv/lib/python3.5/site-packages/hypothesis/_settings.py", line 40, in <module>
    from hypothesis.internal.compat import integer_types, quiet_raise, string_types
  File "/tmpfs/bazel_tests_virtualenv/lib/python3.5/site-packages/hypothesis/internal/compat.py", line 310, in <module>
    typing._Union,
AttributeError: module 'typing' has no attribute '_Union'


Discussion:
Presumable cause: https://github.com/HypothesisWorks/hypothesis/pull/2092
What's your exact python version? And are you installing a typing module backport? 
We're running in a virtualenv with these packages:
```
$ pip freeze
absl-py==0.8.0
astor==0.8.0
attrs==19.1.0
cloudpickle==1.1.1
cycler==0.10.0
decorator==4.4.0
gast==0.2.2
google-pasta==0.1.7
grpcio==1.23.0
h5py==2.10.0
hypothesis==4.36.1
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.0
kiwisolver==1.1.0
Markdown==3.1.1
matplotlib==3.0.3
mock==3.0.5
numpy==1.17.2
opt-einsum==3.0.1
protobuf==3.9.1
pyparsing==2.4.2
python-dateutil==2.8.0
scipy==1.3.1
six==1.12.0
tb-nightly==2.0.0a20190917
tensorflow-estimator-2.0-preview==1.14.0.dev2019091101
termcolor==1.1.0
tf-nightly-2.0-preview==2.0.0.dev20190917
Werkzeug==0.15.6
wrapt==1.11.2
```
It will take me a bit to dig up the exact python version (beyond 3.5)
there were some changes to the typing module in python 3.5 between micro versions.

I managed to reproduce your issue with python 3.5.0

```
tox -e py35-full --recreate
GLOB sdist-make: /home/jonathan/PycharmProjects/hypothesis/hypothesis-python/setup.py
py35-full create: /home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full
py35-full installdeps: -r../requirements/test.txt
py35-full inst: /home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/.tmp/package/1/hypothesis-4.36.1.zip
py35-full installed: apipkg==1.5,atomicwrites==1.3.0,attrs==19.1.0,execnet==1.7.1,hypothesis==4.36.1,importlib-metadata==0.23,more-itertools==7.2.0,packaging==19.1,pathlib2==2.3.4,pluggy==0.13.0,py==1.8.0,pyparsing==2.4.2,pytest==5.1.2,pytest-forked==1.0.2,pytest-xdist==1.29.0,six==1.12.0,wcwidth==0.1.7,zipp==0.6.0
py35-full run-test-pre: PYTHONHASHSEED='3222604743'
py35-full run-test: commands[0] | bash scripts/basic-test.sh
+++ dirname scripts/basic-test.sh
++ cd scripts
++ pwd
+ HERE=/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/scripts
+ cd /home/jonathan/PycharmProjects/hypothesis/hypothesis-python/scripts/..
+ python -c '
import os
for k, v in sorted(dict(os.environ).items()):
    print("%s=%s" % (k, v))
'
HOME=/home/jonathan
LANG=en_US.UTF-8
OLDPWD=/home/jonathan/PycharmProjects/hypothesis/hypothesis-python
PATH=/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/bin:/home/jonathan/PycharmProjects/hypothesis/venv350/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
PWD=/home/jonathan/PycharmProjects/hypothesis/hypothesis-python
PYTHONHASHSEED=3222604743
SHLVL=1
TOX_ENV_DIR=/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full
TOX_ENV_NAME=py35-full
TOX_PACKAGE=/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/.tmp/package/1/hypothesis-4.36.1.zip
TOX_WORK_DIR=/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox
VIRTUAL_ENV=/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full
_=/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/bin/python
+ pip install .
Looking in indexes: https://pypi.org/simple, https://artifactory-iva.si.francetelecom.fr/artifactory/api/pypi/python-virt-orange-product-devops/simple, https://artifactory-cwfr1.rd.francetelecom.fr/artifactory/api/pypi/python-virt-orange-product-devops/simple
Processing /home/jonathan/PycharmProjects/hypothesis/hypothesis-python
Requirement already satisfied: attrs>=16.0.0 in ./.tox/py35-full/lib/python3.5/site-packages (from hypothesis==4.36.1) (19.1.0)
Building wheels for collected packages: hypothesis
  Building wheel for hypothesis (setup.py) ... done
  Created wheel for hypothesis: filename=hypothesis-4.36.1-cp35-none-any.whl size=270640 sha256=0cd4f3a755c360c7edd292980e88df41f7ac9b7a3751c2b73a78bfd4bd5fffee
  Stored in directory: /home/jonathan/.cache/pip/wheels/66/bd/ff/bcee3e30f03491461728473b3aded632cde06e1b176ecd78a8
Successfully built hypothesis
Installing collected packages: hypothesis
  Found existing installation: hypothesis 4.36.1
    Uninstalling hypothesis-4.36.1:
      Successfully uninstalled hypothesis-4.36.1
Successfully installed hypothesis-4.36.1
+ PYTEST='python -m pytest -n2'
++ python -c 'import sys; print(sys.version_info[0] == 2)'
+ '[' False = True ']'
+ python -m pytest -n2 tests/cover tests/pytest tests/py3
Traceback (most recent call last):
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/hypothesis/internal/compat.py", line 304, 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/jonathan/.pyenv/versions/3.5.0/lib/python3.5/runpy.py", line 170, in _run_module_as_main
    "__main__", mod_spec)
  File "/home/jonathan/.pyenv/versions/3.5.0/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/pytest.py", line 101, in <module>
    raise SystemExit(pytest.main())
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/_pytest/config/__init__.py", line 59, in main
    config = _prepareconfig(args, plugins)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/_pytest/config/__init__.py", line 209, in _prepareconfig
    pluginmanager=pluginmanager, args=args
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/pluggy/manager.py", line 92, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/pluggy/manager.py", line 86, in <lambda>
    firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/pluggy/callers.py", line 203, in _multicall
    gen.send(outcome)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/_pytest/helpconfig.py", line 89, in pytest_cmdline_parse
    config = outcome.get_result()
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/_pytest/config/__init__.py", line 720, in pytest_cmdline_parse
    self.parse(args)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/_pytest/config/__init__.py", line 928, in parse
    self._preparse(args, addopts=addopts)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/_pytest/config/__init__.py", line 874, in _preparse
    self.pluginmanager.load_setuptools_entrypoints("pytest11")
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/pluggy/manager.py", line 297, in load_setuptools_entrypoints
    plugin = ep.load()
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/importlib_metadata/__init__.py", line 92, in load
    module = import_module(match.group('module'))
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/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/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 140, in exec_module
    exec(co, module.__dict__)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/hypothesis/__init__.py", line 27, in <module>
    from hypothesis._settings 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/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 140, in exec_module
    exec(co, module.__dict__)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/hypothesis/_settings.py", line 40, in <module>
    from hypothesis.internal.compat import integer_types, quiet_raise, string_types
  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/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/_pytest/assertion/rewrite.py", line 140, in exec_module
    exec(co, module.__dict__)
  File "/home/jonathan/PycharmProjects/hypothesis/hypothesis-python/.tox/py35-full/lib/python3.5/site-packages/hypothesis/internal/compat.py", line 310, in <module>
    typing._Union,
AttributeError: module 'typing' has no attribute '_Union'
ERROR: InvocationError for command /bin/bash scripts/basic-test.sh (exited with code 1)
_______________________________________________________________________________________________________________ summary _______________________________________________________________________________________________________________
ERROR:   py35-full: commands failed
```
> there were some changes to the typing module in python 3.5 between micro versions.

Yep... I'll fix this and add a 3.5.0 CI environment :weary: 

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
@@ -304,11 +304,13 @@ 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:
+            # 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
         ForwardRef = typing._ForwardRef  # type: ignore
 
 


Test patch: