feat: generate Literal type aliases instead of StrEnum classes#759
Open
feat: generate Literal type aliases instead of StrEnum classes#759
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #759 +/- ##
==========================================
- Coverage 95.90% 95.55% -0.36%
==========================================
Files 48 49 +1
Lines 5228 4788 -440
==========================================
- Hits 5014 4575 -439
+ Misses 214 213 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
36b6927 to
b306913
Compare
ff6fa87 to
965eb8b
Compare
janbuchar
requested changes
Apr 29, 2026
Contributor
There was a problem hiding this comment.
This rename is 1) pointless and 2) wrong - the file contains non-literal types too
| ) | ||
|
|
||
|
|
||
| def snake_case_camelcase_literal_values(content: str) -> str: |
Contributor
There was a problem hiding this comment.
Please improve the name so that it's clear what is the input convention and what is on the output
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue
Description
Replaces every generated
class X(StrEnum)with aX = Literal[...]alias. Users pass plain strings (status='RUNNING') instead of enum members, the aliases are reusable across method signatures, and behavior matches Crawlee and the Apify SDK — avoiding mixing-enum-with-string footguns like #575.Why post-processing
The natural fix —
--enum-field-as-literal=all+--use-type-aliasondatamodel-code-generator— only handles enums referenced from operation parameters; the rest get inlined at every reference site with no stable name to import. Filed upstream as koxudaxi/datamodel-code-generator#3104. Until that lands,scripts/postprocess_generated_models.pydoes the rewrite ourselves; once fixed, we can drop the post-processing.What the post-process does
convert_enums_to_literals— rewrites every top-levelclass X(StrEnum)toX = Literal[...], preserving value order and class docstring.deduplicate_error_type_enum— removes the duplicate inlinedclass Type(StrEnum)datamodel-codegen emits alongside the namedErrorType(same upstream issue), and rewiresTypeannotations toErrorType. AST-based.split_literals_to_file— moves the 11 alias blocks into_literals_generated.pyso consumers don't pull in every Pydantic model.snake_case_camelcase_literal_values— converts camelCase string values (StorageOwnership's'ownedByMe'/'sharedWithMe') to snake_case and emits_<NAME>_WIRE_VALUESso resource clients can convert back to the wire format.The hand-maintained
_types.pyis renamed to_literals.pyfor symmetry.Consumers
TYPE_CHECKINGwhere possible.dataset_collection,key_value_store_collection,request_queue_collectiontranslateownershipback to wire format via_STORAGE_OWNERSHIP_WIRE_VALUES._TERMINAL_STATUSESin_resource_client.pyis derived fromTerminalActorJobStatusviatyping.get_args()— single source of truth.docs/02_concepts/code/03_nested_*.pyexamples no longer reference.MEMBER/.MEMBER.value.Tests
tests/unit/test_postprocess_generated_models.pycovers each step independently plus a full-pipeline integration test.Breaking change
Tracked under v3 on #576.
ActorJobStatus.RUNNINGand similar enum-member access no longer exists — pass the plain string instead.