Repository: HypothesisWorks/hypothesis

Issue:
6.14.4 test regression with Python 3.10.0b4: 
I suppose the change to `is_a_new_type()` is to blame somehow.

```
$ python3.10 --version
Python 3.10.0b4
```

Example error:
```pytb
___________________________________________________ test_attrs_inference_from_type ____________________________________________________
[gw5] linux -- Python 3.10.0 /usr/bin/python3.10
Traceback (most recent call last):
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/tests/cover/test_annotations.py", line 137, in test_attrs_inference_from_type
    def test_attrs_inference_from_type(c):
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/core.py", line 1037, in wrapped_test
    processed_args = process_arguments_to_given(
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/core.py", line 450, in process_arguments_to_given
    search_strategy.validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/strategies.py", line 400, in validate
    self.do_validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/collections.py", line 46, in do_validate
    s.validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/strategies.py", line 400, in validate
    self.do_validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/strategies.py", line 800, in do_validate
    self.mapped_strategy.validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/strategies.py", line 400, in validate
    self.do_validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/lazy.py", line 135, in do_validate
    w.validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/strategies.py", line 400, in validate
    self.do_validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/strategies.py", line 800, in do_validate
    self.mapped_strategy.validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/strategies.py", line 400, in validate
    self.do_validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/collections.py", line 46, in do_validate
    s.validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/strategies.py", line 400, in validate
    self.do_validate()
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/lazy.py", line 133, in do_validate
    w = self.wrapped_strategy
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/lazy.py", line 112, in wrapped_strategy
    base = self.function(*self.__args, **self.__kwargs)
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/core.py", line 851, in builds
    return from_attrs(target, args, kwargs, required | to_infer)
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/attrs.py", line 33, in from_attrs
    kwargs[name] = from_attrs_attribute(getattr(fields, name), target)
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/attrs.py", line 86, in from_attrs_attribute
    strat = default | null | types_to_strategy(attrib, validator_types)
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/attrs.py", line 123, in types_to_strategy
    if is_a_type(getattr(attrib, "type", None)):
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/types.py", line 116, in is_a_type
    return isinstance(thing, type) or is_generic_type(thing) or is_a_new_type(thing)
  File "/tmp/portage/dev-python/hypothesis-6.14.4/work/hypothesis-hypothesis-python-6.14.4/hypothesis-python-python3_10/build/test/lib/hypothesis/strategies/_internal/types.py", line 111, in is_a_new_type
    return isinstance(thing, typing.NewType)  # pragma: no cover  # on 3.8, anyway
TypeError: isinstance() arg 2 must be a type, a tuple of types or a union
```

Full log: [dev-python:hypothesis-6.14.4:20210727-064254.log](https://github.com/HypothesisWorks/hypothesis/files/6883265/dev-python.hypothesis-6.14.4.20210727-064254.log)



Discussion:
Ugh, yeah. I'll change the condition to check "newtype is not an instance of type" instead of the version. 
Yeap, the same for me:

```
 ---------------------------------- Hypothesis ----------------------------------
You can add @seed(291616716577260634810600700501220117373) to this test or run pytest with --hypothesis-seed=291616716577260634810600700501220117373 to reproduce this failure.
______________ test_requirescontext_applicativen_composition_law _______________

    def factory(source: st.DataObject) -> None:
>       with type_vars():

returns/contrib/hypothesis/laws.py:204: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/hypothesis/core.py:716: in _execute_once_for_engine
    escalate_hypothesis_internal_error()
.venv/lib/python3.10/site-packages/hypothesis/core.py:690: in _execute_once_for_engine
    result = self.execute_once(data)
.venv/lib/python3.10/site-packages/hypothesis/core.py:624: in execute_once
    result = self.test_runner(data, run)
.venv/lib/python3.10/site-packages/hypothesis/executors.py:52: in default_new_style_executor
    return function(data)
.venv/lib/python3.10/site-packages/hypothesis/core.py:620: in run
    return test(*args, **kwargs)
returns/contrib/hypothesis/laws.py:204: in factory
    with type_vars():
.venv/lib/python3.10/site-packages/hypothesis/core.py:562: in test
    result = self.test(*args, **kwargs)
returns/contrib/hypothesis/laws.py:207: in factory
    source.draw(st.builds(law.definition))
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/core.py:1631: in draw
    result = self.conjecture_data.draw(strategy)
.venv/lib/python3.10/site-packages/hypothesis/internal/conjecture/data.py:871: in draw
    strategy.validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/strategies.py:400: in validate
    self.do_validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/lazy.py:135: in do_validate
    w.validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/core.py:792: in validate
    fixed_dictionaries(self.kwargs).validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/strategies.py:400: in validate
    self.do_validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/lazy.py:135: in do_validate
    w.validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/strategies.py:400: in validate
    self.do_validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/strategies.py:800: in do_validate
    self.mapped_strategy.validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/strategies.py:400: in validate
    self.do_validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/collections.py:46: in do_validate
    s.validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/strategies.py:400: in validate
    self.do_validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/lazy.py:135: in do_validate
    w.validate()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/strategies.py:401: in validate
    self.is_empty
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/strategies.py:135: in accept
    recur(self)
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/strategies.py:131: in recur
    mapping[strat] = getattr(strat, calculation)(recur)
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/deferred.py:70: in calc_is_empty
    return recur(self.wrapped_strategy)
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/deferred.py:40: in wrapped_strategy
    result = self.__definition()
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/core.py:944: in <lambda>
    lambda thing: deferred(lambda: _from_type(thing)),
.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/core.py:983: in _from_type
    if types.is_a_new_type(thing):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

thing = returns.interfaces.applicative.ApplicativeN[~_FirstType, ~_SecondType, ~_ThirdType]

    def is_a_new_type(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
E       TypeError: isinstance() arg 2 must be a type, a tuple of types or a union

.venv/lib/python3.10/site-packages/hypothesis/strategies/_internal/types.py:111: TypeError
```

Link: https://github.com/dry-python/returns/pull/1015/checks?check_run_id=3168653314
Refs https://github.com/dry-python/returns/pull/1015
Looks like it is still a function in `3.10.0b4`: https://github.com/python/cpython/blob/v3.10.0b4/Lib/typing.py#L2329

Resolving patch:
diff --git a/hypothesis-python/src/hypothesis/strategies/_internal/types.py b/hypothesis-python/src/hypothesis/strategies/_internal/types.py
--- a/hypothesis-python/src/hypothesis/strategies/_internal/types.py
+++ b/hypothesis-python/src/hypothesis/strategies/_internal/types.py
@@ -98,7 +98,7 @@ def try_issubclass(thing, superclass):
 
 
 def is_a_new_type(thing):
-    if sys.version_info[:2] < (3, 10):
+    if not isinstance(typing.NewType, type):
         # At runtime, `typing.NewType` returns an identity function rather
         # than an actual type, but we can check whether that thing matches.
         return (


Test patch: