Skip to content

Commit

Permalink
Revert psutil dependency and introduce pytest_xdist_auto_num_workers …
Browse files Browse the repository at this point in the history
…hook

This reverts the behavior we had before psutil was a hard dependency, but
opens up the possibility of customization through the
pytest_xdist_auto_num_workers hook, making things like pytest-dev#477 possible.

Fix pytest-dev#585
  • Loading branch information
nicoddemus committed Aug 24, 2020
1 parent e469fc7 commit fb140e2
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 8 deletions.
1 change: 1 addition & 0 deletions changelog/585.feature.rst
@@ -0,0 +1 @@
New ``pytest_xdist_auto_num_workers`` hook can be implemented by plugins or ``conftets.py`` to control the number of workers when ``--numprocesses=auto`` is given in the command-line.
7 changes: 7 additions & 0 deletions changelog/585.trivial.rst
@@ -0,0 +1,7 @@
``psutil`` is no longer a dependency, as it has proven to make ``pytest-xdist`` installation in certain platforms and containers problematic.

To those interested to continue to use ``psutil`` to detect the number of CPUs, the new ``pytest_xdist_auto_num_cpus`` hook can be used in the root ``conftest.py`` file of the project::

def pytest_xdist_auto_num_workers(config):
import psutil
return psutil.cpu_count(logical=False)
10 changes: 10 additions & 0 deletions src/xdist/newhooks.py
Expand Up @@ -55,3 +55,13 @@ def pytest_xdist_node_collection_finished(node, ids):
@pytest.mark.firstresult
def pytest_xdist_make_scheduler(config, log):
""" return a node scheduler implementation """


@pytest.mark.firstresult
def pytest_xdist_auto_num_workers(config):
"""
Return the number of workers to spawn when ``--numprocesses=auto`` is given in the
command-line.
.. versionadded:: 2.1
"""
13 changes: 5 additions & 8 deletions src/xdist/plugin.py
Expand Up @@ -5,7 +5,7 @@
import pytest


def auto_detect_cpus():
def pytest_xdist_auto_num_workers():
try:
from os import sched_getaffinity
except ImportError:
Expand All @@ -28,13 +28,9 @@ def cpu_count():
return n if n else 1


class AutoInt(int):
"""Mark value as auto-detected."""


def parse_numprocesses(s):
if s == "auto":
return AutoInt(auto_detect_cpus())
return "auto"
elif s is not None:
return int(s)

Expand Down Expand Up @@ -187,12 +183,13 @@ def pytest_configure(config):
@pytest.mark.tryfirst
def pytest_cmdline_main(config):
usepdb = config.getoption("usepdb", False) # a core option
if isinstance(config.option.numprocesses, AutoInt):
if config.option.numprocesses == "auto":
if usepdb:
config.option.numprocesses = 0
config.option.dist = "no"
else:
config.option.numprocesses = int(config.option.numprocesses)
auto_num_cpus = config.hook.pytest_xdist_auto_num_workers(config=config)
config.option.numprocesses = auto_num_cpus

if config.option.numprocesses:
if config.option.dist == "no":
Expand Down
16 changes: 16 additions & 0 deletions testing/test_plugin.py
Expand Up @@ -51,6 +51,7 @@ def test_auto_detect_cpus(testdir, monkeypatch):
assert config.getoption("numprocesses") == 2

config = testdir.parseconfigure("-nauto")
check_options(config)
assert config.getoption("numprocesses") == 99

config = testdir.parseconfigure("-nauto", "--pdb")
Expand All @@ -62,9 +63,24 @@ def test_auto_detect_cpus(testdir, monkeypatch):
monkeypatch.delattr(os, "sched_getaffinity", raising=False)
monkeypatch.setenv("TRAVIS", "true")
config = testdir.parseconfigure("-nauto")
check_options(config)
assert config.getoption("numprocesses") == 2


def test_hook_auto_num_workers(testdir, monkeypatch):
from xdist.plugin import pytest_cmdline_main as check_options

testdir.makeconftest(
"""
def pytest_xdist_auto_num_workers():
return 42
"""
)
config = testdir.parseconfigure("-nauto")
check_options(config)
assert config.getoption("numprocesses") == 42


def test_boxed_with_collect_only(testdir):
from xdist.plugin import pytest_cmdline_main as check_options

Expand Down

0 comments on commit fb140e2

Please sign in to comment.