Typical pytest usage looks like this:
def test_clone(cmd_mox):
cmd_mox.mock("git").with_args("clone", "repo").returns(exit_code=0)
my_tool.clone_repo("repo")
# No explicit replay() or verify() calls required.
The context manager interface is available when pytest fixtures are not in play:
with CmdMox() as mox:
mox.stub("ls").returns(stdout="")
mox.replay()
subprocess.run(["ls"], check=True)
If replay aborts—whether because your code raised an exception or you hit
Ctrl+C—CmdMox still tears down the environment before surfacing the original
error. The controller catches interruptions during replay startup, stops the
IPC server, removes the shim directory (and its socket), and restores PATH
before re-raising so you never leak temporary artefacts between tests.