Parent
#8
What to build
Fix a type-annotation bug in tools/codegen/v2gjson_emitter.py's _param_type function: fields with kind="struct" (libcbv2g-declared nested structs like RelativeTimeInterval: struct din_RelativeTimeIntervalType) currently fall through to the default return "int" branch, producing constructor signatures like RelativeTimeInterval: int|None = None when the legal value at runtime is the dict returned by the corresponding nested constructor (RelativeTimeIntervalType(...)).
Add a branch if field.kind == "struct": return "dict[str, Any]" (mirroring the existing kind="array" → list[dict[str, Any]] branch). Regenerate all eight V2Gjson modules from the emitter and verify no other change to constructor bodies occurs (the runtime _value_expr already passes the value through unchanged for kind="struct").
The C++ marshalers (src/generated/*_marshalers.generated.cpp) confirm the contract: outJson["RelativeTimeInterval"] = getJson_RelativeTimeIntervalType(...) emits a JSON object, and getDoc_RelativeTimeIntervalType(...) consumes one. This is purely a static-type-annotation fix; no runtime behavior changes.
Per ADR-0014, this fix is in the v1.0 window — shipping the broken annotation and fixing in v1.1 would make a dict|None annotation a MAJOR-bump change post-tag.
Acceptance criteria
Blocked by
Parent
#8
What to build
Fix a type-annotation bug in
tools/codegen/v2gjson_emitter.py's_param_typefunction: fields withkind="struct"(libcbv2g-declared nested structs likeRelativeTimeInterval: struct din_RelativeTimeIntervalType) currently fall through to the defaultreturn "int"branch, producing constructor signatures likeRelativeTimeInterval: int|None = Nonewhen the legal value at runtime is the dict returned by the corresponding nested constructor (RelativeTimeIntervalType(...)).Add a branch
if field.kind == "struct": return "dict[str, Any]"(mirroring the existingkind="array"→list[dict[str, Any]]branch). Regenerate all eight V2Gjson modules from the emitter and verify no other change to constructor bodies occurs (the runtime_value_expralready passes the value through unchanged forkind="struct").The C++ marshalers (
src/generated/*_marshalers.generated.cpp) confirm the contract:outJson["RelativeTimeInterval"] = getJson_RelativeTimeIntervalType(...)emits a JSON object, andgetDoc_RelativeTimeIntervalType(...)consumes one. This is purely a static-type-annotation fix; no runtime behavior changes.Per ADR-0014, this fix is in the v1.0 window — shipping the broken annotation and fixing in v1.1 would make a
dict|Noneannotation a MAJOR-bump change post-tag.Acceptance criteria
tools/codegen/v2gjson_emitter.py_param_typereturns"dict[str, Any]"forkind="struct"fieldstests/integration/round-trip suites still passPMaxScheduleEntryType,SalesTariffEntryType, ISO-2 / ISO-20 analogs) to confirm the annotation is nowdict[str, Any] | NoneBlocked by