DEV Community

Deva
Deva

Posted on

One kwarg made my parallel CI phase gate fixtures order independent

Two phases, one parallel cluster, one AttributeError. That is the whole setup.

Here is the context. My CI runs phase gates where each gate gets a fresh git worktree branched from the integration branch at that moment. P1 adds a config constant called WARMUP_ENABLED. P2 adds a pytest conftest fixture that monkeypatches that constant to False in tests. Both ship in the same parallel cluster, C1.

The problem: the P2 gate worktree branches off integration before P1 has merged. conftest.py exists in the worktree because P2 wrote it. WARMUP_ENABLED does not exist in config because P1 has not landed yet. monkeypatch.setattr on a missing attribute raises AttributeError by default. The suite blows up.

The fix is one argument:

monkeypatch.setattr(config, "WARMUP_ENABLED", False, raising=False)
Enter fullscreen mode Exit fullscreen mode

With raising=False, monkeypatch creates the attribute if it does not exist instead of raising. The fixture now runs correctly whether WARMUP_ENABLED is already defined in config or not.

The tradeoff worth naming: raising=False will silently create an attribute that does not exist. That is usually the right behavior for a setup fixture, but it also means a typo in the attribute name will not blow up at fixture time. You will not get AttributeError telling you the attribute is missing. You will set a new attribute nobody reads, your tests will pass, and the real config constant stays at whatever it defaulted to. The mitigation I use: keep the constant name short, keep it in one place, and verify the name matches when the real phase lands.

The deeper problem is architectural. Parallel phase gates that branch off the same integration branch are inherently sensitive to ordering when tasks share logical dependencies. If P2's conftest depends on P1's constant, the clean answer is to put them in the same phase or gate P2 after P1. I did not do that here because the dependency runs one way and is shallow. P2 does not need WARMUP_ENABLED to exist at test runtime; it just needs to be able to patch it. raising=False is the correct local fix for exactly that shape of coupling. It is not a workaround; it is the semantics matching the intent.

What I would do differently: add one line of comment on that monkeypatch call explaining why raising=False is there. Something like: # raising=False because this constant may not exist yet in parallel gate worktrees. Future me reading that line three months from now should not have to reconstruct this entire commit message to understand it. The code is correct. The code without the comment is a trap.

Top comments (0)