Support for Python3.9 type hint syntax#2795
Merged
Merged
Conversation
- Rename the new python-version level to 3.10: PEP 604 unions (X | None)
require Python 3.10, not 3.9. Split the feature flag into
builtinGenerics (PEP 585, 3.9+) and unionOperators (PEP 604, 3.10+),
which also yields a 3.9 level with builtin generics but typing
Optional/Union. Make 3.10 the default python-version.
- Emit " = None" defaults outside the quoted annotation: the annotation
'Foo | None = None' is invalid syntax.
- Only quote PEP 604 unions when a member actually needs a forward
reference, and never quote inside an already-quoted annotation.
- Restore withTyping("Dict") registration in the dict converter so the
typing import is emitted for pre-3.9 versions, and revert typeObject's
map branch to the runtime type "dict".
- Cover the legacy typing.* code paths in QUICKTEST via
quickTestRendererOptions for 3.5/3.6/3.7/3.9.
- Run python fixtures under Python 3.12 in CI and the fixture driver.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
With dataclasses (3.7+), optional properties become nullable unions and get a " = None" default — except when the property type is Any (null is absorbed into it) or plain null (the union collapses), which got no default yet could sort after defaulted fields, making the generated dataclass raise "TypeError: non-default argument follows default argument" at import. This was latent on master because CI only ever exercised 3.5/3.6, which don't use dataclasses; with 3.10 as the new default it breaks e.g. vega-lite.schema and the combinations samples. Emit " = None" for root-level Any/None fields too, and make the property sort order compute exactly "will this field render with a default" via followTargetType — the old kind-based predicate saw pre-transformation types (transformed unions have kind "any" at sort time) and could order a non-defaulted field after defaulted ones. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Description
In python 3.9 and onwards, some generics are type hinted differently (Dict, List should be lowercase dict, list instead) as well as some syntax changes (Optional[Type] syntax replaced with Type | None syntax, along with Union[Type1, Type2] replaced with Type1 | Type2)
I added a new option to pythonOptions.features, a boolean "builtinGenerics". In python 3.9 it's enabled, and disabled for the previous versions. I use pretty simple logic to do it, just a couple of if statements and ternary operators to account for the new syntax.
Some ways quotes are handled around types was changed to support wrapping around unions. (see _suppressQuotes in PythonRenderer's
namedTypemethod)Motivation and Context
To keep up with newer Python syntax.
How Has This Been Tested?
Tested with python 3.7 and python 3.9 using the scripted tests that use mypy (confirms that the syntax is valid, and that with python 3.7, it's not trying to use any of the new syntax) along with looking at the outputs manually and confirming that 3.9 uses the newer syntax.