Goal
Prevent a testing.invoke(cwd=None) call from running inside another invocation's temporary process-wide working directory.
Background
#11 serialized pairs where both invocations specify cwd. The current lock is acquired only in the cwd is not None branch. Because os.chdir() is process-global, a concurrent no-cwd invocation bypasses the lock and observes the directory temporarily selected by the other call.
Reproduction and evidence
Framework reference: 263d893 on main.
Patch CliRunner.invoke to hold the first call open, start invoke(app, cwd=tempdir), then concurrently start invoke(app).
original=/Users/rameshhp/work/base-cli
observed=<tempdir>,<tempdir>
The no-cwd call should have observed the caller's original directory, not the other test's fixture directory. Existing coverage only starts two calls that both pass cwd.
Scope
- Make all helper invocations coordinate with any process-wide cwd mutation.
- Preserve parallelism only where it cannot observe or overlap a temporary
os.chdir().
- Restore cwd on every success/failure path.
- Document the mixed-call concurrency contract.
- Add a deterministic mixed
cwd/no-cwd regression test.
Acceptance criteria
- A no-
cwd invocation cannot enter while another helper call has changed process cwd.
- Mixed calls observe their intended directories.
- The original process cwd is restored after exceptions and normal exits.
- Existing same-
cwd and invocation-parity tests pass.
Project fields
- Status: Backlog
- Priority: P2
- Area: Python
- Initiative: v1.0 Readiness
- Size: S
Ownership
Goal
Prevent a
testing.invoke(cwd=None)call from running inside another invocation's temporary process-wide working directory.Background
#11 serialized pairs where both invocations specify
cwd. The current lock is acquired only in thecwd is not Nonebranch. Becauseos.chdir()is process-global, a concurrent no-cwdinvocation bypasses the lock and observes the directory temporarily selected by the other call.Reproduction and evidence
Framework reference:
263d893onmain.Patch
CliRunner.invoketo hold the first call open, startinvoke(app, cwd=tempdir), then concurrently startinvoke(app).The no-
cwdcall should have observed the caller's original directory, not the other test's fixture directory. Existing coverage only starts two calls that both passcwd.Scope
os.chdir().cwd/no-cwdregression test.Acceptance criteria
cwdinvocation cannot enter while another helper call has changed process cwd.cwdand invocation-parity tests pass.Project fields
Ownership