Skip to content

test: untrack generated FITS output artifacts in test_autoarray #494

Description

@Jammy2211

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_test writer to pytest's tmp_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 .gitignore lines with one directory pattern as a backstop
    against a future writer regressing this.
  • Remove a dead test_data_path fixture in the imaging tests that no test requests.
  • Verify from a clean checkout: full suite twice in a row, git status clean 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.py writes structures/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-25 defines a test_data_path fixture that no test
    ever requests — dead code shadowing the module-level constant.

Implementation Steps

  1. Convert writers to tmp_path. In each, drop the shutil.rmtree / os.makedirs
    preamble and write to tmp_path / <name>, reading back from the same path. Inputs keep
    reading from their committed files/ 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-level test_data_path constant (line 12). Leave
      create_fits / clean_fits / fits_path alone — those target files/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 first test_data_path (input files/), replace the rebound
      output path with tmp_path.
    • test_autoarray/dataset/imaging/test_dataset.py — delete the unused
      make_test_data_path fixture (lines 16-25).

    Prune import os / import shutil only where they become genuinely unused.

  2. Untrack and delete the 13 files (git rm, not --cached — nothing reads them), then
    remove the five emptied output_test/ directories and any parent left empty
    (dataset/files/arrays/, structures/arrays/files/values/).

  3. .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.

  4. Verify. source activate.sh then python3 -m pytest -q -n auto from a clean
    checkout, run twice in a row, asserting git status --porcelain empty 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.

  5. Siblings. Grep PyAutoGalaxy/PyAutoLens for the same pattern and route findings through
    /intake as 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 artifact
  • test_autoarray/structures/arrays/test_uniform_1d.py — second writer of the same directory
  • test_autoarray/structures/test_visibilities.py — writer of the untracked-but-un-ignored artifact
  • test_autoarray/mask/test_mask_2d.py — writer into an already-ignored directory
  • test_autoarray/dataset/interferometer/test_dataset.py — writer into an already-ignored directory
  • test_autoarray/dataset/imaging/test_dataset.py — dead test_data_path fixture
  • .gitignore — the two file-by-file lines replaced by the directory pattern

Trade-offs

  • tmp_path over 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, since test_uniform_1d and test_uniform_2d currently
    rmtree the 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

  1. 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's tmp_path fixture is a near-drop-in and removes the
      tracked path entirely. This is the durable fix.
    • .gitignore the directories (test_autoarray/**/output_test/) plus
      git rm --cached the 13 files, if converting the tests is judged too wide.
      Cheaper, but leaves the tests writing into the source tree.
  2. 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:12 reads from an output_test path —
    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 of output_test/ instead.
  3. 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).
  4. 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions