Skip to content

fix: tolerate data-less HDUs in the database scrape - #1415

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/empty-hdu-scrape-and-latent-guard
Jul 22, 2026
Merged

fix: tolerate data-less HDUs in the database scrape#1415
Jammy2211 merged 1 commit into
mainfrom
feature/empty-hdu-scrape-and-latent-guard

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

The HDU.hdu setter assigned hdu.data straight into the inherited Array.array setter, which dereferences array.dtype without a null check. Any HDU carrying no data therefore raised AttributeError: 'NoneType' object has no attribute 'dtype' and aborted the whole sqlite scrape.

Data-less HDUs are routine rather than exotic. The first HDU of a multi-extension FITS is conventionally an empty PrimaryHDU, and AggregateFITS emits exactly that shape — aggregate_fits.py:107, whose own docstring at line 94 reads "The first HDU in each list is an empty PrimaryHDU". The database path could not ingest the library's own aggregated FITS output.

Such HDUs now store a null payload and are reconstructed with data=None, so an empty PrimaryHDU round-trips losslessly.

Found while reproducing a census report against autofit_workspace_test scripts/profiling/aggregator/profile_database.py, which was filed as a test-mode env-config gap. It is neither test-mode-specific nor env-dependent — the minimal repro is db.HDU(hdu=fits.PrimaryHDU()).

Closes #1413 (library half; the workspace half is queued behind a repo conflict).

API Changes

Behaviour: HDU round-trips data-less HDUs instead of raising AttributeError. This only converts a hard crash into the correct result — no previously-working call changes its output.

Added: HDU.has_data, a read-only property distinguishing an HDU with an array payload from one without.

See full details below.

Test Plan

  • test_hdu_without_data — a bare fits.PrimaryHDU() round-trips, returning data is None and preserving the PrimaryHDU type
  • test_set_fits_with_empty_primary_hdu — the shape the scrape actually meets (empty primary + named ImageHDU extension) survives set_fits/get_fits
  • Both new tests confirmed to fail without the fix, with exactly the reported AttributeError at array.py:56
  • test_autofit/ full suite: 1527 passed, 1 skipped
  • autofit_workspace_test profiling/aggregator/profile_database.py runs end-to-end (exit 0); previously the reported crash
  • black --check clean
Full API Changes (for automation & release notes)

Added

  • autofit.database.model.array.HDU.has_databool property; True when the HDU holds an array payload. A data-less HDU stores no shape, which is how the two are distinguished.

Changed Behaviour

  • autofit.database.model.array.HDU.hdu (setter) — an HDU whose .data is None now records a null payload (_dtype, _shape, bytes left unset) instead of raising AttributeError from the inherited Array.array setter.
  • autofit.database.model.array.HDU.hdu (getter) — reconstructs with data=None when has_data is False, rather than calling np.frombuffer on a null buffer.
  • Downstream, Fit.set_fits / Aggregator.add_directory now ingest multi-extension FITS beginning with an empty PrimaryHDU; previously any such file aborted the scrape.

Migration

  • None. No signature changed and no symbol was removed or renamed; code that worked before is unaffected.

Generated by the PyAutoLabs agent workflow.

The `HDU.hdu` setter assigned `hdu.data` straight into `Array.array`,
whose setter dereferences `array.dtype` unguarded. Any HDU without data
therefore raised `AttributeError: 'NoneType' object has no attribute
'dtype'` and aborted the sqlite scrape.

Data-less HDUs are routine rather than exotic: the first HDU of a
multi-extension FITS is conventionally an empty `PrimaryHDU`, and
`AggregateFITS` emits exactly that shape (aggregate_fits.py:107). The
database path could not ingest the library's own aggregated FITS output.

Store a null payload for such HDUs and reconstruct them with `data=None`,
so an empty `PrimaryHDU` round-trips losslessly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Jul 22, 2026
@Jammy2211
Jammy2211 merged commit 490d98a into main Jul 22, 2026
5 checks passed
@Jammy2211
Jammy2211 deleted the feature/empty-hdu-scrape-and-latent-guard branch July 22, 2026 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending-release PR queued for the next release build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: db scrape crashes on empty PrimaryHDU; latent guard vacuous

1 participant