Skip to content

refactor list handling - #382

Merged
wpbonelli merged 5 commits into
modflowpy:developfrom
wpbonelli:tagged-lists
Oct 1, 2026
Merged

wpbonelli merged 5 commits into
modflowpy:developfrom
wpbonelli:tagged-lists

Conversation

@wpbonelli

Copy link
Copy Markdown
Member

wpbonelli and others added 5 commits September 30, 2026 07:39
modflow-devtools#368 distinguishes tagged lists (every line starts with a
keyword) from untagged ones (a table filling its block), and represents
ts_filerecord and tas_filerecord as tagged lists, since TS6/TAS6 FILEIN may
repeat. Codegen and the grammar generator assumed any list in a non-period
block was the block's table, so they turned options into a table and
dropped ts_file.

A tagged list is now a repeatable field among the block's others: each
element is what a single occurrence would be (a file record's Path, or a
record class), in an Optional[list[...]] field with `repeats` metadata.
Ingress appends one element per row, egress writes one line per element,
and the typed reader always returns a list. ts_file/tas_file become
Optional[list[Path]], converting a single path to a one-element list.

This also fixes repeated TS6 FILEIN rows being dropped on load (all but
the last), so test_repeated_ts6_kept is no longer an expected failure.

Pin modflow-devtools to modflowpy#368 so this lands separately from modflowpy#369.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Whether a list is tagged and what its item is are independent of which
block it's in. Codegen had separate paths for a period block's plain list,
its keystring union, a list alone in another block, and (in the previous
commit) a tagged list; now one builder makes any list's element classes:

- a union item: one Item class per arm, dispatched by keyword, plus a
  _<Class>Item alias, in any block (not just period)
- a tagged record item: one Item class led by its _keyword, built like a
  union arm (Item is a Record, so this replaces the record class)
- an untagged record item: one Item class of positional columns
- a file record item: Path, so ts_file stays list[Path]

Only the field around the elements depends on the block: dict[int, list]
in the period block, named for the block when the list is its only field,
named for the list when it shares the block.

The file layout is inferred from types, so drop the `repeats` metadata: a
list holds one line per element, and an Item list sharing its block takes
the rows starting with its elements' keyword(s). AUXILIARY, a string array
in the DFN, is now NDArray[np.str_] (a list of names still converts), so
a one-line list of values is an array, not a list.

Generated classes only change for the above. Tagged lists of union items
and of non-file records have no real case yet; synthetic tests cover them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The typed reader returns a list for a block's list elements (a tagged
list's lines, or a union item's arms) from the block's schema, rather
than from a set of tagged lists or a field happening to repeat.

An item's aux column comes from its DFN, where its shape names the
array sizing it (auxiliary), instead of being injected into every
period and packagedata item. This drops aux from items whose DFN has
none (BUY, VSC, FMI, MVR, CSUB, PRP). Ingress sizes such columns from
the named fields, and Item finds them by their shape, not by name.

Converters are derived from the generated type (attrs optional, to_list,
to_array) instead of one hand-written converter per type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
normalize_aux_keys mapped per-column aux0/aux1/... keys, left from when
list rows were recarrays, onto the item's aux tuple. Nothing produces
those keys any more; dict input now gives aux as a column of tuples,
like the item field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wpbonelli wpbonelli added this to the MVP milestone Oct 1, 2026
@wpbonelli
wpbonelli marked this pull request as ready for review October 1, 2026 16:57
@wpbonelli
wpbonelli merged commit 9abe68d into modflowpy:develop Oct 1, 2026
16 checks passed
@wpbonelli
wpbonelli deleted the tagged-lists branch October 1, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant