Repository navigation
Description
Overview
test_autoarray writes test output into tracked paths, so any change to the
autonerves FITS writer rewrites a committed binary and dirties the tree for every
contributor. This was demonstrated on PyAutoArray#483, where the PyAutoNerves#155
header-comment fix ([""] -> "") silently modified
test_autoarray/structures/arrays/files/array/output_test/array.fits the moment the
autonerves floor moved — identical cards, values, data and byte size, but a modified
tracked file that had to be committed into an unrelated PR.
The convention to prevent this already exists and was applied inconsistently:
.gitignore names two individual generated files rather than the pattern. This task
applies the durable fix (pytest's tmp_path) uniformly, so no test writes into the
source tree at all, and untracks the 13 exposed artifacts.
Audit correction to the original prompt. Of the 13 tracked files, only one is a
live output — structures/arrays/files/array/output_test/array.fits, the file #483
flipped. The other 12 are orphans: no test in the repo references their paths, and a
repo-wide grep for their basenames returns nothing. They are residue from tests that were
since deleted (the two .gitignore lines are gravestones for one such test). The prompt's
open question about test_uniform_1d.py:12 resolves the same way: that path is written,
not read — no file in the set is a real input.
Plan
- Convert every
output_testwriter to pytest'stmp_path— the prompt's preferred,
durable fix — so no test writes into the source tree. - Delete the one live tracked artifact and the twelve orphans, untracking all thirteen.
- Replace the two file-by-file
.gitignorelines with one directory pattern as a backstop
against a future writer regressing this. - Remove a dead
test_data_pathfixture in the imaging tests that no test requests. - Verify from a clean checkout: full suite twice in a row,
git statusclean after each. - Check PyAutoGalaxy/PyAutoLens for the same pattern and file separately — do not widen
this PR.
Detailed implementation plan
Work Classification
Library
Affected Repositories
- PyAutoArray (primary)
Branch Survey
| Repository | Current Branch | Dirty? |
|---|---|---|
| ./PyAutoArray | main | clean |
Suggested branch: feature/untrack-fits-test-artifacts
Worktree root: ~/Code/PyAutoLabs-wt/untrack-fits-test-artifacts/
Inventory: what is actually tracked
| Tracked path | Written by | Verdict |
|---|---|---|
structures/arrays/files/array/output_test/array.fits |
test_uniform_2d.py:208 and test_uniform_1d.py:166 (same dir; both rmtree it) |
live output |
dataset/files/array/output_test/noise_map.fits |
— | orphan |
dataset/files/arrays/output_test/{background_noise_map,background_sky_map,exposure_time_map,image,noise_map,poisson_noise_map,psf}.fits |
— | orphan (7 files) |
structures/arrays/files/output_test/{array,masked_array}.fits, values_test.dat |
— | orphan (3 files) |
structures/arrays/files/values/output_test/values_test.dat |
— | orphan |
Only six test modules reference output_test at all; four already resolve into
.gitignored directories (mask/files/array/, dataset/{imaging,interferometer}/files/array/).
Two extras the audit turned up:
structures/test_visibilities.pywritesstructures/files/output_test/data.fits—
untracked and un-ignored, so it dirties the tree as an untracked file today.dataset/imaging/test_dataset.py:16-25defines atest_data_pathfixture that no test
ever requests — dead code shadowing the module-level constant.
Implementation Steps
-
Convert writers to
tmp_path. In each, drop theshutil.rmtree/os.makedirs
preamble and write totmp_path / <name>, reading back from the same path. Inputs keep
reading from their committedfiles/fixtures.test_autoarray/structures/arrays/test_uniform_2d.py—
test__output_to_fits__3x3_ones__fits_file_has_ones_and_correct_pixel_scale_header
(lines 194-216).test_autoarray/structures/arrays/test_uniform_1d.py— the output test at lines
~158-176; also delete the module-leveltest_data_pathconstant (line 12). Leave
create_fits/clean_fits/fits_pathalone — those targetfiles/array_1d, a
separate concern.test_autoarray/structures/test_visibilities.py—test__output_to_fits(lines 89-111).test_autoarray/mask/test_mask_2d.py—
test__from_fits__output_to_fits__roundtrip_preserves_values_pixel_scales_and_header
(lines 410-440).test_autoarray/dataset/interferometer/test_dataset.py—test__output_all_arrays
(lines 130-168): keep the firsttest_data_path(inputfiles/), replace the rebound
output path withtmp_path.test_autoarray/dataset/imaging/test_dataset.py— delete the unused
make_test_data_pathfixture (lines 16-25).
Prune
import os/import shutilonly where they become genuinely unused. -
Untrack and delete the 13 files (
git rm, not--cached— nothing reads them), then
remove the five emptiedoutput_test/directories and any parent left empty
(dataset/files/arrays/,structures/arrays/files/values/). -
.gitignore— delete the two individual lines
(test_autoarray/dataset/files/array/output_test/{uv_wavelengths,visibilities}.fits) and
add one pattern in their place:# Test output: tests write into output_test/ dirs; never track the results test_autoarray/**/output_test/This also covers
structures/files/output_test/from the visibilities test. It is a
backstop only — after step 1 no test should write into the tree at all. -
Verify.
source activate.shthenpython3 -m pytest -q -n autofrom a clean
checkout, run twice in a row, assertinggit status --porcelainempty after each. The
second run is what catches a test that silently depended on a committed artifact — it
would fail on run 1, not run 2. -
Siblings. Grep PyAutoGalaxy/PyAutoLens for the same pattern and route findings through
/intakeas separate prompts. No changes to those repos in this PR.
Key Files
test_autoarray/structures/arrays/test_uniform_2d.py— writer of the one live tracked artifacttest_autoarray/structures/arrays/test_uniform_1d.py— second writer of the same directorytest_autoarray/structures/test_visibilities.py— writer of the untracked-but-un-ignored artifacttest_autoarray/mask/test_mask_2d.py— writer into an already-ignored directorytest_autoarray/dataset/interferometer/test_dataset.py— writer into an already-ignored directorytest_autoarray/dataset/imaging/test_dataset.py— deadtest_data_pathfixture.gitignore— the two file-by-file lines replaced by the directory pattern
Trade-offs
tmp_pathover a.gitignore-only fix is the prompt's own preference and the only option
that stops tests writing into the source tree; it costs six small test edits. It also
removes an existing ordering hazard, sincetest_uniform_1dandtest_uniform_2dcurrently
rmtreethe same shared directory.- Deleting the 12 orphans is beyond the prompt as written. They are provably dead, they are
the same defect's accumulated residue, and leaving them would mean a second PR for one
git rm.
Original Prompt
Click to expand starting prompt
Untrack the generated FITS test artifacts in autoarray
Type: maintenance
Target: libraries
Repos:
- @PyAutoArray
Difficulty: small
Autonomy: supervised
Priority: medium
Status: formalised
Filed: 2026-08-22 (backfilled from git)
Filed 2026-08-23 from the PyAutoArray#482/#483 floor bump, which tripped over
this. Not a bug — a git-hygiene defect that converts unrelated upstream changes
into binary diffs.
The defect
test_autoarray writes test output into tracked paths. The tests rmtree
the directory, recreate it, write a FITS, and read it back — the file is never an
input expectation, yet it is committed. So any change to the autonerves FITS
writer rewrites a tracked binary and dirties the tree for every contributor.
Demonstrated on #483: the PyAutoNerves#155 header-comment fix ([""] -> "")
silently changed test_autoarray/structures/arrays/files/array/output_test/array.fits
the moment the autonerves floor moved to a release carrying it —
HEAD : PIXSCAY = 1.0 / ['']
WORKING : PIXSCAY = 1.0
— identical cards, values, data and byte size, but a modified tracked file that
had to be either committed into an unrelated PR or left dirtying the tree. It
was committed there; that was the least-bad option, not a good one.
Why this is worth fixing rather than absorbing
The convention already exists and is applied inconsistently. .gitignore
lines 9-10 name two individual generated files:
test_autoarray/dataset/files/array/output_test/uv_wavelengths.fits
test_autoarray/dataset/files/array/output_test/visibilities.fits
so someone already hit this and patched the two files in front of them rather
than the pattern. 13 tracked files across five output_test/ directories are
still exposed:
test_autoarray/dataset/files/array/output_test/noise_map.fits
test_autoarray/dataset/files/arrays/output_test/{background_noise_map,background_sky_map,
exposure_time_map,image,noise_map,poisson_noise_map,psf}.fits
test_autoarray/structures/arrays/files/array/output_test/array.fits
test_autoarray/structures/arrays/files/output_test/{array,masked_array}.fits
test_autoarray/structures/arrays/files/output_test/values_test.dat
test_autoarray/structures/arrays/files/values/output_test/values_test.dat
Writers: structures/arrays/test_uniform_2d.py:201-211,
structures/test_visibilities.py:96-107, mask/test_mask_2d.py:417,
dataset/interferometer/test_dataset.py:140, dataset/imaging/test_dataset.py:18,
structures/arrays/test_uniform_1d.py:12.
Suggested scope
- Pick one of the two fixes and apply it uniformly — do not patch
file-by-file again:tmp_path(preferred): the tests already rmtree/recreate their output
dir, so pytest'stmp_pathfixture is a near-drop-in and removes the
tracked path entirely. This is the durable fix..gitignorethe directories (test_autoarray/**/output_test/) plus
git rm --cachedthe 13 files, if converting the tests is judged too wide.
Cheaper, but leaves the tests writing into the source tree.
- Confirm each candidate file is genuinely output before untracking it. The
inventory above was read off the writers, but
structures/arrays/test_uniform_1d.py:12reads from anoutput_testpath —
check whether it consumes a file another test produced (ordering dependency)
or a committed one. If any file is a real input, it is not in scope and should
be moved out ofoutput_test/instead. - Verify the suite passes from a clean checkout and twice in a row (a test
that silently depended on a committed artifact will fail on the first run
after untracking, not the second). - Leave the sibling repos alone. PyAutoGalaxy/PyAutoLens likely share the
pattern; check, and file separately rather than widening this.
Note
The equivalent problem in the workspaces was solved differently — an autouse
conftest fixture per repo (see complete/2026/08/small-datasets-regime-stamp.md,
"Committed FITS fixtures became regime-DEPENDENT"). That solved regime
dependence of fixtures that are genuinely inputs. This is the different case:
files that are outputs and should not be tracked at all.
Activity
Jammy2211 commentedon Aug 27, 2026
Library PR Created
PR: #495 (
pending-release)Branch:
feature/untrack-fits-test-artifacts· 20 files, +48 / -106Implemented as planned, with the
tmp_pathoption. After a full run nooutput_test/directory is created anywhere in the source tree — the tests write only into pytest's
per-test temp dirs, so the defect is closed at the source rather than masked by an ignore rule.
Gate: 1177 passed, 55 skipped — identical to the pre-change baseline on
main. Run from aclean checkout, twice in a row, with
git status --porcelainasserted unchanged after each.PyAutoHeart is not reachable from this session, so the readiness gate ran through the documented
fallback (per-repo suite, any failure treated as RED).
Two corrections to the plan above
The imaging
test_data_pathfixture was not dead code. The plan called it "neverrequested" and proposed deleting it. That was wrong — three tests take it
(
test__from_fits__small_datasets_env_caps_data_and_noise_map,..._env_unset__shape_unchanged,test__output_to_fits__round_trips_data_psf_noise_map_correctly);my grep of its usages had been truncated. Deleting it outright broke them, which the first
verification run caught. Those three now take
tmp_pathinstead, which is the same outcome theplan wanted — they were writing generated FITS into the source tree through that fixture — but
reached properly rather than by removing a live fixture.
structures/files/output_test/data.fitswas already ignored. The plan claimed it was"untracked and un-ignored, so it dirties the tree as an untracked file today". It is in fact
covered by a nested
test_autoarray/structures/files/.gitignorecontaining*. Convertingtest_visibilities.pytotmp_pathis still right, but that file was never leaking. Worthnoting that this nested
*is a third inconsistent convention in the repo alongside thefile-by-file lines and the directory lines — not in scope here, just visible from the audit.
Neither changes the shape of the diff.
Sibling repos — checked, not widened
output_test/anywhere, zero tracked test-output artifacts, and aglobal
data_temp/in.gitignorecovering every write path. Nothing to do.output_test/and zero tracked artifacts either, so this defect isautoarray-only. It does have a smaller, different one: its tests write to
test_autolens/{imaging,interferometer}/data_temp/, but.gitignorecovers only theintegration/copies, so those paths are not ignored. The testsrmtreeon success, whichhides it on the happy path; a failing or interrupted run leaves the artifacts as untracked files.
Filed separately as
PyAutoMind/draft/maintenance/libraries/autolens_data_temp_not_ignored.mdrather than mixed into this PR.
Merge is a human call — the PR is open and awaiting review.
Generated by Claude Code
Jammy2211 commentedon Aug 27, 2026
Shipped
Merged: #495 →
mainasa5d718eAll three CI legs green on
3dea5bc(unittest 3.12,unittest 3.13,unittest-nojax).test_autoarrayno longer writes test output into the source tree. The nine tests that wrote intoan
output_test/directory take pytest'stmp_path, the 13 tracked artifacts are gone, and the twofile-by-file
.gitignorelines are replaced bytest_autoarray/**/output_test/as a backstop.After a full run, no
output_test/directory is created anywhere in the tree — so a futureautonerves FITS-writer change cannot rewrite a committed binary the way PyAutoNerves#155 did on #483.
Net: 20 files, +48 / −106.
Worth remembering
array.fitsthat maintenance: floor autonerves at the first release carrying the SMALLDAT stamp #483flipped was still being written. The rest — and the two
.gitignorelines — were residue fromtests deleted long ago. The inventory in a prompt describes the symptom; it is worth re-deriving
which entries are still load-bearing before acting on it.
test_data_pathfixture looked dead and was not. Three tests requested it; a truncatedgrep hid them. Deleting it outright broke them, caught on the first verification run. This is
exactly the failure mode the prompt's "run the suite twice" instruction exists for, arriving one
step earlier than expected.
.gitignorefiles containing*(
test_autoarray/structures/files/,test_autoarray/util/files/array/), alongside the rootfile-by-file lines and directory lines. Not touched here, but it is why one artifact that looked
exposed was in fact already covered.
Follow-up filed, not widened
PyAutoGalaxy is clean. PyAutoLens carries no tracked artifacts either — this defect was
autoarray-only — but its
.gitignorecovers only theintegration/copies ofdata_temp/whileits tests write to
test_autolens/{imaging,interferometer}/data_temp/. The teardownrmtreehidesthat unless a run fails. Filed as
PyAutoMind/draft/maintenance/libraries/autolens_data_temp_not_ignored.md.Generated by Claude Code