Skip to content

Commit d9d72d3

Browse files
committed
fixes
1 parent 6d0ec17 commit d9d72d3

2 files changed

Lines changed: 22 additions & 78 deletions

File tree

docs/md/dfnspec.md

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
- [Type-specific attributes](#type-specific-attributes-2)
4040
- [`valid`](#valid)
4141
- [`case_sensitive`](#case_sensitive)
42+
- [`time_series`](#time_series)
4243
- [`pk`](#pk)
4344
- [`fk`](#fk)
4445
- [`fk_ref`](#fk_ref)
@@ -52,7 +53,7 @@
5253
- [Double](#double)
5354
- [Type-specific attributes](#type-specific-attributes-4)
5455
- [`time_series`](#time_series-1)
55-
- [Path](#path)
56+
- [File](#file)
5657
- [Type-specific attributes](#type-specific-attributes-5)
5758
- [`mode`](#mode)
5859
- [Composites](#composites)
@@ -309,6 +310,10 @@ Type `string`.
309310

310311
`boolean (default: false)`. Indicates that the string's case must be preserved. The MF6 parser uppercases strings by default.
311312

313+
###### `time_series`
314+
315+
`boolean (default: false)`. Marks fields where the parser accepts either a string literal or a time-series name (referencing a `utl-ts` object).
316+
312317
###### `pk`
313318

314319
`boolean (default: false)`. Marks this scalar as the primary key of its containing list's item record. Valid only on integer or string scalars that are columns in a list item record. Exactly one column per list item may be marked pk.
@@ -327,10 +332,6 @@ Type `integer`.
327332

328333
##### Type-specific attributes
329334

330-
###### `tagged`
331-
332-
`boolean (default: true)`. Indicates that the field value should be preceded by the field name.
333-
334335
###### `valid`
335336

336337
`[integer] | null`. Permitted values (enumeration constraint). Empty list is treated as absent.
@@ -357,17 +358,13 @@ Type `double`.
357358

358359
##### Type-specific attributes
359360

360-
###### `tagged`
361-
362-
`boolean (default: true)`. Indicates that the field value should be preceded by the field name.
363-
364361
###### `time_series`
365362

366363
`boolean (default: false)`. Marks fields where the parser accepts either a numeric literal or a time-series name (referencing a `utl-ts` object). Not inferable from structural type. Also appears on array fields (where it references a `utl-tas` object instead). Note that `utl-tas` currently only works with layered arrays, not full-grid arrays, though generalizing has been considered.
367364

368-
#### Path
365+
#### File
369366

370-
Type `path`.
367+
Type `file`.
371368

372369
##### Type-specific attributes
373370

@@ -472,13 +469,14 @@ And a `scope` (see [Scope and resolution](#scope-and-resolution)) that controls
472469

473470
Self-sizing `array` fields (those with `shape: []`) may also serve as dimension sources: any such array's name may appear in a `shape` expression to mean "one element per item in this array." These are registered in `dims` with `field` pointing to the array name.
474471

475-
Shape expressions for non-string arrays may use one of three structural forms. All three may additionally carry a bound annotation:
472+
Shape expressions for non-string arrays may use one of four structural forms. Dim references may additionally carry a bound annotation:
476473

477474
- **Dim reference** (`^[A-Za-z_]\w*$`): a plain identifier resolved via the scope chain (explicit → derived → inherited dims). When the array is a subfield of a record and the identifier does not resolve globally, resolution falls back to intra-record sibling scope (see below).
478475
- **Intra-record sibling reference**: a dim reference that names a sibling `integer` in the same enclosing record. Makes the record a variadic tuple whose width varies per row. Valid only when the array is a subfield of a record. See below.
476+
- **Arithmetic offset** (`dim [+-] integer`): a dim reference with an integer offset, e.g. `nlay + 1`. Only the dim portion is validated; the offset is accepted as-is.
479477
- **Row-level column lookup** (`block.column(fk_field)`): a cross-list per-row quantity, valid only for array subfields of records. See below.
480478

481-
Any dim reference (either of the first two forms) may carry a **bound annotation** prefix (`<`, `>`, `<=`, or `>=`). The dim portion validates normally; the bound is advisory and is not enforced by the MF6 parser.
479+
Any dim reference (including the dim portion of an arithmetic offset) may carry a **bound annotation** prefix (`<`, `>`, `<=`, or `>=`). The dim portion validates normally; the bound is advisory and is not enforced by the MF6 parser.
482480

483481
A shape expression that does not match one of these forms is a schema validation error. String arrays (`dtype: "string"`) must have empty `shape`.
484482

modflow_devtools/dfns/schema.py

Lines changed: 11 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@
1717

1818

1919
class FieldBase(BaseModel):
20+
name: str
21+
longname: str | None = None
22+
description: str | None = None
23+
optional: bool = False
24+
default: Any | None = None
25+
developmode: bool = False
26+
netcdf: bool = False
27+
tagged: bool = True
28+
2029
@classmethod
2130
def from_dict(cls, d: dict, strict: bool = False) -> "FieldBase":
2231
type_name = d.get("type")
@@ -25,7 +34,7 @@ def from_dict(cls, d: dict, strict: bool = False) -> "FieldBase":
2534
"string": String,
2635
"integer": Integer,
2736
"double": Double,
28-
"path": File,
37+
"file": File,
2938
"array": Array,
3039
"record": Record,
3140
"union": Union,
@@ -43,25 +52,10 @@ def from_dict(cls, d: dict, strict: bool = False) -> "FieldBase":
4352

4453
class Keyword(FieldBase):
4554
type: Literal["keyword"] = PydanticField(default="keyword", frozen=True)
46-
name: str
47-
longname: str | None = None
48-
description: str | None = None
49-
optional: bool = False
50-
default: Any | None = None
51-
developmode: bool = False
52-
netcdf: bool = False
5355

5456

5557
class String(FieldBase):
5658
type: Literal["string"] = PydanticField(default="string", frozen=True)
57-
name: str
58-
longname: str | None = None
59-
description: str | None = None
60-
optional: bool = False
61-
default: Any | None = None
62-
developmode: bool = False
63-
netcdf: bool = False
64-
tagged: bool = True
6559
valid: list[str] | None = None
6660
case_sensitive: bool = False
6761
time_series: bool = False
@@ -72,14 +66,6 @@ class String(FieldBase):
7266

7367
class Integer(FieldBase):
7468
type: Literal["integer"] = PydanticField(default="integer", frozen=True)
75-
name: str
76-
longname: str | None = None
77-
description: str | None = None
78-
optional: bool = False
79-
default: Any | None = None
80-
developmode: bool = False
81-
netcdf: bool = False
82-
tagged: bool = True
8369
valid: list[int] | None = None
8470
time_series: bool = False
8571
pk: bool = False
@@ -89,25 +75,11 @@ class Integer(FieldBase):
8975

9076
class Double(FieldBase):
9177
type: Literal["double"] = PydanticField(default="double", frozen=True)
92-
name: str
93-
longname: str | None = None
94-
description: str | None = None
95-
optional: bool = False
96-
default: Any | None = None
97-
developmode: bool = False
98-
netcdf: bool = False
99-
tagged: bool = True
10078
time_series: bool = False
10179

10280

10381
class File(FieldBase):
10482
type: Literal["file"] = PydanticField(default="file", frozen=True)
105-
name: str
106-
longname: str | None = None
107-
description: str | None = None
108-
optional: bool = False
109-
default: Any | None = None
110-
developmode: bool = False
11183
mode: Literal["filein", "fileout"]
11284

11385

@@ -119,13 +91,6 @@ class File(FieldBase):
11991

12092
class Array(FieldBase):
12193
type: Literal["array"] = PydanticField(default="array", frozen=True)
122-
name: str
123-
longname: str | None = None
124-
description: str | None = None
125-
optional: bool = False
126-
default: Any | None = None
127-
developmode: bool = False
128-
netcdf: bool = False
12994
dtype: Literal["keyword", "integer", "double", "string"]
13095
shape: list[str] = []
13196
time_series: bool = False
@@ -134,12 +99,6 @@ class Array(FieldBase):
13499

135100
class Record(FieldBase):
136101
type: Literal["record"] = PydanticField(default="record", frozen=True)
137-
name: str
138-
longname: str | None = None
139-
description: str | None = None
140-
optional: bool = False
141-
default: Any | None = None
142-
developmode: bool = False
143102
fields: "dict[str, Scalar | Array | Record | Union]" = PydanticField(default_factory=dict)
144103

145104
@property
@@ -149,12 +108,6 @@ def children(self) -> "dict[str, Field]":
149108

150109
class Union(FieldBase):
151110
type: Literal["union"] = PydanticField(default="union", frozen=True)
152-
name: str
153-
longname: str | None = None
154-
description: str | None = None
155-
optional: bool = False
156-
default: Any | None = None
157-
developmode: bool = False
158111
arms: "dict[str, Scalar | Array | Record]" = PydanticField(default_factory=dict)
159112

160113
@property
@@ -164,13 +117,6 @@ def children(self) -> "dict[str, Field]":
164117

165118
class List(FieldBase):
166119
type: Literal["list"] = PydanticField(default="list", frozen=True)
167-
name: str
168-
longname: str | None = None
169-
description: str | None = None
170-
optional: bool = False
171-
default: Any | None = None
172-
developmode: bool = False
173-
netcdf: bool = False
174120
item: "Record | Union"
175121

176122
@property
@@ -397,7 +343,7 @@ class Simulation(ComponentBase):
397343

398344
class Model(ComponentBase):
399345
type: Literal["model"] = "model"
400-
solution: str | list[str] | None = None # compatible solution type(s)
346+
solution: Literal["ims", "ems", "sln-ims", "sln-ems"] | None = None
401347

402348

403349
class Package(ComponentBase):

0 commit comments

Comments
 (0)