Skip to content

New semantic analyzer: Prohibit duplicate type variable definitions and fix stale upper bounds and values#6563

Merged
ilevkivskyi merged 11 commits intopython:masterfrom
ilevkivskyi:new-dup-typevar
Jun 26, 2019
Merged

New semantic analyzer: Prohibit duplicate type variable definitions and fix stale upper bounds and values#6563
ilevkivskyi merged 11 commits intopython:masterfrom
ilevkivskyi:new-dup-typevar

Conversation

@ilevkivskyi
Copy link
Copy Markdown
Member

@ilevkivskyi ilevkivskyi commented Mar 18, 2019

This is a follow up for #6527.

Fixes #7037
I think this also essentially concludes #6300

This PR prohibits duplicate type variable definitions, previously the second one was silently winning. Also now the first one wins. Note that it didn't require additional attribute on TypeVarExpr as I initially though, it looks like we can simple use s.rvalue.analyzed for the purpose of linking assignments to variables.

This PR also naturally fixes an issue where stale upper bound or value appears in a class that uses the type variable.

@ilevkivskyi ilevkivskyi requested a review from JukkaL March 18, 2019 19:58
Copy link
Copy Markdown
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I have one question about incrementally updating a type variable definition and a few nits.

Comment thread mypy/newsemanal/semanal.py Outdated
if existing and not isinstance(existing.node, (TypeVarExpr, PlaceholderNode)):
if existing and not (isinstance(existing.node, PlaceholderNode) or
# Also give error for another type variable with the same name.
isinstance(existing.node, TypeVarExpr) and
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit: Use parentheses to make precedence explicit when mixing and/or.

Comment thread mypy/newsemanal/semanal.py Outdated
# T = TypeVar('T', bound=C[Any])
# class C(Generic[T]):
# ...
# We can use allow_placeholder=True for upper bound and values to avoid this,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make it clear whether we are actually doing this. Instead, write something like "We could use ..., but we don't do this, because ...".

What happens if the type variable definition and the class definition are in different parts of an import cycle? Do we ensure that once the type variable has been completed, the new bound will be used in the class definition?

@ilevkivskyi ilevkivskyi changed the title New semantic analyzer: Prohibit duplicate type variable definitions New semantic analyzer: Prohibit duplicate type variable definitions and fix stale upper bounds and values Jun 25, 2019
Comment thread mypy/type_visitor.py

def visit_type_var(self, t: TypeVarType) -> T:
return self.strategy([])
return self.query_types([t.upper_bound] + t.values)
Copy link
Copy Markdown
Member Author

@ilevkivskyi ilevkivskyi Jun 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is strictly speaking unrelated, but it made one new test fail (because has_placeholder() was wrong).

Copy link
Copy Markdown
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a good way to deal with the problem. I was worried that we need to do something drastic to address the issue, and I'm glad that this is a pretty straightforward change.

Left a few minor comments, otherwise looks good.

Comment thread mypy/newsemanal/semanal.py Outdated
assert isinstance(call.analyzed, TypeVarExpr)
call.analyzed.upper_bound = upper_bound
call.analyzed.values = values
self.progress = True
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this always progress, or should we check for changes in the bounds?

Comment thread mypy/newsemanal/semanal.py Outdated
# self.defer().
analyzed = AnyType(TypeOfAny.special_form)
# Type variables are special: we need to place them in the symbol table
# soon, even if upper bound is not ready yet.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why they need to be added to the symbol table soon?

Comment thread mypy/newsemanal/semanal.py Outdated
allow_placeholder=True)
if analyzed is None:
# Type variables are special: we need to place them in the symbol table
# soon, even if some value is not ready yet.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above: can you explain why?

@JukkaL
Copy link
Copy Markdown
Collaborator

JukkaL commented Jun 26, 2019

Oh and feel free to merge when you've addressed my comments.

@ilevkivskyi
Copy link
Copy Markdown
Member Author

Travis hook seems to be stuck, all tests have passed, so I am merging this now.

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.

New semantic analyzer: regression with circular import and TypeVar

2 participants