You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
8.2 KiB
150 lines
8.2 KiB
5 years ago
|
From 99f99513ce19968ea0e5da15ba2084c32e6d0a2d Mon Sep 17 00:00:00 2001
|
||
|
From: Michel Alexandre Salim <michel@michel-slm.name>
|
||
|
Date: Tue, 12 May 2020 11:14:08 -0700
|
||
|
Subject: [PATCH] Add support for Python 3.9's NamedTuple changes
|
||
|
|
||
|
In Python 3.9, NamedTuples no longer have a `_field_type` attribute;
|
||
|
it has been deprecated since Python 3.8 and the `__annotations__`
|
||
|
attribute has identical information:
|
||
|
|
||
|
```
|
||
|
>>> from typing import NamedTuple
|
||
|
>>> class MyNT(NamedTuple):
|
||
|
... x: int
|
||
|
... y: int = 1
|
||
|
...
|
||
|
...
|
||
|
>>> issubclass(P, tuple)
|
||
|
True
|
||
|
>>> issubclass(P, NamedTuple)
|
||
|
False
|
||
|
>>> hasattr(MyNT, "_fields")
|
||
|
True
|
||
|
>>> hasattr(MyNT, "_field_types")
|
||
|
True
|
||
|
>>> hasattr(MyNT, "__annotations__")
|
||
|
True
|
||
|
>>> MyNT._field_types
|
||
|
{'x': <class 'int'>, 'y': <class 'int'>}
|
||
|
>>> MyNT.__annotations__
|
||
|
{'x': <class 'int'>, 'y': <class 'int'>}
|
||
|
```
|
||
|
|
||
|
see https://bugs.python.org/issue40182
|
||
|
|
||
|
Testing for the existence of *either* `_field_types` or
|
||
|
`__annotations__` fixes the four failing tests on Python 3.9:
|
||
|
|
||
|
```
|
||
|
/builddir/build/BUILD/hypothesis-hypothesis-python-5.12.0/hypothesis-python
|
||
|
<mock-chroot> sh-5.0# PYTHONPATH=/builddir/build/BUILDROOT/python-hypothesis-5.12.0-1.fc33.x86_64/usr/lib/python3.9/site-packages pytest tests/cover/test_lookup.py::test_infers_args_f
|
||
|
or_namedtuple_builds
|
||
|
==================== test session starts ====================
|
||
|
platform linux -- Python 3.9.0a6, pytest-4.6.10, py-1.8.0, pluggy-0.13.0
|
||
|
rootdir: /builddir/build/BUILD/hypothesis-hypothesis-python-5.12.0, inifile: pytest.ini
|
||
|
plugins: hypothesis-5.12.0, xdist-1.32.0, forked-1.1.1
|
||
|
collected 1 item
|
||
|
|
||
|
tests/cover/test_lookup.py . [100%]
|
||
|
|
||
|
================= slowest 20 test durations =================
|
||
|
0.23s call hypothesis-python/tests/cover/test_lookup.py::test_infers_args_for_namedtuple_builds
|
||
|
0.02s setup hypothesis-python/tests/cover/test_lookup.py::test_infers_args_for_namedtuple_builds
|
||
|
|
||
|
(0.00 durations hidden. Use -vv to show these durations.)
|
||
|
================= 1 passed in 0.45 seconds ==================
|
||
|
<mock-chroot> sh-5.0# grep -rl test_infers_args_for_namedtuple_builds *
|
||
|
tests/cover/__pycache__/test_lookup.cpython-39-PYTEST.pyc
|
||
|
tests/cover/test_lookup.py
|
||
|
<mock-chroot> sh-5.0# PYTHONPATH=/builddir/build/BUILDROOT/python-hypothesis-5.12.0-1.fc33.x86_64/usr/lib/python3.9/site-packages pytest tests/cover/test_lookup.py::test_infers_args_for_namedtuple_from_type
|
||
|
==================== test session starts ====================
|
||
|
platform linux -- Python 3.9.0a6, pytest-4.6.10, py-1.8.0, pluggy-0.13.0
|
||
|
rootdir: /builddir/build/BUILD/hypothesis-hypothesis-python-5.12.0, inifile: pytest.ini
|
||
|
plugins: hypothesis-5.12.0, xdist-1.32.0, forked-1.1.1
|
||
|
collected 1 item
|
||
|
|
||
|
tests/cover/test_lookup.py . [100%]
|
||
|
|
||
|
================= slowest 20 test durations =================
|
||
|
0.20s call hypothesis-python/tests/cover/test_lookup.py::test_infers_args_for_namedtuple_from_type
|
||
|
0.02s setup hypothesis-python/tests/cover/test_lookup.py::test_infers_args_for_namedtuple_from_type
|
||
|
|
||
|
(0.00 durations hidden. Use -vv to show these durations.)
|
||
|
================= 1 passed in 0.42 seconds ==================
|
||
|
<mock-chroot> sh-5.0# grep -rl test_resolves_forward_references_outside_annotations *
|
||
|
tests/cover/test_lookup_py36.py
|
||
|
tests/cover/__pycache__/test_lookup_py36.cpython-39-PYTEST.pyc
|
||
|
<mock-chroot> sh-5.0# PYTHONPATH=/builddir/build/BUILDROOT/python-hypothesis-5.12.0-1.fc33.x86_64/usr/lib/python3.9/site-packages pytest tests/cover/test_lookup_py36.py::test_resolves
|
||
|
_forward_references_outside_annotations
|
||
|
==================== test session starts ====================
|
||
|
platform linux -- Python 3.9.0a6, pytest-4.6.10, py-1.8.0, pluggy-0.13.0
|
||
|
rootdir: /builddir/build/BUILD/hypothesis-hypothesis-python-5.12.0, inifile: pytest.ini
|
||
|
plugins: hypothesis-5.12.0, xdist-1.32.0, forked-1.1.1
|
||
|
collected 1 item
|
||
|
|
||
|
tests/cover/test_lookup_py36.py . [100%]
|
||
|
|
||
|
================= slowest 20 test durations =================
|
||
|
0.93s call hypothesis-python/tests/cover/test_lookup_py36.py::test_resolves_forward_references_outside_annotations
|
||
|
0.01s setup hypothesis-python/tests/cover/test_lookup_py36.py::test_resolves_forward_references_outside_annotations
|
||
|
|
||
|
(0.00 durations hidden. Use -vv to show these durations.)
|
||
|
================= 1 passed in 0.95 seconds ==================
|
||
|
<mock-chroot> sh-5.0# PYTHONPATH=/builddir/build/BUILDROOT/python-hypothesis-5.12.0-1.fc33.x86_64/usr/lib/python3.9/site-packages pytest tests/cover/test_lookup.py::test_infers_args_for_namedtuple_from_type^C
|
||
|
<mock-chroot> sh-5.0# grep -rl test_specialised_collection_types *
|
||
|
tests/cover/__pycache__/test_lookup.cpython-39-PYTEST.pyc
|
||
|
tests/cover/test_lookup.py
|
||
|
<mock-chroot> sh-5.0# PYTHONPATH=/builddir/build/BUILDROOT/python-hypothesis-5.12.0-1.fc33.x86_64/usr/lib/python3.9/site-packages pytest tests/cover/test_lookup.py::test_specialised_collection_types
|
||
|
==================== test session starts ====================
|
||
|
platform linux -- Python 3.9.0a6, pytest-4.6.10, py-1.8.0, pluggy-0.13.0
|
||
|
rootdir: /builddir/build/BUILD/hypothesis-hypothesis-python-5.12.0, inifile: pytest.ini
|
||
|
plugins: hypothesis-5.12.0, xdist-1.32.0, forked-1.1.1
|
||
|
collected 14 items
|
||
|
|
||
|
tests/cover/test_lookup.py .............. [100%]
|
||
|
|
||
|
================= slowest 20 test durations =================
|
||
|
0.44s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ12-coll_type12-int]
|
||
|
0.34s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ2-dict-int]
|
||
|
0.34s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ4-dict_values-int]
|
||
|
0.34s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ11-coll_type11-int]
|
||
|
0.31s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ3-dict_keys-int]
|
||
|
0.30s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ10-coll_type10-int]
|
||
|
0.28s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ0-set-int]
|
||
|
0.26s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ1-frozenset-int]
|
||
|
0.23s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ9-coll_type9-int]
|
||
|
0.21s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ7-tuple-int]
|
||
|
0.20s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ5-list-int]
|
||
|
0.19s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ8-coll_type8-int]
|
||
|
0.13s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[A_NamedTuple-tuple-int]
|
||
|
0.10s call hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ6-tuple-int]
|
||
|
0.02s setup hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ2-dict-int]
|
||
|
0.02s setup hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ0-set-int]
|
||
|
0.02s setup hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[A_NamedTuple-tuple-int]
|
||
|
0.02s setup hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ10-coll_type10-int]
|
||
|
0.02s setup hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ11-coll_type11-int]
|
||
|
0.02s setup hypothesis-python/tests/cover/test_lookup.py::test_specialised_collection_types[typ4-dict_values-int]
|
||
|
================= 14 passed in 4.11 seconds =================
|
||
|
```
|
||
|
|
||
|
This addresses issue #2427 .
|
||
|
---
|
||
|
hypothesis-python/src/hypothesis/internal/compat.py | 4 +++-
|
||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/hypothesis-python/src/hypothesis/internal/compat.py b/hypothesis-python/src/hypothesis/internal/compat.py
|
||
|
index 08853a6b80..fd045a3464 100644
|
||
|
--- a/hypothesis-python/src/hypothesis/internal/compat.py
|
||
|
+++ b/hypothesis-python/src/hypothesis/internal/compat.py
|
||
|
@@ -92,7 +92,9 @@ def is_typed_named_tuple(cls):
|
||
|
return (
|
||
|
issubclass(cls, tuple)
|
||
|
and hasattr(cls, "_fields")
|
||
|
- and hasattr(cls, "_field_types")
|
||
|
+ and (hasattr(cls, "_field_types")
|
||
|
+ or hasattr(cls, "__annotations__")
|
||
|
+ )
|
||
|
)
|
||
|
|
||
|
|