Skip to content

fix: an unguarded pyarrow import is refused under pytest -n too (#1305) - #1316

Merged
jdatcmd merged 2 commits into
mainfrom
fix/1305-xdist-capability-refusal
Oct 13, 2026
Merged

jdatcmd merged 2 commits into
mainfrom
fix/1305-xdist-capability-refusal

Conversation

@jdatcmd

@jdatcmd jdatcmd commented Oct 13, 2026

Copy link
Copy Markdown
Collaborator

Closes #1305, the gap OffgridwithJD found while reviewing #1286.

The bug

pytest_collect_file records direct imports of a declinable capability. Under xdist that hook runs in the workers, so the controller, which prints the summary and sets the exit status, never saw them. OffgridwithJD's measurement: serial, REFUSED ... rc=1; -n 2, 2 passed rc=0.

The fix

This is the second fix the issue suggested: ship the sites back, the way pgc_unrunnable already crosses the boundary.

  • A worker puts its sites in config.workeroutput["pgc_capability_imports"] in pytest_sessionfinish.
  • The controller merges them in pytest_testnodedown, keeping the first of each, since every worker collects every file. That happens before the controller's own sessionfinish sets the exit status, and its terminal summary then prints the REFUSED lines.
  • The hook is optionalhook=True, so a run without xdist loads nothing new.

Test, red first

test_an_unguarded_import_is_refused_under_xdist_too runs pytest twice as a subprocess: serial, then -n 2. It uses a stub pyarrow package and a file holding import pyarrow.parquet as pq.

  • On main: the serial premise holds, and under -n 2, got 0 want 1 for the controller naming the import.
  • Fixed: the site is named once and the -n 2 run exits non-zero.

test_capability_decline.py gives 9 passed. The guard half is 413 passed and 1 failed; the failure is test_build_refusal, the same one that fails on unmodified main on this box. TESTS.md section 91 has the row, and guard_tests is 413 → 414 by collection.

🤖 Generated with Claude Code

jdatcmd and others added 2 commits October 13, 2026 00:43
…), red

OffgridwithJD measured on #1286 that the refusal is lost under xdist: the
serial run said REFUSED and exited 1, the -n 2 run said 2 passed and exited
0, because pytest_collect_file runs in the workers. A pytester arm runs both
as subprocesses over a stub pyarrow and a file holding
'import pyarrow.parquet as pq'. Red on main: the serial premise holds, and
under -n 2 the controller names nothing (got 0 want 1).

guard_tests 413 -> 414 by collection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1305)

A worker records the sites it collected in workeroutput at session end; the
controller merges them in pytest_testnodedown, keeping the first of each
(every worker collects every file), before its own sessionfinish sets the
exit status and its terminal summary prints the REFUSED lines. The hook is
optionalhook, so a run without xdist loads nothing new.

test_capability_decline.py 9 passed; the guard half 413 passed, 1 failed
(test_build_refusal, which fails identically on unmodified main here).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@OffgridwithJD OffgridwithJD left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at d29ade6. I reproduced it with my own probe from #1286 rather than the PR's test: a stub pyarrow package on the path, and a test file holding import pyarrow.parquet as pq.

tree serial -n 2
origin/main (2f0ffc3) rc=1, REFUSED named once rc=0, nothing named (the #1305 gap)
this PR rc=1, REFUSED named once rc=1, REFUSED named once

test_capability_decline.py gives 9 passed here. Shipping the sites through workeroutput and merging them in pytest_testnodedown is the same pattern pgc_unrunnable already uses, so the boundary is crossed one consistent way.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The unguarded-pyarrow-import refusal is lost under pytest -n (xdist)

2 participants