Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pytest-xdist for
openSUSE:Factory checked in at 2023-05-19 11:55:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-xdist (Old)
and /work/SRC/openSUSE:Factory/.python-pytest-xdist.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-xdist"
Fri May 19 11:55:15 2023 rev:22 rq:1087079 version:3.3.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pytest-xdist/python-pytest-xdist.changes
2023-04-25 16:53:25.934159946 +0200
+++
/work/SRC/openSUSE:Factory/.python-pytest-xdist.new.1533/python-pytest-xdist.changes
2023-05-19 11:55:44.083336425 +0200
@@ -1,0 +2,7 @@
+Sun May 14 09:36:49 UTC 2023 - Dirk Müller <[email protected]>
+
+- update to 3.3.0:
+ * Improved progress output when collecting nodes to be less
+ verbose.
+
+-------------------------------------------------------------------
Old:
----
pytest-xdist-3.2.1.tar.gz
New:
----
pytest-xdist-3.3.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pytest-xdist.spec ++++++
--- /var/tmp/diff_new_pack.D3yfy8/_old 2023-05-19 11:55:44.699339951 +0200
+++ /var/tmp/diff_new_pack.D3yfy8/_new 2023-05-19 11:55:44.711340019 +0200
@@ -19,7 +19,7 @@
%define skip_python2 1
%{?sle15_python_module_pythons}
Name: python-pytest-xdist
-Version: 3.2.1
+Version: 3.3.0
Release: 0
Summary: Distributed testing and loop-on-failing for py.test
License: MIT
++++++ pytest-xdist-3.2.1.tar.gz -> pytest-xdist-3.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/CHANGELOG.rst
new/pytest-xdist-3.3.0/CHANGELOG.rst
--- old/pytest-xdist-3.2.1/CHANGELOG.rst 2023-03-12 16:09:12.000000000
+0100
+++ new/pytest-xdist-3.3.0/CHANGELOG.rst 2023-05-12 22:41:10.000000000
+0200
@@ -1,3 +1,12 @@
+pytest-xdist 3.3.0 (2023-05-12)
+===============================
+
+Features
+--------
+
+- `#555 <https://github.com/pytest-dev/pytest-xdist/issues/555>`_: Improved
progress output when collecting nodes to be less verbose.
+
+
pytest-xdist 3.2.1 (2023-03-12)
===============================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/PKG-INFO
new/pytest-xdist-3.3.0/PKG-INFO
--- old/pytest-xdist-3.2.1/PKG-INFO 2023-03-12 16:09:27.893345800 +0100
+++ new/pytest-xdist-3.3.0/PKG-INFO 2023-05-12 22:41:30.270263200 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytest-xdist
-Version: 3.2.1
+Version: 3.3.0
Summary: pytest xdist plugin for distributed testing, most importantly across
multiple CPUs
Home-page: https://github.com/pytest-dev/pytest-xdist
Author: holger krekel and contributors
@@ -32,6 +32,7 @@
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Requires-Python: >=3.7
+Description-Content-Type: text/x-rst
Provides-Extra: testing
Provides-Extra: psutil
Provides-Extra: setproctitle
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/RELEASING.rst
new/pytest-xdist-3.3.0/RELEASING.rst
--- old/pytest-xdist-3.2.1/RELEASING.rst 2023-03-12 16:09:12.000000000
+0100
+++ new/pytest-xdist-3.3.0/RELEASING.rst 2023-05-12 22:41:10.000000000
+0200
@@ -32,14 +32,8 @@
$ tox -e release -- X.Y.Z
-#. Commit and push the branch for review.
+#. Commit and push the branch to ``upstream`` and open a PR.
-#. Once PR is **green** and **approved**, create and push a tag::
+#. Once the PR is **green** and **approved**, start the ``deploy`` workflow
manually from the branch ``release-VERSION``, passing ``VERSION`` as parameter.
- $ export VERSION=X.Y.Z
- $ git tag v$VERSION release-$VERSION
- $ git push [email protected]:pytest-dev/pytest-xdist.git v$VERSION
-
-That will build the package and publish it on ``PyPI`` automatically.
-
-#. Merge the release PR to `master`.
+#. Merge the release PR to ``master``.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/docs/distribution.rst
new/pytest-xdist-3.3.0/docs/distribution.rst
--- old/pytest-xdist-3.2.1/docs/distribution.rst 2023-03-12
16:09:12.000000000 +0100
+++ new/pytest-xdist-3.3.0/docs/distribution.rst 2023-05-12
22:41:10.000000000 +0200
@@ -50,7 +50,8 @@
.. _distribution modes:
* ``--dist load`` **(default)**: Sends pending tests to any worker that is
- available, without any guaranteed order.
+ available, without any guaranteed order. Scheduling can be fine-tuned with
+ the `--maxschedchunk` option, see output of `pytest --help`.
* ``--dist loadscope``: Tests are grouped by **module** for *test functions*
and by **class** for *test methods*. Groups are distributed to available
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/setup.cfg
new/pytest-xdist-3.3.0/setup.cfg
--- old/pytest-xdist-3.2.1/setup.cfg 2023-03-12 16:09:27.893345800 +0100
+++ new/pytest-xdist-3.3.0/setup.cfg 2023-05-12 22:41:30.270263200 +0200
@@ -2,6 +2,7 @@
name = pytest-xdist
description = pytest xdist plugin for distributed testing, most importantly
across multiple CPUs
long_description = file: README.rst
+long_description_content_type = text/x-rst
license = MIT
author = holger krekel and contributors
author_email = [email protected],[email protected]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest-xdist-3.2.1/src/pytest_xdist.egg-info/PKG-INFO
new/pytest-xdist-3.3.0/src/pytest_xdist.egg-info/PKG-INFO
--- old/pytest-xdist-3.2.1/src/pytest_xdist.egg-info/PKG-INFO 2023-03-12
16:09:27.000000000 +0100
+++ new/pytest-xdist-3.3.0/src/pytest_xdist.egg-info/PKG-INFO 2023-05-12
22:41:30.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytest-xdist
-Version: 3.2.1
+Version: 3.3.0
Summary: pytest xdist plugin for distributed testing, most importantly across
multiple CPUs
Home-page: https://github.com/pytest-dev/pytest-xdist
Author: holger krekel and contributors
@@ -32,6 +32,7 @@
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Requires-Python: >=3.7
+Description-Content-Type: text/x-rst
Provides-Extra: testing
Provides-Extra: psutil
Provides-Extra: setproctitle
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/src/xdist/_version.py
new/pytest-xdist-3.3.0/src/xdist/_version.py
--- old/pytest-xdist-3.2.1/src/xdist/_version.py 2023-03-12
16:09:27.000000000 +0100
+++ new/pytest-xdist-3.3.0/src/xdist/_version.py 2023-05-12
22:41:30.000000000 +0200
@@ -1,4 +1,4 @@
# file generated by setuptools_scm
# don't change, don't track in version control
-__version__ = version = '3.2.1'
-__version_tuple__ = version_tuple = (3, 2, 1)
+__version__ = version = '3.3.0'
+__version_tuple__ = version_tuple = (3, 3, 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/src/xdist/dsession.py
new/pytest-xdist-3.3.0/src/xdist/dsession.py
--- old/pytest-xdist-3.2.1/src/xdist/dsession.py 2023-03-12
16:09:12.000000000 +0100
+++ new/pytest-xdist-3.3.0/src/xdist/dsession.py 2023-05-12
22:41:10.000000000 +0200
@@ -1,3 +1,8 @@
+from __future__ import annotations
+import sys
+from enum import Enum, auto
+from typing import Sequence
+
import pytest
from xdist.remote import Producer
@@ -251,14 +256,16 @@
self._session.testscollected = len(ids)
self.sched.add_node_collection(node, ids)
if self.terminal:
- self.trdist.setstatus(node.gateway.spec, "[%d]" % (len(ids)))
+ self.trdist.setstatus(
+ node.gateway.spec, WorkerStatus.CollectionDone,
tests_collected=len(ids)
+ )
if self.sched.collection_is_completed:
if self.terminal and not self.sched.has_pending:
self.trdist.ensure_show_status()
self.terminal.write_line("")
if self.config.option.verbose > 0:
self.terminal.write_line(
- "scheduling tests via %s" %
(self.sched.__class__.__name__)
+ f"scheduling tests via {self.sched.__class__.__name__}"
)
self.sched.schedule()
@@ -345,7 +352,7 @@
if rep.failed:
self.countfailures += 1
if self.maxfail and self.countfailures >= self.maxfail:
- self.shouldstop = "stopping after %d failures" %
(self.countfailures)
+ self.shouldstop = f"stopping after {self.countfailures}
failures"
def triggershutdown(self):
self.log("triggering shutdown")
@@ -372,32 +379,51 @@
self.config.hook.pytest_runtest_logreport(report=rep)
+class WorkerStatus(Enum):
+ """Status of each worker during creation/collection."""
+
+ # Worker spec has just been created.
+ Created = auto()
+
+ # Worker has been initialized.
+ Initialized = auto()
+
+ # Worker is now ready for collection.
+ ReadyForCollection = auto()
+
+ # Worker has finished collection.
+ CollectionDone = auto()
+
+
class TerminalDistReporter:
- def __init__(self, config):
+ def __init__(self, config) -> None:
self.config = config
self.tr = config.pluginmanager.getplugin("terminalreporter")
- self._status = {}
+ self._status: dict[str, tuple[WorkerStatus, int]] = {}
self._lastlen = 0
self._isatty = getattr(self.tr, "isatty", self.tr.hasmarkup)
- def write_line(self, msg):
+ def write_line(self, msg: str) -> None:
self.tr.write_line(msg)
- def ensure_show_status(self):
+ def ensure_show_status(self) -> None:
if not self._isatty:
self.write_line(self.getstatus())
- def setstatus(self, spec, status, show=True):
- self._status[spec.id] = status
+ def setstatus(
+ self, spec, status: WorkerStatus, *, tests_collected: int, show: bool
= True
+ ) -> None:
+ self._status[spec.id] = (status, tests_collected)
if show and self._isatty:
self.rewrite(self.getstatus())
- def getstatus(self):
+ def getstatus(self) -> str:
if self.config.option.verbose >= 0:
- parts = [f"{spec.id} {self._status[spec.id]}" for spec in
self._specs]
- return " / ".join(parts)
- else:
- return "bringing up nodes..."
+ line = get_workers_status_line(list(self._status.values()))
+ if line:
+ return line
+
+ return "bringing up nodes..."
def rewrite(self, line, newline=False):
pline = line + " " * max(self._lastlen - len(line), 0)
@@ -409,37 +435,41 @@
self.tr.rewrite(pline, bold=True)
@pytest.hookimpl
- def pytest_xdist_setupnodes(self, specs):
+ def pytest_xdist_setupnodes(self, specs) -> None:
self._specs = specs
for spec in specs:
- self.setstatus(spec, "I", show=False)
- self.setstatus(spec, "I", show=True)
+ self.setstatus(spec, WorkerStatus.Created, tests_collected=0,
show=False)
+ self.setstatus(spec, WorkerStatus.Created, tests_collected=0,
show=True)
self.ensure_show_status()
@pytest.hookimpl
- def pytest_xdist_newgateway(self, gateway):
- if self.config.option.verbose > 0:
- rinfo = gateway._rinfo()
+ def pytest_xdist_newgateway(self, gateway) -> None:
+ rinfo = gateway._rinfo()
+ is_local = rinfo.executable == sys.executable
+ if self.config.option.verbose > 0 and not is_local:
version = "%s.%s.%s" % rinfo.version_info[:3]
self.rewrite(
"[%s] %s Python %s cwd: %s"
% (gateway.id, rinfo.platform, version, rinfo.cwd),
newline=True,
)
- self.setstatus(gateway.spec, "C")
+ self.setstatus(gateway.spec, WorkerStatus.Initialized,
tests_collected=0)
@pytest.hookimpl
- def pytest_testnodeready(self, node):
- if self.config.option.verbose > 0:
- d = node.workerinfo
+ def pytest_testnodeready(self, node) -> None:
+ d = node.workerinfo
+ is_local = d.get("executable") == sys.executable
+ if self.config.option.verbose > 0 and not is_local:
infoline = "[{}] Python {}".format(
d["id"], d["version"].replace("\n", " -- ")
)
self.rewrite(infoline, newline=True)
- self.setstatus(node.gateway.spec, "ok")
+ self.setstatus(
+ node.gateway.spec, WorkerStatus.ReadyForCollection,
tests_collected=0
+ )
@pytest.hookimpl
- def pytest_testnodedown(self, node, error):
+ def pytest_testnodedown(self, node, error) -> None:
if not error:
return
self.write_line(f"[{node.gateway.id}] node down: {error}")
@@ -457,3 +487,36 @@
# if --max-worker-restart was not provided, use a reasonable default
(#226)
result = config.option.numprocesses * 4
return result
+
+
+def get_workers_status_line(
+ status_and_items: Sequence[tuple[WorkerStatus, int]]
+) -> str:
+ """
+ Return the line to display during worker setup/collection based on the
+ status of the workers and number of tests collected for each.
+ """
+ statuses = [s for s, c in status_and_items]
+ total_workers = len(statuses)
+ workers_noun = "worker" if total_workers == 1 else "workers"
+ if status_and_items and all(s == WorkerStatus.CollectionDone for s in
statuses):
+ # All workers collect the same number of items, so we grab
+ # the total number of items from the first worker.
+ first = status_and_items[0]
+ status, tests_collected = first
+ tests_noun = "item" if tests_collected == 1 else "items"
+ return f"{total_workers} {workers_noun} [{tests_collected}
{tests_noun}]"
+ if WorkerStatus.CollectionDone in statuses:
+ done = sum(1 for s, c in status_and_items if c > 0)
+ return f"collecting: {done}/{total_workers} {workers_noun}"
+ if WorkerStatus.ReadyForCollection in statuses:
+ ready = statuses.count(WorkerStatus.ReadyForCollection)
+ return f"ready: {ready}/{total_workers} {workers_noun}"
+ if WorkerStatus.Initialized in statuses:
+ initialized = statuses.count(WorkerStatus.Initialized)
+ return f"initialized: {initialized}/{total_workers} {workers_noun}"
+ if WorkerStatus.Created in statuses:
+ created = statuses.count(WorkerStatus.Created)
+ return f"created: {created}/{total_workers} {workers_noun}"
+
+ return ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/src/xdist/plugin.py
new/pytest-xdist-3.3.0/src/xdist/plugin.py
--- old/pytest-xdist-3.2.1/src/xdist/plugin.py 2023-03-12 16:09:12.000000000
+0100
+++ new/pytest-xdist-3.3.0/src/xdist/plugin.py 2023-05-12 22:41:10.000000000
+0200
@@ -173,6 +173,8 @@
"one - might be useful for a small number of slow tests. "
"Larger numbers will allow the scheduler to submit consecutive "
"chunks of tests to workers - allows reusing fixtures. "
+ "Due to implementation reasons, at least 2 tests are scheduled per
"
+ "worker at the start. Only later tests can be scheduled one by
one. "
"Unlimited if not set."
),
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/testing/acceptance_test.py
new/pytest-xdist-3.3.0/testing/acceptance_test.py
--- old/pytest-xdist-3.2.1/testing/acceptance_test.py 2023-03-12
16:09:12.000000000 +0100
+++ new/pytest-xdist-3.3.0/testing/acceptance_test.py 2023-05-12
22:41:10.000000000 +0200
@@ -101,7 +101,12 @@
"""
)
result = pytester.runpytest(p1, "-v", "-d", "--tx=popen", "--tx=popen")
- result.stdout.fnmatch_lines(["*1*Python*", "*2 failed, 1 passed, 1
skipped*"])
+ result.stdout.fnmatch_lines(
+ [
+ "created: 2/2 workers",
+ "*2 failed, 1 passed, 1 skipped*",
+ ]
+ )
assert result.ret == 1
def test_n1_fail_minus_x(self, pytester: pytest.Pytester) -> None:
@@ -151,7 +156,12 @@
"""
)
result = pytester.runpytest(p1, "-d", "-v")
- result.stdout.fnmatch_lines(["*2*Python*", "*2 failed, 1 passed, 1
skipped*"])
+ result.stdout.fnmatch_lines(
+ [
+ "created: 3/3 workers",
+ "*2 failed, 1 passed, 1 skipped*",
+ ]
+ )
assert result.ret == 1
def test_dist_tests_with_crash(self, pytester: pytest.Pytester) -> None:
@@ -237,9 +247,6 @@
assert result.ret == 0
result.stdout.fnmatch_lines(
[
- "*0* *cwd*",
- # "RSyncStart: [G1]",
- # "RSyncFinished: [G1]",
"*1 passed*",
]
)
@@ -276,7 +283,11 @@
p1 = pytester.makepyfile("def test_func(): pass")
result = pytester.runpytest("-v", p1, "-d", "--tx=popen")
result.stdout.fnmatch_lines(
- ["*0*Python*", "*calculated result is 49*", "*1 passed*"]
+ [
+ "created: 1/1 worker",
+ "*calculated result is 49*",
+ "*1 passed*",
+ ]
)
assert result.ret == 0
@@ -393,14 +404,14 @@
out = result.stdout.str()
if verbosity == "-v":
assert "scheduling tests" in out
- assert "gw" in out
+ assert "1 worker [1 item]" in out
elif verbosity == "-q":
assert "scheduling tests" not in out
assert "gw" not in out
assert "bringing up nodes..." in out
else:
assert "scheduling tests" not in out
- assert "gw" in out
+ assert "1 worker [1 item]" in out
def test_pass_skip_fail(self, pytester: pytest.Pytester) -> None:
pytester.makepyfile(
@@ -1099,8 +1110,9 @@
result = pytester.runpytest(*args)
assert "test session starts" in result.stdout.str()
assert "\x1b[1m" in result.stdout.str()
- assert "gw0 [10] / gw1 [10]" in result.stdout.str()
- assert "gw0 C / gw1 C" not in result.stdout.str()
+ assert "created: 2/2 workers" in result.stdout.str()
+ assert "2 workers [10 items]" in result.stdout.str()
+ assert "collecting:" not in result.stdout.str()
def test_without_terminal_plugin(pytester, request) -> None:
@@ -1554,8 +1566,8 @@
assert result.ret == 1
result.stdout.fnmatch_lines(
[
- "gw0 I",
- "gw0 [[]0[]]",
+ "created: 1/1 worker",
+ "1 worker [[]0 items[]]",
"*_ ERROR collecting test_collection_crash.py _*",
"E assert 0",
"*= 1 error in *",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest-xdist-3.2.1/testing/test_dsession.py
new/pytest-xdist-3.3.0/testing/test_dsession.py
--- old/pytest-xdist-3.2.1/testing/test_dsession.py 2023-03-12
16:09:12.000000000 +0100
+++ new/pytest-xdist-3.3.0/testing/test_dsession.py 2023-05-12
22:41:10.000000000 +0200
@@ -1,7 +1,13 @@
-from xdist.dsession import DSession, get_default_max_worker_restart
+from __future__ import annotations
+from xdist.dsession import (
+ DSession,
+ get_default_max_worker_restart,
+ get_workers_status_line,
+ WorkerStatus,
+)
from xdist.report import report_collection_diff
from xdist.scheduler import EachScheduling, LoadScheduling,
WorkStealingScheduling
-from typing import Optional
+from typing import Sequence
import pytest
import execnet
@@ -473,7 +479,7 @@
def test_default_max_worker_restart() -> None:
class config:
class option:
- maxworkerrestart: Optional[str] = None
+ maxworkerrestart: str | None = None
numprocesses: int = 0
assert get_default_max_worker_restart(config) is None
@@ -527,3 +533,70 @@
reprec = pytester.inline_run("-n1")
reprec.assertoutcome(passed=2)
assert 0
+
+
+Created = WorkerStatus.Created
+Initialized = WorkerStatus.Initialized
+ReadyForCollection = WorkerStatus.ReadyForCollection
+CollectionDone = WorkerStatus.CollectionDone
+
+
[email protected](
+ "status_and_items, expected",
+ [
+ (
+ [],
+ "",
+ ),
+ (
+ [(Created, 0)],
+ "created: 1/1 worker",
+ ),
+ (
+ [(Created, 0), (Created, 0)],
+ "created: 2/2 workers",
+ ),
+ (
+ [(Initialized, 0), (Created, 0)],
+ "initialized: 1/2 workers",
+ ),
+ (
+ [(Initialized, 0), (Initialized, 0)],
+ "initialized: 2/2 workers",
+ ),
+ (
+ [(ReadyForCollection, 0), (Created, 0)],
+ "ready: 1/2 workers",
+ ),
+ (
+ [(ReadyForCollection, 0), (ReadyForCollection, 0)],
+ "ready: 2/2 workers",
+ ),
+ (
+ [(CollectionDone, 12), (Created, 0)],
+ "collecting: 1/2 workers",
+ ),
+ (
+ [(CollectionDone, 12), (CollectionDone, 12)],
+ "2 workers [12 items]",
+ ),
+ (
+ [(CollectionDone, 1), (CollectionDone, 1)],
+ "2 workers [1 item]",
+ ),
+ (
+ [(CollectionDone, 1)],
+ "1 worker [1 item]",
+ ),
+ # Different number of tests collected will raise an error and should
not happen in practice,
+ # but we test for it anyway.
+ (
+ [(CollectionDone, 1), (CollectionDone, 12)],
+ "2 workers [1 item]",
+ ),
+ ],
+)
+def test_get_workers_status_line(
+ status_and_items: Sequence[tuple[WorkerStatus, int]], expected: str
+) -> None:
+ assert get_workers_status_line(status_and_items) == expected