Add support for Python 3.10 (#250)

* Fix tests on Python 3.10.
* "Fix" a test broken just on windows + allow to use posargs for tox test runs.
* Checking array.array non-strictly did not help on Windows. – So ignore it completely.
This commit is contained in:
Michael Howitz 2022-01-24 13:03:51 +01:00 committed by GitHub
parent 64784b2b96
commit 67a4f6f7f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 122 additions and 100 deletions

View File

@ -28,7 +28,7 @@ max_line_length = off
# 4 space indentation # 4 space indentation
indent_size = 4 indent_size = 4
[*.{yml,zpt,pt,dtml}] [*.{yml,zpt,pt,dtml,zcml}]
# 2 space indentation # 2 space indentation
indent_size = 2 indent_size = 2

View File

@ -92,24 +92,26 @@ jobs:
# with `test`, and `docs` must use a subset. # with `test`, and `docs` must use a subset.
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false
matrix: matrix:
python-version: python-version:
- 2.7 - "2.7"
- 3.5 - "3.5"
- pypy-2.7 - "pypy-2.7"
- pypy-3.6 - "pypy-3.7"
- 3.6 - "3.6"
- 3.7 - "3.7"
- 3.8 - "3.8"
- 3.9 - "3.9"
- "3.10"
os: [ubuntu-20.04, macos-latest] os: [ubuntu-20.04, macos-latest]
exclude: exclude:
- os: macos-latest - os: macos-latest
python-version: pypy-2.7 python-version: "pypy-2.7"
- os: macos-latest - os: macos-latest
python-version: pypy-3.6 python-version: "pypy-3.7"
- os: macos-latest - os: macos-latest
python-version: 3.5 python-version: "3.5"
steps: steps:
- name: checkout - name: checkout
@ -167,7 +169,7 @@ jobs:
# We cannot 'uses: pypa/gh-action-pypi-publish@v1.4.1' because # We cannot 'uses: pypa/gh-action-pypi-publish@v1.4.1' because
# that's apparently a container action, and those don't run on # that's apparently a container action, and those don't run on
# the Mac. # the Mac.
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') && startsWith(runner.os, 'Mac') if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') && startsWith(runner.os, 'Mac') && !startsWith(matrix.python-version, 'pypy')
env: env:
TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
run: | run: |
@ -177,24 +179,26 @@ jobs:
needs: build-package needs: build-package
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false
matrix: matrix:
python-version: python-version:
- 2.7 - "2.7"
- 3.5 - "3.5"
- pypy-2.7 - "pypy-2.7"
- pypy-3.6 - "pypy-3.7"
- 3.6 - "3.6"
- 3.7 - "3.7"
- 3.8 - "3.8"
- 3.9 - "3.9"
- "3.10"
os: [ubuntu-20.04, macos-latest] os: [ubuntu-20.04, macos-latest]
exclude: exclude:
- os: macos-latest - os: macos-latest
python-version: pypy-2.7 python-version: "pypy-2.7"
- os: macos-latest - os: macos-latest
python-version: pypy-3.6 python-version: "pypy-3.7"
- os: macos-latest - os: macos-latest
python-version: 3.5 python-version: "3.5"
steps: steps:
- name: checkout - name: checkout
@ -270,7 +274,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
python-version: [3.9] python-version: ["3.9"]
os: [ubuntu-20.04] os: [ubuntu-20.04]
steps: steps:
@ -309,8 +313,6 @@ jobs:
pip install -U wheel pip install -U wheel
pip install -U coverage pip install -U coverage
pip install -U "`ls dist/zope.interface-*.whl`[docs]" pip install -U "`ls dist/zope.interface-*.whl`[docs]"
# Until repoze.sphinx.autointerface supports Sphinx 4.x we cannot use it:
pip install -U "Sphinx < 4"
- name: Build docs - name: Build docs
env: env:
ZOPE_INTERFACE_STRICT_IRO: 1 ZOPE_INTERFACE_STRICT_IRO: 1
@ -318,13 +320,12 @@ jobs:
sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest
lint: lint:
needs: build-package needs: build-package
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
python-version: [3.9] python-version: ["3.9"]
os: [ubuntu-20.04] os: [ubuntu-20.04]
steps: steps:
@ -376,7 +377,7 @@ jobs:
# We use a regular Python matrix entry to share as much code as possible. # We use a regular Python matrix entry to share as much code as possible.
strategy: strategy:
matrix: matrix:
python-version: [3.9] python-version: ["3.9"]
image: [manylinux2010_x86_64, manylinux2010_i686, manylinux2014_aarch64] image: [manylinux2010_x86_64, manylinux2010_i686, manylinux2014_aarch64]
steps: steps:
@ -415,13 +416,13 @@ jobs:
# The 2010 image is the most recent spec that comes with Python 2.7, # The 2010 image is the most recent spec that comes with Python 2.7,
# and only up through the tag 2021-02-06-3d322a5 # and only up through the tag 2021-02-06-3d322a5
env: env:
DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }}:2021-02-06-3d322a5 DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }}
run: | run: |
bash .manylinux.sh bash .manylinux.sh
- name: Build zope.interface (i686) - name: Build zope.interface (i686)
if: matrix.image == 'manylinux2010_i686' if: matrix.image == 'manylinux2010_i686'
env: env:
DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }}:2021-02-06-3d322a5 DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }}
PRE_CMD: linux32 PRE_CMD: linux32
run: | run: |
bash .manylinux.sh bash .manylinux.sh

2
.gitignore vendored
View File

@ -1,9 +1,11 @@
# Generated from: # Generated from:
# https://github.com/zopefoundation/meta/tree/master/config/c-code # https://github.com/zopefoundation/meta/tree/master/config/c-code
*.dll
*.egg-info/ *.egg-info/
*.profraw *.profraw
*.pyc *.pyc
*.pyo *.pyo
*.so
.coverage .coverage
.coverage.* .coverage.*
.eggs/ .eggs/

View File

@ -1,4 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Generated from:
# https://github.com/zopefoundation/meta/tree/master/config/c-code
set -e -x set -e -x
@ -21,14 +23,19 @@ fi
ls -ld /cache ls -ld /cache
ls -ld /cache/pip ls -ld /cache/pip
# We need some libraries because we build wheels from scratch:
yum -y install libffi-devel
# Compile wheels # Compile wheels
for PYBIN in /opt/python/*/bin; do for PYBIN in /opt/python/*/bin; do
if [[ "${PYBIN}" == *"cp27"* ]] || \ if \
[[ "${PYBIN}" == *"cp27"* ]] || \
[[ "${PYBIN}" == *"cp35"* ]] || \ [[ "${PYBIN}" == *"cp35"* ]] || \
[[ "${PYBIN}" == *"cp36"* ]] || \ [[ "${PYBIN}" == *"cp36"* ]] || \
[[ "${PYBIN}" == *"cp37"* ]] || \ [[ "${PYBIN}" == *"cp37"* ]] || \
[[ "${PYBIN}" == *"cp38"* ]] || \ [[ "${PYBIN}" == *"cp38"* ]] || \
[[ "${PYBIN}" == *"cp39"* ]]; then [[ "${PYBIN}" == *"cp39"* ]] || \
[[ "${PYBIN}" == *"cp310"* ]] ; then
"${PYBIN}/pip" install -e /io/ "${PYBIN}/pip" install -e /io/
"${PYBIN}/pip" wheel /io/ -w wheelhouse/ "${PYBIN}/pip" wheel /io/ -w wheelhouse/
if [ `uname -m` == 'aarch64' ]; then if [ `uname -m` == 'aarch64' ]; then

View File

@ -1,4 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Generated from:
# https://github.com/zopefoundation/meta/tree/master/config/c-code
set -e -x set -e -x

View File

@ -2,44 +2,30 @@
# https://github.com/zopefoundation/meta/tree/master/config/c-code # https://github.com/zopefoundation/meta/tree/master/config/c-code
[meta] [meta]
template = "c-code" template = "c-code"
commit-id = "3ddccc7a1430600364f48f37e4f24a275e1bbb85" commit-id = "23625f0c67c2171441dbe2069830d3b3fdb17757"
[python] [python]
with-appveyor = true with-appveyor = true
with-pypy = true with-pypy = true
with-legacy-python = true with-legacy-python = true
with-docs = false with-sphinx-doctests = true
with-sphinx-doctests = false with-windows = false
with-future-python = false
with-docs = true
[tox] [tox]
use-flake8 = false use-flake8 = false
additional-envlist = [
"docs",
]
testenv-commands = [ testenv-commands = [
"coverage run -p -m unittest discover -s src", "coverage run -p -m unittest discover -s src {posargs}",
] ]
testenv-deps = [ testenv-deps = [
] ]
testenv-setenv = [ testenv-setenv = [
"ZOPE_INTERFACE_STRICT_IRO=1", "ZOPE_INTERFACE_STRICT_IRO=1",
] ]
testenv-additional = [
"",
"[testenv:docs]",
"basepython = python3",
"# Until repoze.sphinx.autointerface supports Sphinx 4.x we cannot use it:",
"deps =",
" Sphinx < 4",
" coverage",
"extras = docs",
"commands =",
" sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html",
" coverage run -p -m sphinx -b doctest -d docs/_build/doctrees docs docs/_build/doctest",
]
coverage-command = "coverage combine" coverage-command = "coverage combine"
coverage-additional = [ coverage-additional = [
"depends = py27,py27-pure,py35,py35-pure,py36,py36-pure,py37,py37-pure,py38,py38-pure,py39,py39-pure,pypy,pypy3,docs", "depends = py27,py27-pure,py35,py35-pure,py36,py36-pure,py37,py37-pure,py38,py38-pure,py39,py39-pure,py310,py310-pure,pypy,pypy3,docs",
"parallel_show_output = true", "parallel_show_output = true",
] ]
@ -102,19 +88,6 @@ global-env-vars = [
" TWINE_PASSWORD:", " TWINE_PASSWORD:",
" secure: aoZC/+rvJKg8B5GMGIxd1X2q2bz7SMl8G3810BID9U8PXFqM0FbWaK9fZ9qcU0UyG2xJsK56Fb6+L6g27I0Lg8UFNhlU1zLAuMSgJQbHsqawFgSY067IdJB68pp34d/oEyxMrJvAKENHH77Fe4KGDssLlk5WnnYS3DA9b66p5imP+1DTtkq5/gMtoG4nZTBtVos7J2kkYTQ5t4BjzTQxPMC3bStNnvuuB0orX4AoCyTrOR1wdZFiNKLzbVnrJCNn24t/n3kG9WrxbnKlrbOm4A==", " secure: aoZC/+rvJKg8B5GMGIxd1X2q2bz7SMl8G3810BID9U8PXFqM0FbWaK9fZ9qcU0UyG2xJsK56Fb6+L6g27I0Lg8UFNhlU1zLAuMSgJQbHsqawFgSY067IdJB68pp34d/oEyxMrJvAKENHH77Fe4KGDssLlk5WnnYS3DA9b66p5imP+1DTtkq5/gMtoG4nZTBtVos7J2kkYTQ5t4BjzTQxPMC3bStNnvuuB0orX4AoCyTrOR1wdZFiNKLzbVnrJCNn24t/n3kG9WrxbnKlrbOm4A==",
] ]
build-script = [
"- python -W ignore setup.py -q bdist_wheel",
]
test-steps = [ test-steps = [
"- python -m unittest discover -s src", "- python -m unittest discover -s src",
] ]
additional-lines = [
"artifacts:",
" - path: 'dist\\*.whl'",
" name: wheel",
"",
"deploy_script:",
" - ps: if ($env:APPVEYOR_REPO_TAG -eq $TRUE) { pip install twine; twine upload --skip-existing dist/* }",
"",
"deploy: on",
]

View File

@ -2,9 +2,11 @@
Changes Changes
========= =========
5.4.1 (unreleased) 5.5.0 (unreleased)
================== ==================
- Add support for Python 3.10.
- Add missing Trove classifier showing support for Python 3.9. - Add missing Trove classifier showing support for Python 3.9.
- Add some more entries to ``zope.interface.interfaces.__all__``. - Add some more entries to ``zope.interface.interfaces.__all__``.

View File

@ -7,6 +7,11 @@ include tox.ini
include appveyor.yml include appveyor.yml
include .coveragerc include .coveragerc
recursive-include docs *.py
recursive-include docs *.rst
recursive-include docs *.txt
recursive-include docs Makefile
recursive-include src *.py recursive-include src *.py
include *.cmd include *.cmd
include *.sh include *.sh

View File

@ -1,10 +1,9 @@
# Generated from: # Generated from:
# https://github.com/zopefoundation/meta/tree/master/config/c-code # https://github.com/zopefoundation/meta/tree/master/config/c-code
environment: environment:
# Currently the builds use @mgedmin's Appveyor account. The PyPI token # Currently the builds use @mgedmin's Appveyor account. The PyPI token
# belongs to zope.wheelbuilder, which is managed by @mgedmin and @dataflake. # belongs to zope.wheelbuilder, which is managed by @mgedmin and @dataflake.
global: global:
TWINE_USERNAME: __token__ TWINE_USERNAME: __token__
TWINE_PASSWORD: TWINE_PASSWORD:
@ -23,6 +22,8 @@ environment:
- python: 38-x64 - python: 38-x64
- python: 39 - python: 39
- python: 39-x64 - python: 39-x64
- python: 310
- python: 310-x64
install: install:
- "SET PYTHONVERSION=%PYTHON%" - "SET PYTHONVERSION=%PYTHON%"
@ -47,14 +48,11 @@ build_script:
test_script: test_script:
- python -m unittest discover -s src - python -m unittest discover -s src
on_success:
- echo Build succesful!
artifacts: artifacts:
- path: 'dist\*.whl' - path: 'dist\*.whl'
name: wheel name: wheel
deploy_script: deploy_script:
- ps: if ($env:APPVEYOR_REPO_TAG -eq $TRUE) { pip install twine; twine upload --skip-existing dist/* } - ps: if ($env:APPVEYOR_REPO_TAG -eq $TRUE) { pip install twine; twine upload --skip-existing dist\*.whl }
deploy: on deploy: on

View File

@ -3,6 +3,9 @@
[bdist_wheel] [bdist_wheel]
universal = 1 universal = 1
[zest.releaser]
create-wheel = no
[flake8] [flake8]
doctests = 1 doctests = 1
@ -10,6 +13,8 @@ doctests = 1
ignore = ignore =
.editorconfig .editorconfig
.meta.toml .meta.toml
docs/_build/html/_sources/*
docs/_build/doctest/*
docs/_build/doctest/output.txt docs/_build/doctest/output.txt
docs/_build/html/_sources/* docs/_build/html/_sources/*
docs/_build/html/_sources/api/* docs/_build/html/_sources/api/*

View File

@ -100,7 +100,7 @@ long_description = (
) )
setup(name='zope.interface', setup(name='zope.interface',
version='5.4.1.dev0', version='5.5.0.dev0',
url='https://github.com/zopefoundation/zope.interface', url='https://github.com/zopefoundation/zope.interface',
license='ZPL 2.1', license='ZPL 2.1',
description='Interfaces for Python', description='Interfaces for Python',
@ -121,6 +121,7 @@ setup(name='zope.interface',
"Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: PyPy",
"Framework :: Zope :: 3", "Framework :: Zope :: 3",

View File

@ -81,16 +81,17 @@ def add_verify_tests(cls, iface_classes_iter):
sro = implements.__sro__ sro = implements.__sro__
self.assertIs(sro[-1], Interface) self.assertIs(sro[-1], Interface)
# Check that we got the strict C3 resolution order, unless we if stdlib_class not in self.UNVERIFIABLE_RO:
# know we cannot. Note that 'Interface' is virtual base that doesn't # Check that we got the strict C3 resolution order, unless
# necessarily appear at the same place in the calculated SRO as in the # we know we cannot. Note that 'Interface' is virtual base
# final SRO. # that doesn't necessarily appear at the same place in the
strict = stdlib_class not in self.NON_STRICT_RO # calculated SRO as in the final SRO.
isro = ro.ro(implements, strict=strict) strict = stdlib_class not in self.NON_STRICT_RO
isro.remove(Interface) isro = ro.ro(implements, strict=strict)
isro.append(Interface) isro.remove(Interface)
isro.append(Interface)
self.assertEqual(tuple(isro), sro) self.assertEqual(tuple(isro), sro)
name = 'test_auto_ro_' + suffix name = 'test_auto_ro_' + suffix
test_ro.__name__ = name test_ro.__name__ = name
@ -101,6 +102,7 @@ class VerifyClassMixin(unittest.TestCase):
verifier = staticmethod(verifyClass) verifier = staticmethod(verifyClass)
UNVERIFIABLE = () UNVERIFIABLE = ()
NON_STRICT_RO = () NON_STRICT_RO = ()
UNVERIFIABLE_RO = ()
def _adjust_object_before_verify(self, iface, x): def _adjust_object_before_verify(self, iface, x):
return x return x

View File

@ -11,6 +11,7 @@
############################################################################## ##############################################################################
import array
import unittest import unittest
try: try:
import collections.abc as abc import collections.abc as abc
@ -93,6 +94,10 @@ class TestVerifyClass(VerifyClassMixin, unittest.TestCase):
# It's imported because...? Coverage imports it, but why do we have it without # It's imported because...? Coverage imports it, but why do we have it without
# coverage? # coverage?
'Row', 'Row',
# In Python 3.10 ``array.array`` appears as ``IMutableSequence`` but it
# does not provide a ``clear()`` method and it cannot be instantiated
# using ``array.array()``.
array.array,
} }
if PYPY: if PYPY:
@ -121,6 +126,14 @@ class TestVerifyClass(VerifyClassMixin, unittest.TestCase):
}) })
NON_STRICT_RO = { NON_STRICT_RO = {
} }
else:
UNVERIFIABLE_RO = {
# ``array.array`` fails the ``test_auto_ro_*`` tests with and
# without strict RO but only on Windows (AppVeyor) on Python 3.10.0
# (in older versions ``array.array`` does not appear as
# ``IMutableSequence``).
array.array,
}
add_abc_interface_tests(TestVerifyClass, collections.ISet.__module__) add_abc_interface_tests(TestVerifyClass, collections.ISet.__module__)
@ -158,3 +171,11 @@ class TestVerifyObject(VerifyObjectMixin,
CONSTRUCTORS.update({ CONSTRUCTORS.update({
collections.IValuesView: {}.viewvalues, collections.IValuesView: {}.viewvalues,
}) })
else:
UNVERIFIABLE_RO = {
# ``array.array`` fails the ``test_auto_ro_*`` tests with and
# without strict RO but only on Windows (AppVeyor) on Python 3.10.0
# (in older versions ``array.array`` does not appear as
# ``IMutableSequence``).
array.array,
}

33
tox.ini
View File

@ -10,10 +10,11 @@ envlist =
py37,py37-pure py37,py37-pure
py38,py38-pure py38,py38-pure
py39,py39-pure py39,py39-pure
py310,py310-pure
pypy pypy
pypy3 pypy3
coverage
docs docs
coverage
[testenv] [testenv]
usedevelop = true usedevelop = true
@ -23,20 +24,11 @@ setenv =
!pure-!pypy-!pypy3: PURE_PYTHON=0 !pure-!pypy-!pypy3: PURE_PYTHON=0
ZOPE_INTERFACE_STRICT_IRO=1 ZOPE_INTERFACE_STRICT_IRO=1
commands = commands =
coverage run -p -m unittest discover -s src coverage run -p -m unittest discover -s src {posargs}
!py27-!pypy: sphinx-build -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
extras = extras =
test test
docs
[testenv:docs]
basepython = python3
# Until repoze.sphinx.autointerface supports Sphinx 4.x we cannot use it:
deps =
Sphinx < 4
coverage
extras = docs
commands =
sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
coverage run -p -m sphinx -b doctest -d docs/_build/doctrees docs docs/_build/doctest
[testenv:coverage] [testenv:coverage]
basepython = python3 basepython = python3
@ -44,12 +36,14 @@ allowlist_externals =
mkdir mkdir
deps = deps =
coverage coverage
setenv =
PURE_PYTHON=1
commands = commands =
mkdir -p {toxinidir}/parts/htmlcov mkdir -p {toxinidir}/parts/htmlcov
coverage combine coverage combine
coverage html -i coverage html -i
coverage report -i -m --fail-under=99 coverage report -i -m --fail-under=99
depends = py27,py27-pure,py35,py35-pure,py36,py36-pure,py37,py37-pure,py38,py38-pure,py39,py39-pure,pypy,pypy3,docs depends = py27,py27-pure,py35,py35-pure,py36,py36-pure,py37,py37-pure,py38,py38-pure,py39,py39-pure,py310,py310-pure,pypy,pypy3,docs
parallel_show_output = true parallel_show_output = true
[testenv:lint] [testenv:lint]
@ -57,7 +51,16 @@ basepython = python3
skip_install = true skip_install = true
deps = deps =
check-manifest check-manifest
check-python-versions check-python-versions >= 0.19.1
wheel
commands = commands =
check-manifest check-manifest
check-python-versions check-python-versions
[testenv:docs]
basepython = python3
skip_install = false
commands_pre =
commands =
sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest