Start using TypeAliasType in the semantic analyzer#7923
Start using TypeAliasType in the semantic analyzer#7923ilevkivskyi merged 16 commits intopython:masterfrom
Conversation
|
(A side note, I can potentially make fewer but larger PRs, but IMO so far the idea of small PRs worked well for type aliases, so I would prefer to continue this way.) |
|
There is another important thing to call out, previously unions never contained another unions as items (because constructor flattened them), and some code might implicitly rely on this. IMO we should probably update these places, since maintaining this guarantee may be painful. |
|
Yet another important thing is that this may break many plugins, so we need to announce this in #6617 when will merge this. |
JukkaL
left a comment
There was a problem hiding this comment.
Great, this PR enables type alias types with fairly minor local changes. I'm no longer worried that introducing this is very risky, but I think that we should have at least one full week of internal testing before a public release.
Thank you for writing such detailed plan for the next steps! The plan looks solid to me.
| def visit_type_alias_type(self, t: TypeAliasType) -> None: | ||
| super().visit_type_alias_type(t) | ||
| if t in self.seen_aliases: | ||
| return |
There was a problem hiding this comment.
Add comment about this special case.
| self.scope = Scope() | ||
| # Should we also analyze function definitions, or only module top-levels? | ||
| self.recurse_into_functions = True | ||
| self.seen_aliases = set() # type: Set[TypeAliasType] |
There was a problem hiding this comment.
Add comment (also explain why we need this).
mypy/types.py
Outdated
| """ | ||
| assert self.alias is not None | ||
| if self.alias.no_args: | ||
| assert isinstance(self.alias.target, ProperType) |
| def __init__(self, strategy: Callable[[Iterable[T]], T]) -> None: | ||
| self.strategy = strategy | ||
| self.seen = [] # type: List[Type] | ||
| self.seen_aliases = set() # type: Set[TypeAliasType] |
There was a problem hiding this comment.
Whill we ever need to clear this? If the visitor is single-use, mention this in the docstring.
This PR starts using the new
TypeAliasTypein the semantic analyzer. This PR doesn't yet pulls the trigger to enable the recursive types, but it is now essentially one line of code away. This PR:TypeAliasTypeinstead of eagerly expanding the alias target.TypeAliasExprto refer toTypeAlias(sorry for the noise).get_proper_type()I found necessary while playing with actual recursive types over the weekend.Here are some strategical comments:
It would probably make sense to test this well locally before a public release.
L = List; x: L[int], I preserve this by using eager expansion in this special case, otherwise it would complicate the whole logic significantly. This is also mostly a legacy thing because we have built-in aliases likeList = listmagically added by semantic analyzer.get_proper_type()is not a best strategy. It saves all the existing special-casing but also introduces a risk for infinite recursion. In particular, "type ops tangle" should ideally always pass on the original alias type. Unfortunately, there is no way to fix/enforce this (without having some severe performance impact). Note it is mostly fine to "carelessly" useget_proper_type()in the "front end" (likechecker.py,checkexpr.py,checkmember.pyetc).Here is my plan for the next five PRs:
SubtypeVisitorandProperSubtypeVisitor, there is very large amount of code duplication (there is already an issue for this).sametypes.py(I am going to open a new issue, see my arguments there).TypeInfos, but will be stored asTypeAlias. Essentially there will be almost no difference betweenA = Tuple[int, int]andA = NamedTuple('A', [('x', int), ('y', int)]). This will allow typed dicts and named tuple participate in recursive types.TypeInfos so it IMO it really makes sense to make them uniform (and avoid confusions and code duplication in future).5a. Potentially as a follow-up I may add support for generic named tuples and typed dicts, since steps 4 plus 5 will make this almost trivial.