Handle union and literal typing correctly in annotations #478
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.
This fixes a few issues all related to handling Union and Literals in type annotations. Namely:
fixes #475
Previously, the AST parsing for type annotations was incorrectly converting "None" in the example above to be a TypeVar, and then when we called
exec
on the new transformed AST, an error was being thrown. We make sure that in the AST parsing, we only convert a string to a TypeVar.fixes #481
We also handle the case with Literal, where before if you had
Literal["a", "b"]
, "a" and "b" were incorrectly assumed to be CspTypeVar, when they should be the actual literal value. For adjusting the annotations, we stop now if we encounter aLiteral
annotation.fixes #482
Related to the
Literal
andUnion
typing, whenfrom_dict
on csp.Struct was called, we were skipping handlingLiteral
andUnion
. We update the type normalization code to not treatLiteral
as a generic container. Infrom_dict
, aUnion
has no validation performed on it, since under the hood the type normalizer returnsobject
. ForLiteral
, we perform (as we were before in adjusting the annotations themselves) a very basic type check. Namely, we just make sure that we pick a suitable parent class for all the values ofLiteral
(as the type normalization does), and just check it is that class. The tests added demonstrate this, that we don't actually check forLiteral
when callingfrom_dict
, but just make sure the types line up. So, ifLiteral[1, 2]
exists, then a string passed for that field would error. The nuances of this behavior are addressed in this specific test case: https://github.com/Point72/csp/pull/478/files#diff-16e10f816ba9638999d038fb8bd076b4021e901b60e548b1bc392b6191026687R3907