Skip to content

Add native Python writer and import management - #816

Open
jonathan343 wants to merge 3 commits into
feat/codegen-symbolsfrom
feat/codegen-writer
Open

jonathan343 wants to merge 3 commits into
feat/codegen-symbolsfrom
feat/codegen-writer

Conversation

@jonathan343

@jonathan343 jonathan343 commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Note

Stacked on #815, targeting feat/codegen-symbols so this PR contains only the writer and import-management work.

Summary

Adds PythonWriter to render structured type references as Python annotations with deterministic imports and indentation. It handles nested and nullable types, forward references, builtin shadowing, and import-name collisions without renaming generated declarations or fields.

The writer returns source in memory. Callers supply declaration and field names and write the module body. File output and structure generation remain separate follow-ups. The API and example are in designs/codegen/writer.md.

Example

from smithy_python.symbols import TypeReference
from smithy_python.writer import PythonWriter

node = TypeReference("Node", "example.models", nullable=True)
writer = PythonWriter(
    "example.models", declarations={"Node"}, local_names={"children", "amount"}
)
writer.line("class Node:")
with writer.indent():
    writer.line("children: ", TypeReference("list", "builtins", (node,)))
    writer.line("amount: ", TypeReference("Decimal", "decimal"))
source = writer.render()

Produces:

from __future__ import annotations

from decimal import Decimal


class Node:
    children: list[Node | None]
    amount: Decimal

Additional Testing

Local rendering checks passed all 434 models in aws/api-models-aws and all 24 in aws-sdk-python/codegen/aws-models, covering annotations, imports, compilation, and deterministic output. Streaming references produced the expected unsupported errors. These checks validate source rendering, not generated AWS classes, and do not add an external CI dependency.


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

Render annotations and deterministic imports in memory. Verify emitted
modules and resolved annotations.
Cover Python 3.12 through 3.15 with a fixed builtin-name set. Add
regression tests and clarify local-name reservations.
Avoid self-imports and duplicate imports for equivalent Unicode
spellings. Add runtime collision and builtin coverage tests.
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.

1 participant