Skip to content

Improve TypedDict key quoting - #769

Merged
Tinche merged 1 commit into
mainfrom
tin/fix-typeddicts
Aug 9, 2026
Merged

Tinche merged 1 commit into
mainfrom
tin/fix-typeddicts

Conversation

@Tinche

@Tinche Tinche commented Aug 9, 2026

Copy link
Copy Markdown
Member

Improves codegen for typeddicts to fix handling keys with single quotes.

@Tinche
Tinche force-pushed the tin/fix-typeddicts branch from de4072c to bf77745 Compare August 9, 2026 19:57
Improves codegen for typeddicts to fix handling keys with single quotes.

Signed-off-by: Tin Tvrtkovic <tinchester@gmail.com>
@Tinche
Tinche force-pushed the tin/fix-typeddicts branch from bf77745 to 8f3f971 Compare August 9, 2026 19:57
@codspeed

codspeed Bot commented Aug 9, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 64 untouched benchmarks


Comparing tin/fix-typeddicts (8f3f971) with main (82b02c0)

Open in CodSpeed

@Tinche
Tinche merged commit f2e42f3 into main Aug 9, 2026
14 checks passed
@Tinche
Tinche deleted the tin/fix-typeddicts branch August 9, 2026 20:01
Tinche pushed a commit that referenced this pull request Sep 14, 2026
`make_hetero_tuple_structure_fn` builds the per-index note by interpolating
`str(cl)` into a single-quoted string literal in the generated source, at
`src/cattrs/gen/__init__.py` line 903 on main:
`f"__c_ivn('Structuring {cl} @ index {ix}', {ix}, {type_name})]"`. When a type
argument has a quote in its `repr`, such as `Literal["a"]`, the quote closes
the literal early and compiling the hook raises `SyntaxError` before any data
is looked at. This only affects the generated path, so `Converter()` fails
where `BaseConverter()` and `Converter(detailed_validation=False)` succeed.
`NamedTuple`s structure through the same factory, so they crash the same way.

This is the same class of bug as #769 and #771, and the fix is the same shape
already used in `src/cattrs/gen/typeddicts.py` line 394: build the note text in
Python and embed it with `repr`. The note text is byte-identical to before, so
nothing that reads `IterableValidationNote` changes.

The test covers a quote from `Literal`, the same quote nested inside a `List`,
an `Annotated` whose metadata repr contains both quote characters, and a
`NamedTuple` field, then triggers a real validation failure and checks the note
reads exactly as it does for a tuple whose arguments have no quotes. The
expected note is built from the same type expression so the assertion does not
depend on how a given Python version renders typing objects.
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