Skip to content

Commit

Permalink
Use execnet main_thread_only execmodel
Browse files Browse the repository at this point in the history
Use the execnet main_thread_only execmodel so that code which expects
to run in the main thread will just work.  This execmodel has been
merged to the execnet master branch via pytest-dev/execnet#243, so this
patch should not be merged until there is a released version of execnet
supporting the main_thread_only execmodel.

Also increase minimum python version to 3.8 since execnet dropped 3.7
support in pytest-dev/execnet#245.

Closes: pytest-dev#620
  • Loading branch information
zmedico committed Feb 25, 2024
1 parent f57c658 commit 61c0a8f
Show file tree
Hide file tree
Showing 8 changed files with 17 additions and 12 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ jobs:
fail-fast: false
matrix:
tox_env:
- "py37-pytestlatest"
- "py38-pytestlatest"
- "py39-pytestlatest"
- "py310-pytestlatest"
Expand All @@ -46,8 +45,6 @@ jobs:

os: [ubuntu-latest, windows-latest]
include:
- tox_env: "py37-pytestlatest"
python: "3.7"
- tox_env: "py38-pytestlatest"
python: "3.8"
- tox_env: "py39-pytestlatest"
Expand Down
3 changes: 3 additions & 0 deletions changelog/620.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Use the execnet main_thread_only execmodel so that code which expects to run in the main thread will just work.

Also increase minimum python version to 3.8 since execnet dropped 3.7 support in pytest-dev/execnet#245.
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,15 @@ classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"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",
"Programming Language :: Python :: 3.12",
]
requires-python = ">=3.7"
requires-python = ">=3.8"
dependencies = [
"execnet>=1.1",
"execnet@git+https://github.com/pytest-dev/execnet#egg=master",
"pytest>=6.2.0",
]
dynamic = ["version"]
Expand Down
2 changes: 1 addition & 1 deletion src/xdist/looponfail.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def trace(self, *args):
print("RemoteControl:", msg)

def initgateway(self):
return execnet.makegateway("popen")
return execnet.makegateway("execmodel=main_thread_only//popen")

def setup(self, out=None):
if out is None:
Expand Down
8 changes: 7 additions & 1 deletion src/xdist/workermanage.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ def __init__(self, config, specs=None, defaultchdir="pyexecnetcache") -> None:
self.testrunuid = self.config.getoption("testrunuid")
if self.testrunuid is None:
self.testrunuid = uuid.uuid4().hex
self.group = execnet.Group()
self.group = execnet.Group(execmodel="main_thread_only")
if specs is None:
specs = self._getxspecs()
self.specs = []
for spec in specs:
if not isinstance(spec, execnet.XSpec):
spec = execnet.XSpec(spec)
if getattr(spec, "execmodel", None) != "main_thread_only":
spec = execnet.XSpec(f"execmodel=main_thread_only//{spec}")
if not spec.chdir and not spec.popen:
spec.chdir = defaultchdir
self.group.allocate_id(spec)
Expand All @@ -68,6 +70,10 @@ def setup_nodes(self, putevent):
return [self.setup_node(spec, putevent) for spec in self.specs]

def setup_node(self, spec, putevent):
if not isinstance(spec, execnet.XSpec):
spec = execnet.XSpec(spec)
if getattr(spec, "execmodel", None) != "main_thread_only":
spec = execnet.XSpec(f"execmodel=main_thread_only//{spec}")
gw = self.group.makegateway(spec)
self.config.hook.pytest_xdist_newgateway(gateway=gw)
self.rsync_roots(gw)
Expand Down
2 changes: 1 addition & 1 deletion testing/test_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __init__(self, request, pytester: pytest.Pytester) -> None:
def setup(self) -> None:
self.pytester.chdir()
# import os ; os.environ['EXECNET_DEBUG'] = "2"
self.gateway = execnet.makegateway()
self.gateway = execnet.makegateway("execmodel=main_thread_only//popen")
self.config = config = self.pytester.parseconfigure()
putevent = self.events.put if self.use_callback else None

Expand Down
4 changes: 2 additions & 2 deletions testing/test_workermanage.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def test_popen_makegateway_events(
assert len(call.specs) == 2

call = hookrecorder.popcall("pytest_xdist_newgateway")
assert call.gateway.spec == execnet.XSpec("popen")
assert call.gateway.spec == execnet.XSpec("execmodel=main_thread_only//popen")
assert call.gateway.id == "gw0"
call = hookrecorder.popcall("pytest_xdist_newgateway")
assert call.gateway.id == "gw1"
Expand Down Expand Up @@ -162,7 +162,7 @@ def test_hrsync_filter(self, source: Path, dest: Path) -> None:
assert names == {"dir", "file.txt", "somedir"}

def test_hrsync_one_host(self, source: Path, dest: Path) -> None:
gw = execnet.makegateway("popen//chdir=%s" % dest)
gw = execnet.makegateway("execmodel=main_thread_only//popen//chdir=%s" % dest)
finished = []
rsync = HostRSync(source)
rsync.add_target_host(gw, finished=lambda: finished.append(1))
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tox]
envlist=
linting
py{37,38,39,310,311,312}-pytestlatest
py{38,39,310,311,312}-pytestlatest
py310-pytestmain
py310-psutil
py310-setproctitle
Expand Down

0 comments on commit 61c0a8f

Please sign in to comment.