Atlas debugs a single failing Python test by running that one test in isolation with pytest through the bash tool, reading the assertion and the module it exercises, walking the call path with the lsp tool's goToDefinition and findReferences operations, and only then editing. Because bash is a real shell, every lever you would reach for by hand is available: a -k filter to shrink the output, a verbose flag to see the full comparison, temporary logging added with edit. The goal is to fix the production code in your package, not to soften the assertion in tests/ until it stops complaining.
How do you debug one failing pytest test without drowning in output?
Run the 1 failing test, not the suite. Atlas invokes pytest through the bash tool with the framework's filter flag, for example pytest -k test_refund_partial or the exact node ID tests/test_orders.py::test_refund_partial, so the output is small enough for a model and a human to actually reason about.
A full pytest run against a Django or FastAPI codebase can produce thousands of lines, and a single failure buried in that is genuinely harder to understand than the same failure in isolation. Atlas narrows first. The bash tool runs a real shell, so the ordinary pytest filters are all available: -k for a substring selector, a node ID for one exact test, and a verbose flag when the assertion comparison has been elided into a diff too short to read. The narrowed run gives you the traceback, the assert line, and the actual versus expected values, and that is the entire input to the next step. Narrowing is also fast, which matters more than it sounds: a debugging loop that takes four seconds gets iterated ten times, and a loop that takes four minutes gets iterated twice and then guessed at.
How does Atlas find why a Python test fails, not just where?
Atlas reads the failing test and the module it exercises, then uses 2 lsp operations, goToDefinition and findReferences, to walk the call path. In a Python package that means following the assertion in tests/test_orders.py down through app/services/refunds.py into whatever helper actually produced the wrong number.
The traceback tells you where Python raised, which is often several frames away from where the logic went wrong. A refund that comes back as 1200 instead of 1000 raises inside an assert in the test, but the mistake lives in a rounding helper three calls down. Atlas walks that distance with the language server rather than by guessing at imports. goToDefinition jumps from the call in app/services/refunds.py to the definition of the helper. findReferences shows every other caller of that helper, which is how you learn whether the bug is local or whether five other code paths have been quietly wrong for months. Atlas's index parses AST declarations with tree-sitter, so codebase_search complements the language server when the relevant code is not reachable by an import chain, for instance a signal handler or a registered plugin.
Can Atlas add temporary logging to debug a Python test?
Yes, and in 2026 Atlas forms a hypothesis and checks it, adding temporary logging with the edit tool or re-running with a verbose flag through bash. Because the bash tool is a real shell, the debugging levers a Python developer uses by hand are all available inside the session, and Atlas removes the logging before the change is committed.
Hypothesis-driven debugging beats staring. If Atlas suspects the rounding helper in app/services/refunds.py receives a Decimal where the test supplies a float, the way to find out is to print the type at the boundary and re-run pytest -k on the one failing test. Atlas adds the print or log line with edit, runs the narrowed pytest command through bash, reads the answer, and then removes the instrumentation. Every one of those edits is surfaced as a unified diff before writing, and Atlas snapshots file changes as git patches, so temporary instrumentation is easy to strip and impossible to forget silently: git status shows it. The final step of the documented workflow is explicit about it. Re-run the single test, then the full suite, and remove any temporary logging you added.
How does Atlas fix Python code without rewriting the whole module?
Atlas fixes the production code with the edit tool, and when a Python change spans several hunks, for example a signature change in app/services/refunds.py plus its 2 call sites, Atlas uses apply_patch instead of chaining brittle edits that shift each other's context out from under them.
The temptation, once the root cause is understood, is to rewrite the module cleanly. Resist it while debugging. The change that fixes the bug should be the smallest change that fixes the bug, because that is the change a reviewer can evaluate and a bisect can find later. Atlas's edit tool encourages that scale: it requires an exact-enough oldString and refuses ambiguous multi-match replacements, which in a Python file full of similar-looking return statements is a real protection. apply_patch handles genuinely multi-hunk changes as one unit. Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, and Atlas computes a unified diff for every file edit and surfaces it for approval, so the fix in app/services/refunds.py is read before it lands. Run ruff format on the changed files afterwards.
What do you run after fixing a failing Python test?
Re-run the single test first, then the whole suite. Atlas re-runs pytest -k on the exact failing test to confirm the green, then runs the full pytest suite to check that fixing the refund rounding did not break the 11 other tests that call the same helper in app/services/refunds.py.
The narrow re-run proves the fix addresses the reported failure. The full run proves the fix did not create three new ones, which happens constantly when the buggy behavior had accidental dependents, and findReferences already warned you that eleven other callers exist. Atlas's bash tool truncates output over 2000 lines or 50 KB and saves the complete log to a file it can read, so a large pytest run after the fix stays triageable. Then the cleanup: remove the temporary logging, run ruff format on the touched files, and check the diff. Atlas reads git branches, status, and diffs, and can stage and create commits on your behalf, so the fix in app/services/refunds.py goes in as a reviewable change with the failing test that motivated it. If the dependency resolution itself turned out to be the culprit, uv is where that gets sorted.
Step by step
- 01Run just the failing test with the bash tool, using pytest -k or the exact node ID such as tests/test_orders.py::test_refund_partial, so the output stays small.
- 02Re-run with a verbose flag through bash when the assertion comparison is elided, so the actual and expected values are fully visible.
- 03Read the test and the Python module it exercises, for example tests/test_orders.py and app/services/refunds.py.
- 04Walk the call path with the lsp tool's goToDefinition operation, and use findReferences to see every other caller of the suspect helper.
- 05Form a hypothesis and check it: add temporary logging with the edit tool, then re-run the narrowed pytest command through bash.
- 06Fix the production code with edit; if the change spans several hunks, use apply_patch instead of chaining brittle edits.
- 07Re-run the single test to confirm the green, then run the full pytest suite to catch collateral damage among the other callers.
- 08Remove any temporary logging you added, run ruff format on the changed files, and review the diff before committing.
Frequently asked questions
- How do I debug a single failing pytest test with an AI agent?
- Run it in isolation. Atlas invokes pytest through the bash tool with a -k filter or the exact node ID, reads the assertion and the module under test, walks the call path with the lsp tool's goToDefinition operation, and edits the production code.
- Can Atlas follow a Python call path from a test assertion to the real bug?
- Yes. Atlas uses the lsp tool's goToDefinition to jump from a call in app/services/refunds.py to the helper's definition, and findReferences to list every other callsite, which reveals whether the bug affects code paths beyond the failing test.
- Will an AI coding agent just change the assertion to make my test pass?
- Atlas's documented workflow is to fix the code, not the assertion. Every edit is surfaced as a unified diff for approval before writing, so a change to tests/test_orders.py is visible rather than silent, and the fix belongs in the Python module under app/.
- Can Atlas add print statements or logging while debugging Python?
- Yes. Atlas adds temporary logging with the edit tool and re-runs the narrowed pytest command through bash, which is a real shell. The final workflow step is explicit about removing any temporary logging once the fix is confirmed.
- Should I use edit or apply_patch for a Python fix that touches several places?
- Use apply_patch when the change spans several hunks, for example a signature change in app/services/refunds.py plus its call sites. Chained edit calls are brittle because each replacement shifts the context the next one is matching against.
- What does Atlas run after fixing the failing Python test?
- Atlas re-runs the single test to confirm the green, then the full pytest suite to catch collateral damage among other callers, then ruff format on the changed files. Output over 2000 lines or 50 KB is truncated with the full log saved to a readable file.
- Is it safe to let Atlas run pytest and edit my Python package?
- Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, including the bash tool that invokes pytest. Atlas also computes a unified diff for every file edit and snapshots changes as git patches so edits can be rolled back.
Try Atlas in your terminal
The terminal-native AI coding agent. Free core, single binary.
Install AtlasRelated guides
Debug a Single Failing Test with Atlas in 2026
How to debug one failing test with Atlas in 2026: run it in isolation with bash, walk the call graph with the lsp tool, and fix the code, not the assertion.
Atlas for Python in 2026
Atlas is a terminal-native AI coding agent for Python in 2026. Run it in a repo with a pyproject.toml or requirements.txt and review every diff before it lands.
Automate GitHub Issue and Pull Request Triage in Python with Atlas (2026)
Wire the atlas github command into a Python repo's workflow in 2026. Require MODEL in provider/model form, gate on write permission, and verify with pytest and ruff format.
Upgrade Python Dependencies and Fix Breakage with Atlas in 2026
In 2026, Python developers use Atlas to upgrade dependencies like Django or FastAPI, automatically fixing compile and test failures with `uv`, `pytest`, and `ruff format`.
Add a Regression Test for a Bug Fix in Python with Atlas (2026)
Red first, then green. Atlas writes a failing pytest case, proves it fails with the bash tool exit code, applies the fix with edit, and re-runs the same command.
Write Unit Tests for Untested Python Code with Atlas (2026)
Atlas enumerates a Python module with the lsp tool, copies your existing pytest conventions, writes the test file, and actually runs pytest with the bash tool.
Onboard to an Unfamiliar Python Codebase with Atlas in 2026
Onboard to an unfamiliar Python codebase in 2026. Atlas uses codebase_search, glob, read, and lsp to map a pyproject.toml repo without opening every module.
Self-Review Your Working Diff Before Committing in Python With Atlas (2026)
How to self-review a Python working diff before committing with Atlas in 2026: read the whole diff, grep for leftover breakpoints, then run pytest and ruff format.