Get started¶
Run the smallest useful reproduction¶
Install metapathology in the environment that runs the failing program:
Run a script:
Run a module:
For scripts, metapathology sets sys.argv and puts the script directory at the
front of sys.path, matching a normal Python script launch. Module execution
uses Python's runpy, so the
usual __main__ metadata differences
and Windows multiprocessing caveats apply.
Installation also provides a metapathology command. Prefer
python -m metapathology when interpreter selection matters; it guarantees
that the monitor and target use the same Python and virtual environment.
Run without a target to open a monitored interactive interpreter:
The interactive session preloads metapathology, so
print(metapathology.render_report()) shows progress before exit. It uses
code.interact(),
not the enhanced Python 3.13+ REPL.
Tool options must come before the target. Everything after the target is passed to it.
The target's integer SystemExit status is preserved. An unhandled exception
prints its traceback and exits with status 1. The report is written in both
cases.
If restarting the program under the wrapper is impractical, CPython 3.14+ can attach to a running same-user process.
Save the report¶
With no report option, text is written to standard error. --report infers the
format from .txt or .json and can be repeated:
Use --report-text PATH or --report-json PATH when a filename has no useful
extension. - means standard error. File writes are atomic.
Both files describe the same captured run, so their event references match.
Read only the useful parts¶
Read the report in this order:
- Target outcome and verdict.
- Numbered problems and risks.
- Finder-result comparisons for affected modules.
- Event timeline and state-change stacks when the finding needs proof.
Notes are context, not failures. A custom finder result is also context unless it is connected to an observed effect.
Add evidence only when needed¶
Default capture is designed for the first pass. If the report says the missing evidence requires detailed capture, rerun with:
Detailed capture is slower and wraps more of the import machinery. Prefer one specific option when you know what is missing, for example:
See Choosing capture for the decision table.
Invoke skipped candidates only in a disposable run¶
If the report shows a skipped candidate and you still need its live answer, rerun the smallest reproduction with:
Run it only in a disposable process or container. It executes skipped third-party code, and side effects cannot be rolled back. Read the result as “what it returned now,” not “what would have won.” See Choosing capture.
Stop after the relevant operation¶
Long-lived processes retain events until reporting. If the CLI wrapper is not a good fit, scope capture in code:
import metapathology
with metapathology.monitoring() as monitor:
reproduce_problem()
metapathology.write_report("diagnosis.json", format="json")
The context manager restores import state when it owns the installation.