Skip to content

fix: quote recursive union member annotations#709

Open
Alan4506 wants to merge 2 commits into
smithy-lang:developfrom
Alan4506:fix/recursive-union-forward-ref
Open

fix: quote recursive union member annotations#709
Alan4506 wants to merge 2 commits into
smithy-lang:developfrom
Alan4506:fix/recursive-union-forward-ref

Conversation

@Alan4506
Copy link
Copy Markdown
Contributor

@Alan4506 Alan4506 commented Jun 2, 2026

Description of changes:

Generating a client from a model that contains a recursive union currently fails the code generation process. For example, DynamoDB's AttributeValue is a union where the M variant targets a map of AttributeValue and the L variant targets a list of AttributeValue. These generate Python members typed dict[str, AttributeValue] and list[AttributeValue], i.e. they reference the union itself. smithy build --aut fails during ruff check --fix with:

models.py:15921:22: F821 Undefined name `AttributeValue`
models.py:15941:17: F821 Undefined name `AttributeValue`

The reason is that the AttributeValue union alias is emitted after its member dataclasses, so a member annotation like value: dict[str, AttributeValue] is a forward reference to a name that isn't defined yet.

StructureGenerator already handles this: when a member targets a recursive shape, it wraps the type annotation in quotes to make it a forward reference. UnionGenerator is passed the same set of recursive shapes but never uses it, so union members miss this treatment. This change applies the same logic in UnionGenerator. Only members whose target is a recursive shape are affected; all other unions generate exactly as before.

Testing:

Validated against the DynamoDB model which failed the code generation before. Locally, on top of the clean-json-rpc-v1 branch (which adds AWS JSON protocol support), I applied this change together with #707 (strip \^ escape in docstrings). With both changes in place, the DynamoDB client generates successfully: smithy build --aut passes ruff and pyright cleanly, and there are no F821 errors.

Inspecting the generated AttributeValue union members confirms the recursive annotations are now quoted:

# Before
value: dict[str, AttributeValue]
value: list[AttributeValue]

# After
value: "dict[str, AttributeValue]"
value: "list[AttributeValue]"

(The code emits single quotes, matching StructureGenerator; ruff format then normalizes them to double quotes, which is what appears in the generated output.)

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

@Alan4506 Alan4506 requested a review from a team as a code owner June 2, 2026 19:44
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