Merge pull request #842 from nicoddemus/drop-py36-add-py311
Drop Python 3.6 and add Python 3.11
This commit is contained in:
33
.github/workflows/deploy.yml
vendored
Normal file
33
.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# Needed to fetch tags, which are required by setuptools-scm.
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install build
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install build
|
||||
- name: Build package
|
||||
run: |
|
||||
python -m build
|
||||
- name: Publish package to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_token }}
|
||||
87
.github/workflows/main.yml
vendored
87
.github/workflows/main.yml
vendored
@@ -1,87 +0,0 @@
|
||||
name: build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
tox_env:
|
||||
- "py36-pytestlatest"
|
||||
- "py37-pytestlatest"
|
||||
- "py38-pytestlatest"
|
||||
- "py39-pytestlatest"
|
||||
- "py310-pytestlatest"
|
||||
- "py38-pytestmain"
|
||||
- "py38-psutil"
|
||||
- "py38-setproctitle"
|
||||
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
include:
|
||||
- tox_env: "py36-pytestlatest"
|
||||
python: "3.6"
|
||||
- tox_env: "py37-pytestlatest"
|
||||
python: "3.7"
|
||||
- tox_env: "py38-pytestlatest"
|
||||
python: "3.8"
|
||||
- tox_env: "py39-pytestlatest"
|
||||
python: "3.9"
|
||||
- tox_env: "py310-pytestlatest"
|
||||
python: "3.10"
|
||||
- tox_env: "py38-pytestmain"
|
||||
python: "3.8"
|
||||
- tox_env: "py38-psutil"
|
||||
python: "3.8"
|
||||
- tox_env: "py38-setproctitle"
|
||||
python: "3.8"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# Needed to fetch tags, which are required by setuptools-scm.
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
- name: Install tox
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install tox
|
||||
- name: Test
|
||||
run: |
|
||||
tox -e ${{ matrix.tox_env }}
|
||||
|
||||
deploy:
|
||||
|
||||
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# Needed to fetch tags, which are required by setuptools-scm.
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.7"
|
||||
- name: Install wheel
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install build
|
||||
- name: Build package
|
||||
run: |
|
||||
python -m build
|
||||
- name: Publish package to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_token }}
|
||||
67
.github/workflows/test.yml
vendored
Normal file
67
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "*"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "*"
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
tox_env:
|
||||
- "py37-pytestlatest"
|
||||
- "py38-pytestlatest"
|
||||
- "py39-pytestlatest"
|
||||
- "py310-pytestlatest"
|
||||
- "py310-pytestmain"
|
||||
- "py311-pytestlatest"
|
||||
- "py311-pytestmain"
|
||||
- "py310-psutil"
|
||||
- "py310-setproctitle"
|
||||
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
include:
|
||||
- tox_env: "py37-pytestlatest"
|
||||
python: "3.7"
|
||||
- tox_env: "py38-pytestlatest"
|
||||
python: "3.8"
|
||||
- tox_env: "py39-pytestlatest"
|
||||
python: "3.9"
|
||||
- tox_env: "py310-pytestlatest"
|
||||
python: "3.10"
|
||||
- tox_env: "py310-pytestmain"
|
||||
python: "3.10"
|
||||
- tox_env: "py311-pytestlatest"
|
||||
python: "3.11"
|
||||
- tox_env: "py311-pytestmain"
|
||||
python: "3.11"
|
||||
- tox_env: "py310-psutil"
|
||||
python: "3.10"
|
||||
- tox_env: "py310-setproctitle"
|
||||
python: "3.10"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# Needed to fetch tags, which are required by setuptools-scm.
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
- name: Install tox
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install tox
|
||||
- name: Test
|
||||
run: |
|
||||
tox -e ${{ matrix.tox_env }}
|
||||
@@ -13,7 +13,7 @@ pytest-xdist
|
||||
:alt: Python versions
|
||||
:target: https://pypi.python.org/pypi/pytest-xdist
|
||||
|
||||
.. image:: https://github.com/pytest-dev/pytest-xdist/workflows/build/badge.svg
|
||||
.. image:: https://github.com/pytest-dev/pytest-xdist/workflows/test/badge.svg
|
||||
:target: https://github.com/pytest-dev/pytest-xdist/actions
|
||||
|
||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
|
||||
1
changelog/842.feature.rst
Normal file
1
changelog/842.feature.rst
Normal file
@@ -0,0 +1 @@
|
||||
Python 3.11 is now officially supported.
|
||||
1
changelog/842.removal.rst
Normal file
1
changelog/842.removal.rst
Normal file
@@ -0,0 +1 @@
|
||||
Python 3.6 is no longer supported.
|
||||
@@ -24,11 +24,11 @@ classifiers =
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: 3.11
|
||||
license_file = LICENSE
|
||||
project_urls =
|
||||
Documentation=https://pytest-xdist.readthedocs.io/en/latest
|
||||
@@ -40,7 +40,7 @@ project_urls =
|
||||
packages = find:
|
||||
package_dir = =src
|
||||
zip_safe = False
|
||||
python_requires = >=3.6
|
||||
python_requires = >=3.7
|
||||
install_requires =
|
||||
execnet>=1.1
|
||||
pytest>=6.2.0
|
||||
|
||||
@@ -169,7 +169,7 @@ class DSession:
|
||||
"""
|
||||
self.config.hook.pytest_testnodedown(node=node, error=None)
|
||||
if node.workeroutput["exitstatus"] == 2: # keyboard-interrupt
|
||||
self.shouldstop = "{} received keyboard-interrupt".format(node)
|
||||
self.shouldstop = f"{node} received keyboard-interrupt"
|
||||
self.worker_errordown(node, "keyboard-interrupt")
|
||||
return
|
||||
if node in self.sched.nodes:
|
||||
@@ -230,7 +230,7 @@ class DSession:
|
||||
@pytest.hookimpl
|
||||
def pytest_terminal_summary(self, terminalreporter):
|
||||
if self.config.option.verbose >= 0 and self._summary_report:
|
||||
terminalreporter.write_sep("=", "xdist: {}".format(self._summary_report))
|
||||
terminalreporter.write_sep("=", f"xdist: {self._summary_report}")
|
||||
|
||||
def worker_collectionfinish(self, node, ids):
|
||||
"""worker has finished test collection.
|
||||
@@ -345,7 +345,7 @@ class DSession:
|
||||
# XXX count no of failures and retry N times
|
||||
runner = self.config.pluginmanager.getplugin("runner")
|
||||
fspath = nodeid.split("::")[0]
|
||||
msg = "worker {!r} crashed while running {!r}".format(worker.gateway.id, nodeid)
|
||||
msg = f"worker {worker.gateway.id!r} crashed while running {nodeid!r}"
|
||||
rep = runner.TestReport(
|
||||
nodeid, (fspath, None, fspath), (), "failed", msg, "???"
|
||||
)
|
||||
@@ -381,9 +381,7 @@ class TerminalDistReporter:
|
||||
|
||||
def getstatus(self):
|
||||
if self.config.option.verbose >= 0:
|
||||
parts = [
|
||||
"{} {}".format(spec.id, self._status[spec.id]) for spec in self._specs
|
||||
]
|
||||
parts = [f"{spec.id} {self._status[spec.id]}" for spec in self._specs]
|
||||
return " / ".join(parts)
|
||||
else:
|
||||
return "bringing up nodes..."
|
||||
@@ -431,7 +429,7 @@ class TerminalDistReporter:
|
||||
def pytest_testnodedown(self, node, error):
|
||||
if not error:
|
||||
return
|
||||
self.write_line("[{}] node down: {}".format(node.gateway.id, error))
|
||||
self.write_line(f"[{node.gateway.id}] node down: {error}")
|
||||
|
||||
|
||||
def get_default_max_worker_restart(config):
|
||||
|
||||
@@ -146,7 +146,7 @@ def repr_pytest_looponfailinfo(failreports, rootdirs):
|
||||
tr.line(report, red=True)
|
||||
tr.sep("#", "waiting for changes", bold=True)
|
||||
for rootdir in rootdirs:
|
||||
tr.line("### Watching: {}".format(rootdir), bold=True)
|
||||
tr.line(f"### Watching: {rootdir}", bold=True)
|
||||
|
||||
|
||||
def init_worker_session(channel, args, option_dict):
|
||||
|
||||
@@ -149,7 +149,7 @@ class WorkerInteractor:
|
||||
if len(mark.args) > 0
|
||||
else mark.kwargs.get("name", "default")
|
||||
)
|
||||
item._nodeid = "{}@{}".format(item.nodeid, gname)
|
||||
item._nodeid = f"{item.nodeid}@{gname}"
|
||||
|
||||
@pytest.hookimpl
|
||||
def pytest_collection_finish(self, session):
|
||||
|
||||
@@ -361,12 +361,12 @@ class LoadScopeScheduling:
|
||||
extra_nodes = len(self.nodes) - len(self.workqueue)
|
||||
|
||||
if extra_nodes > 0:
|
||||
self.log("Shutting down {} nodes".format(extra_nodes))
|
||||
self.log(f"Shutting down {extra_nodes} nodes")
|
||||
|
||||
for _ in range(extra_nodes):
|
||||
unused_node, assigned = self.assigned_work.popitem(last=True)
|
||||
|
||||
self.log("Shutting down unused node {}".format(unused_node))
|
||||
self.log(f"Shutting down unused node {unused_node}")
|
||||
unused_node.shutdown()
|
||||
|
||||
# Assign initial workload
|
||||
|
||||
@@ -112,7 +112,7 @@ class NodeManager:
|
||||
for root in candidates:
|
||||
root = Path(root).resolve()
|
||||
if not root.exists():
|
||||
raise pytest.UsageError("rsyncdir doesn't exist: {!r}".format(root))
|
||||
raise pytest.UsageError(f"rsyncdir doesn't exist: {root!r}")
|
||||
if root not in roots:
|
||||
roots.append(root)
|
||||
return roots
|
||||
@@ -192,7 +192,7 @@ class HostRSync(execnet.RSync):
|
||||
if self._verbose > 0:
|
||||
path = os.path.basename(self._sourcedir) + "/" + modified_rel_path
|
||||
remotepath = gateway.spec.chdir
|
||||
print("{}:{} <= {}".format(gateway.spec, remotepath, path))
|
||||
print(f"{gateway.spec}:{remotepath} <= {path}")
|
||||
|
||||
|
||||
def make_reltoroot(roots: Sequence[Path], args: List[str]) -> List[str]:
|
||||
@@ -219,7 +219,7 @@ def make_reltoroot(roots: Sequence[Path], args: List[str]) -> List[str]:
|
||||
parts[0] = root.name + "/" + str(x)
|
||||
break
|
||||
else:
|
||||
raise ValueError("arg {} not relative to an rsync root".format(arg))
|
||||
raise ValueError(f"arg {arg} not relative to an rsync root")
|
||||
result.append(splitcode.join(parts))
|
||||
return result
|
||||
|
||||
@@ -249,7 +249,7 @@ class WorkerController:
|
||||
self.log = Producer(f"workerctl-{gateway.id}", enabled=config.option.debug)
|
||||
|
||||
def __repr__(self):
|
||||
return "<{} {}>".format(self.__class__.__name__, self.gateway.id)
|
||||
return f"<{self.__class__.__name__} {self.gateway.id}>"
|
||||
|
||||
@property
|
||||
def shutting_down(self):
|
||||
@@ -310,11 +310,11 @@ class WorkerController:
|
||||
|
||||
def sendcommand(self, name, **kwargs):
|
||||
"""send a named parametrized command to the other side."""
|
||||
self.log("sending command {}(**{})".format(name, kwargs))
|
||||
self.log(f"sending command {name}(**{kwargs})")
|
||||
self.channel.send((name, kwargs))
|
||||
|
||||
def notify_inproc(self, eventname, **kwargs):
|
||||
self.log("queuing {}(**{})".format(eventname, kwargs))
|
||||
self.log(f"queuing {eventname}(**{kwargs})")
|
||||
self.putevent((eventname, kwargs))
|
||||
|
||||
def process_from_remote(self, eventcall): # noqa too complex
|
||||
@@ -336,7 +336,7 @@ class WorkerController:
|
||||
return
|
||||
eventname, kwargs = eventcall
|
||||
if eventname in ("collectionstart",):
|
||||
self.log("ignoring {}({})".format(eventname, kwargs))
|
||||
self.log(f"ignoring {eventname}({kwargs})")
|
||||
elif eventname == "workerready":
|
||||
self.notify_inproc(eventname, node=self, **kwargs)
|
||||
elif eventname == "internal_error":
|
||||
@@ -389,7 +389,7 @@ class WorkerController:
|
||||
location=kwargs["location"],
|
||||
)
|
||||
else:
|
||||
raise ValueError("unknown event: {}".format(eventname))
|
||||
raise ValueError(f"unknown event: {eventname}")
|
||||
except KeyboardInterrupt:
|
||||
# should not land in receiver-thread
|
||||
raise
|
||||
|
||||
@@ -25,7 +25,7 @@ class EventCall:
|
||||
self.name, self.kwargs = eventcall
|
||||
|
||||
def __str__(self):
|
||||
return "<EventCall {}(**{})>".format(self.name, self.kwargs)
|
||||
return f"<EventCall {self.name}(**{self.kwargs})>"
|
||||
|
||||
|
||||
class WorkerSetup:
|
||||
@@ -60,7 +60,7 @@ class WorkerSetup:
|
||||
ev = EventCall(data)
|
||||
if name is None or ev.name == name:
|
||||
return ev
|
||||
print("skipping {}".format(ev))
|
||||
print(f"skipping {ev}")
|
||||
|
||||
def sendcommand(self, name, **kwargs):
|
||||
self.slp.sendcommand(name, **kwargs)
|
||||
|
||||
16
tox.ini
16
tox.ini
@@ -1,10 +1,10 @@
|
||||
[tox]
|
||||
envlist=
|
||||
linting
|
||||
py{36,37,38,39,310}-pytestlatest
|
||||
py38-pytestmain
|
||||
py38-psutil
|
||||
py38-setproctitle
|
||||
py{37,38,39,310,311}-pytestlatest
|
||||
py310-pytestmain
|
||||
py310-psutil
|
||||
py310-setproctitle
|
||||
isolated_build = true
|
||||
[testenv]
|
||||
extras = testing
|
||||
@@ -14,14 +14,14 @@ deps =
|
||||
commands=
|
||||
pytest {posargs}
|
||||
|
||||
[testenv:py38-psutil]
|
||||
[testenv:py310-psutil]
|
||||
extras =
|
||||
testing
|
||||
psutil
|
||||
commands =
|
||||
pytest {posargs:-k psutil}
|
||||
|
||||
[testenv:py38-setproctitle]
|
||||
[testenv:py310-setproctitle]
|
||||
extras =
|
||||
testing
|
||||
setproctitle
|
||||
@@ -40,7 +40,7 @@ commands = pre-commit run --all-files --show-diff-on-failure
|
||||
[testenv:release]
|
||||
changedir=
|
||||
description = do a release, required posarg of the version number
|
||||
basepython = python3.7
|
||||
basepython = python3.10
|
||||
skipsdist = True
|
||||
usedevelop = True
|
||||
passenv = *
|
||||
@@ -50,7 +50,7 @@ commands =
|
||||
towncrier build --version {posargs} --yes
|
||||
|
||||
[testenv:docs]
|
||||
basepython = python3
|
||||
basepython = python3.10
|
||||
usedevelop = True
|
||||
deps =
|
||||
sphinx
|
||||
|
||||
Reference in New Issue
Block a user