Skip to content

Generate typed nested resource dataclasses - #600

Open
razor-x wants to merge 2 commits into
mainfrom
codex/fix-nested-resource-types-in-python-sdk
Open

Generate typed nested resource dataclasses#600
razor-x wants to merge 2 commits into
mainfrom
codex/fix-nested-resource-types-in-python-sdk

Conversation

@razor-x

@razor-x razor-x commented Aug 6, 2026

Copy link
Copy Markdown
Member

Motivation

  • Nested resource properties were emitted as untyped mappings (Dict[str, Any] or DeepAttrDict) which conflicted with runtime hydration and prevented attribute completion and nested docs.
  • Arrays of object-shaped items (e.g. errors/warnings) were left as lists of bare dicts, forcing subscript access and losing attribute access.
  • Generated docstrings only documented top-level fields and nested unknown keys were not stripped, making the SDK less safe and discoverable.
  • The project lacked a PEP 561 marker and a typing gate, so these regressions were not enforced by CI.

Description

  • Make the code generator recursively discover and register nested object classes and discriminated-object variants in codegen/lib/layouts/resources.ts, producing nested class contexts and per-property metadata.
  • Update type mapping to return generated nested class names in codegen/lib/python-type.ts and change templates (codegen/layouts/resource.hbs and codegen/layouts/partials/resource-dataclass.hbs) to emit nested dataclasses before the parent and to hydrate objects and lists of objects using from_dict.
  • Add a small mapping-compat shim seam/utils/resource_mapping.py that nested dataclasses inherit so they remain indexable and support .get(), in, iteration, and .keys() while becoming real typed dataclasses; leave record properties as Dict[str, Any].
  • Ship PEP 561 marker seam/py.typed, add mypy to dev dependencies and just lint, regenerate the seam/resources/ modules (many files updated), and add regression tests in test/nested_resource_test.py covering nested hydration, list-of-object hydration, unknown key stripping, record passthrough, mapping compatibility, and union hydration for action_attempt.

Testing

  • Ran generation and static checks: npx tsx codegen/smith.ts, npm run lint, and npm run typecheck which completed successfully.
  • Ran Python formatting and static typing: python -m black --check ., python -m mypy seam/resources --disable-error-code=arg-type --disable-error-code=import-not-found, and python -m compileall -q seam, which succeeded for the modified resources.
  • Executed the new unit tests via python -m pytest test/nested_resource_test.py, which failed to run end-to-end due to a missing runtime dependency (urllib3) in the execution environment (test harness), not due to the generated code itself.
  • Confirmed generated changes: Device.properties is now typed as DeviceProperties, errors/warnings are typed lists of nested dataclasses, custom_metadata remains Dict[str, Any], and nested classes are documented and hydrated in from_dict.

Codex Task

Nested resource objects now hydrate as typed mapping-compatible dataclasses and unknown nested API fields are stripped. Free-form record properties remain mappings.

BREAKING CHANGE: Nested properties are typed objects rather than dict subclasses. dict(...) and isinstance(value, dict) no longer work for them; typoed attributes now raise AttributeError instead of returning and inserting an empty mapping; undocumented nested fields are stripped.
@razor-x
razor-x requested a review from a team as a code owner August 6, 2026 05: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.

2 participants