Skip to content

Commit

Permalink
Add support for Python 3.11 (#969)
Browse files Browse the repository at this point in the history
* Add support for Python 3.11

Co-authored-by: Tin Tvrtković <tinchester@gmail.com>

* Tin/py311 (#973)

* Fix test_slots::TestPickle::test_no_getstate_setstate_for_dict_classes

* Fix annotations

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Tweak tests for 3.10

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Tweak tests some more

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

Co-authored-by: Tin Tvrtković <tinchester@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Jun 24, 2022
1 parent a7e82b5 commit a18b395
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "pypy-3.7", "pypy-3.8"]
python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11.0-beta - 3.11", "pypy-3.7", "pypy-3.8"]

steps:
- uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions setup.py
Expand Up @@ -39,6 +39,7 @@
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Libraries :: Python Modules",
Expand Down
28 changes: 13 additions & 15 deletions src/attr/_compat.py
Expand Up @@ -111,12 +111,10 @@ def force_x_to_be_a_cell(): # pragma: no cover
# Convert this code object to a code object that sets the
# function's first _freevar_ (not cellvar) to the argument.
if sys.version_info >= (3, 8):
# CPython 3.8+ has an incompatible CodeType signature
# (added a posonlyargcount argument) but also added
# CodeType.replace() to do this without counting parameters.
set_first_freevar_code = co.replace(
co_cellvars=co.co_freevars, co_freevars=co.co_cellvars
)

def set_closure_cell(cell, value):
cell.cell_contents = value

else:
args = [co.co_argcount]
args.append(co.co_kwonlyargcount)
Expand All @@ -140,15 +138,15 @@ def force_x_to_be_a_cell(): # pragma: no cover
)
set_first_freevar_code = types.CodeType(*args)

def set_closure_cell(cell, value):
# Create a function using the set_first_freevar_code,
# whose first closure cell is `cell`. Calling it will
# change the value of that cell.
setter = types.FunctionType(
set_first_freevar_code, {}, "setter", (), (cell,)
)
# And call it to set the cell.
setter(value)
def set_closure_cell(cell, value):
# Create a function using the set_first_freevar_code,
# whose first closure cell is `cell`. Calling it will
# change the value of that cell.
setter = types.FunctionType(
set_first_freevar_code, {}, "setter", (), (cell,)
)
# And call it to set the cell.
setter(value)

# Make sure it works on this interpreter:
def make_func_with_cell():
Expand Down
13 changes: 9 additions & 4 deletions tests/test_annotations.py
Expand Up @@ -94,6 +94,10 @@ class C:
assert 1 == len(attr.fields(C))
assert_init_annotations(C, x=typing.List[int])

@pytest.mark.skipif(
sys.version_info[:2] < (3, 11),
reason="Incompatible behavior on older Pythons",
)
@pytest.mark.parametrize("slots", [True, False])
def test_auto_attribs(self, slots):
"""
Expand Down Expand Up @@ -149,7 +153,7 @@ class C:
x=typing.List[int],
y=int,
z=int,
foo=typing.Optional[typing.Any],
foo=typing.Any,
)

@pytest.mark.parametrize("slots", [True, False])
Expand Down Expand Up @@ -384,8 +388,9 @@ def noop():

assert attr.converters.optional(noop).__annotations__ == {}

@pytest.mark.xfail(
sys.version_info[:2] == (3, 6), reason="Does not work on 3.6."
@pytest.mark.skipif(
sys.version_info[:2] < (3, 11),
reason="Incompatible behavior on older Pythons",
)
@pytest.mark.parametrize("slots", [True, False])
def test_annotations_strings(self, slots):
Expand Down Expand Up @@ -417,7 +422,7 @@ class C:
x=typing.List[int],
y=int,
z=int,
foo=typing.Optional[typing.Any],
foo=typing.Any,
)

@pytest.mark.parametrize("slots", [True, False])
Expand Down
8 changes: 6 additions & 2 deletions tests/test_make.py
Expand Up @@ -2275,7 +2275,9 @@ class C:
def __getstate__(self):
return ("hi",)

assert None is getattr(C(), "__setstate__", None)
assert getattr(object, "__setstate__", None) is getattr(
C, "__setstate__", None
)

@attr.s(slots=slots, auto_detect=True)
class C:
Expand All @@ -2291,7 +2293,9 @@ def __setstate__(self, state):
i.__setstate__(())

assert True is i.called
assert None is getattr(C(), "__getstate__", None)
assert getattr(object, "__getstate__", None) is getattr(
C, "__getstate__", None
)

@pytest.mark.skipif(PY310, reason="Pre-3.10 only.")
def test_match_args_pre_310(self):
Expand Down
20 changes: 12 additions & 8 deletions tests/test_slots.py
Expand Up @@ -660,10 +660,12 @@ def test_no_getstate_setstate_for_dict_classes(self):
As long as getstate_setstate is None, nothing is done to dict
classes.
"""
i = C1(1, 2)

assert None is getattr(i, "__getstate__", None)
assert None is getattr(i, "__setstate__", None)
assert getattr(object, "__getstate__", None) is getattr(
C1, "__getstate__", None
)
assert getattr(object, "__setstate__", None) is getattr(
C1, "__setstate__", None
)

def test_no_getstate_setstate_if_option_false(self):
"""
Expand All @@ -674,10 +676,12 @@ def test_no_getstate_setstate_if_option_false(self):
class C:
x = attr.ib()

i = C(42)

assert None is getattr(i, "__getstate__", None)
assert None is getattr(i, "__setstate__", None)
assert getattr(object, "__getstate__", None) is getattr(
C, "__getstate__", None
)
assert getattr(object, "__setstate__", None) is getattr(
C, "__setstate__", None
)

@pytest.mark.parametrize("cls", [C2(1), C2Slots(1)])
def test_getstate_set_state_force_true(self, cls):
Expand Down
3 changes: 2 additions & 1 deletion tox.ini
Expand Up @@ -16,11 +16,12 @@ python =
3.8: py38, changelog
3.9: py39, pyright
3.10: py310, manifest, typing, docs
3.11: py311
pypy-3: pypy3


[tox]
envlist = typing,pre-commit,py35,py36,py37,py38,py39,py310,pypy3,pyright,manifest,docs,pypi-description,changelog,coverage-report
envlist = typing,pre-commit,py35,py36,py37,py38,py39,py310,py311,pypy3,pyright,manifest,docs,pypi-description,changelog,coverage-report
isolated_build = True


Expand Down

0 comments on commit a18b395

Please sign in to comment.