Skip to content

native types codegen design and generated schemas - #857

Merged
stobrien89 merged 11 commits into
developfrom
native-types-codegen
Oct 26, 2026
Merged

stobrien89 merged 11 commits into
developfrom
native-types-codegen

Conversation

@stobrien89

@stobrien89 stobrien89 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Issue #, if available:
#797

Description

Adds native Python schema generation and the supporting infrastructure for standalone types packages.

This PR includes the approved standalone types design and implements the schema-generation portion. Model generation and CLI integration will follow in separate PRs.

Changes

  • Add shared generation settings, context, and focused generation plans.
  • Add native Smithy selector parsing and standalone type selection.
  • Add dependency tracking shared by symbols, writers, and package generation.
  • Add staged output management with validation and ownership tracking.
  • Emit the compact schema representation introduced in Generate schemas as on-demand hydration from tuples #841.
  • Apply Java-compatible trait filtering and input/output trait synthesis.
  • Encode trait bit vectors, intern strings, and use prelude integer references.
  • Order schemas iteratively and support lazy forward and recursive references.
  • Add collision-safe schema constant naming.
  • Add a versioned compact encoding contract with smithy-core.
  • Add schema generation, selection, dependency, and output tests.

Follow-up work

  • Apply the lazy model representation introduced in Lazy load model data classes #851 to standalone types.
  • Generate typed stubs and package metadata.
  • Add measured schema and model partitioning for large generated packages.
  • Integrate the smithy-python generate types artifact pipeline with the CLI.
  • Add complete Java/native parity testing and large-model performance measurements.

Compatibility

The Java generator remains authoritative until the native implementation passes complete parity validation. Existing generation and generated packages are unaffected.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@stobrien89
stobrien89 force-pushed the native-types-codegen branch 2 times, most recently from 5d75777 to cf12e65 Compare October 20, 2026 20:23

@jonathan343 jonathan343 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @stobrien89!

The design itself looks great. Most of my feedback is about keeping the doc focused on the goal state. Anything that describes current state, specific PRs, or the Java migration will go stale as we land the implementation, so I'd move that to the PR description or #797.

Comment thread designs/codegen/types.md Outdated
Comment thread designs/codegen/types.md Outdated
Comment thread designs/codegen/types.md Outdated
Comment thread designs/codegen/types.md Outdated
Comment thread designs/codegen/types.md Outdated
Comment thread designs/codegen/types.md Outdated
Comment thread designs/codegen/types.md Outdated
Comment thread designs/codegen/types.md Outdated
Comment thread designs/codegen/types.md Outdated
Comment thread designs/codegen/writer.md Outdated
@stobrien89
stobrien89 force-pushed the native-types-codegen branch from 69872c9 to bbf1e2a Compare October 20, 2026 23:49
@stobrien89 stobrien89 changed the title draft: native types codegen design draft: native types codegen design and generated schemas Oct 21, 2026
@stobrien89
stobrien89 requested a balanced review from Copilot October 21, 2026 23:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Output-path safety, stale-file cleanup, selector evaluation, and generated-name collisions remain unresolved.

5 open issues
What changed in this PR

This PR lays the foundation for native Python standalone-types generation under #797. It adds compact schema emission and shared generation infrastructure while leaving the Java generator authoritative.

Changes:

  • Add selector parsing, standalone-type selection, generation plans, and compact schema emission.
  • Introduce dependency tracking and staged file publication with ownership manifests.
  • Expand unit coverage and document the planned standalone-types pipeline.
File Description
packages/​smithy-python/​tests/​unit/​test_writer.py Test dependency collection from type references.
packages/​smithy-python/​tests/​unit/​test_symbols.py Cover dependency metadata and streaming schema names.
packages/​smithy-python/​tests/​unit/​test_selectors.py Test selector parsing and evaluation.
packages/​smithy-python/​tests/​unit/​test_schemas.py Test compact encoding, hydration, and deterministic output.
packages/​smithy-python/​tests/​unit/​test_generation.py Test generation settings, context, and plans.
packages/​smithy-python/​tests/​unit/​test_files.py Test staging, ownership, cleanup, and path checks.
packages/​smithy-python/​tests/​unit/​test_dependencies.py Test dependency validation and merging.
packages/​smithy-python/​tests/​unit/​test_data_selection.py Cover standalone-type selection rules.
packages/​smithy-python/​src/​smithy_python/​writer.py Record dependencies from nested references.
packages/​smithy-python/​src/​smithy_python/​symbols.py Plan schema and union names; attach dependencies.
packages/​smithy-python/​src/​smithy_python/​selection.py Add standalone-type selection and dependency closure.
packages/​smithy-python/​src/​smithy_python/​schemas.py Plan and emit compact, lazy schemas.
packages/​smithy-python/​src/​smithy_python/​model/​_shapes.py Define shared declaration shape types.
packages/​smithy-python/​src/​smithy_python/​model/​__init__.py Export declaration shape types.
packages/​smithy-python/​src/​smithy_python/​generation.py Introduce shared settings, context, and plans.
packages/​smithy-python/​src/​smithy_python/​files.py Implement staged publication and ownership tracking.
packages/​smithy-python/​src/​smithy_python/​exceptions.py Add selector syntax errors.
packages/​smithy-python/​src/​smithy_python/​dependencies.py Define dependency records and runtime requirements.
packages/​smithy-python/​src/​smithy_python/​_selector.py Implement Smithy selector parsing and evaluation.
packages/​smithy-python/​.changes/​next-release/​smithy-python-feature-schema-generation.json Announce native compact schema generation.
packages/​smithy-core/​src/​smithy_core/​_schema_compact.py Expose the compact encoding version.
designs/​codegen/​writer.md Document writer dependency tracking.
designs/​codegen/​types.md Describe the standalone-types architecture and compatibility goals.
designs/​codegen/​symbols.md Document dependency-bearing type references.
designs/​codegen/​selection.md Describe standalone selection and selectors.
designs/​codegen/​index.md Link the standalone-types design.
designs/​codegen/​cli.md Update documented artifact-specific selection rules.

Review effort: Balanced

Comment thread packages/smithy-python/src/smithy_python/files.py Outdated
Comment thread packages/smithy-python/src/smithy_python/files.py Outdated
Comment thread packages/smithy-python/src/smithy_python/generation.py
Comment thread packages/smithy-python/src/smithy_python/_selector.py Outdated
Comment thread packages/smithy-python/src/smithy_python/_selector.py
@stobrien89
stobrien89 force-pushed the native-types-codegen branch from 743a2bb to eee35b8 Compare October 21, 2026 23:39
@stobrien89
stobrien89 requested a balanced review from Copilot October 21, 2026 23:40
@stobrien89
stobrien89 marked this pull request as ready for review October 21, 2026 23:51
@stobrien89
stobrien89 requested a review from a team as a code owner October 21, 2026 23:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread packages/smithy-python/src/smithy_python/_selector.py Outdated
Comment thread packages/smithy-python/src/smithy_python/files.py
Comment thread packages/smithy-python/src/smithy_python/schemas.py Outdated
Comment thread packages/smithy-python/src/smithy_python/_selector.py Outdated
Comment thread packages/smithy-python/src/smithy_python/_selector.py Outdated
Comment thread packages/smithy-python/src/smithy_python/selection.py Outdated
@kuhe

kuhe commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

I'm curious 🐵 about a few parameters.

let's take EC2's model as the input.

  • what's the size of the model on disk?
  • what's the memory once loaded into Python memory as a JSON dictionary?
  • what's the maximum memory in use when generating the client? i.e. overhead of the codegen process on top of the model load
  • machine type and time taken to generate the client?

To what extent is multithreading possible when we generate hundreds of clients?

return result


def _plan_schema_names(selection: Selection) -> dict[ShapeId, str]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

organize public APIs toward the top of the file and internal APIs towards the bottom

class A:
	def m():
	def _m():

def a():

class _B:

def _b():

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated all changes to order by visibility

@stobrien89 stobrien89 changed the title draft: native types codegen design and generated schemas native types codegen design and generated schemas Oct 22, 2026
@stobrien89
stobrien89 force-pushed the native-types-codegen branch from eee35b8 to 9dfce0e Compare October 22, 2026 15:17
@stobrien89
stobrien89 requested a balanced review from Copilot October 22, 2026 15:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread packages/smithy-python/src/smithy_python/dependencies.py Outdated
Comment thread packages/smithy-python/src/smithy_python/schemas.py
Comment thread packages/smithy-python/src/smithy_python/_selector.py Outdated
Comment thread packages/smithy-python/src/smithy_python/schemas.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Selector tokenization and virtual-trait synthesis have unresolved correctness issues that can reject valid expressions or omit expected matches.

2 open issues
4 resolved since last review

Review effort: Balanced

Comment thread packages/smithy-python/src/smithy_python/_selector.py Outdated
Comment thread packages/smithy-python/src/smithy_python/_selector.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The substantial selector implementation and shared runtime encoding contract warrant human review while complete Java/native parity validation remains deferred.

No open issues 🎉

2 resolved since last review

Review effort: Balanced

kuhe
kuhe previously approved these changes Oct 22, 2026
@stobrien89
stobrien89 added this pull request to stack #864 October 22, 2026 19:47
@stobrien89
stobrien89 force-pushed the native-types-codegen branch from 65953e4 to e19987a Compare October 23, 2026 14:28
@stobrien89
stobrien89 force-pushed the native-types-codegen branch 2 times, most recently from 6bf3583 to aa092a5 Compare October 23, 2026 15:27
kuhe
kuhe previously approved these changes Oct 23, 2026
@stobrien89
stobrien89 force-pushed the native-types-codegen branch from 5bbd9cc to 0ffed12 Compare October 24, 2026 00:01
source = staging.joinpath(*PurePosixPath(path).parts)
target = output.joinpath(*PurePosixPath(path).parts)
target.parent.mkdir(parents=True, exist_ok=True)
os.replace(source, target)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you walk me through the intended output ownership and overwrite behavior here? I noticed we preserve modified stale files, but replace current files even if they've been edited or weren't generated by us. Curious about the reasoning behind that distinction and how you expect callers to use the output directory.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intended distinction is between current and stale generated files. Current files are replaced because the new generation is authoritative, while modified stale files are preserved to avoid losing changes.

That said, I don't think we should replace a current file the manifest doesn’t own. I think we should treat that as a collision and require a clean directory for initial generation.

@jonathan343 jonathan343 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I'd like us to keep in mind as this develops is customers eventually calling codegen from Python to customize symbols or contribute files and dependencies. We don't need to define that API yet, but let's keep the generation pipeline usable independently of the CLI so we have a straightforward path to supporting it.

if self.kind == "empty":
return False
if self.kind == "node" and self.value is None:
return False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we distinguish a missing trait from one whose value is null? A member with @default(null) currently fails [trait|default], even though the Smithy CLI selects it. This can silently exclude structures from generation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, a null trait value is still present. I’ll distinguish from a missing value and add coverage for @default(null).

self._union_unknown_names[shape.id] = result
return result

def type_reference(self, shape_id: ShapeId | str) -> TypeReference:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How should callers customize type resolution? Overriding type_reference() for timestamps changes direct references, but lists still resolve to list[datetime] because nested resolution bypasses the override. If we intend to support this, the same rule should apply in both cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nested references should use the same resolution path as direct references. I’ll route collection arguments through type_reference() and add coverage for customized list and map targets.

@stobrien89

Copy link
Copy Markdown
Contributor Author

One thing I'd like us to keep in mind as this develops is customers eventually calling codegen from Python to customize symbols or contribute files and dependencies. We don't need to define that API yet, but let's keep the generation pipeline usable independently of the CLI so we have a straightforward path to supporting it.

Agreed. I’m keeping the stack layered that way. This PR establishes reusable selection, symbols, planning, dependencies, and output management. The model PR builds on those, and CLI integration stays in the final PR. The CLI only assembles the context, runs the generator, and publishes files, so the pipeline remains usable directly from Python.

@stobrien89
stobrien89 merged commit a9c8f7a into develop Oct 26, 2026
11 checks passed
@stobrien89
stobrien89 deleted the native-types-codegen branch October 26, 2026 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants