FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix crash on overriding class level type alias by ilevkivskyi · Pull Request #5662 · python/mypy · GitHub

Repository navigation

Fix crash on overriding class level type alias - #5662

Closed
ilevkivskyi wants to merge 1 commit into
python:masterfrom
ilevkivskyi:fix-alias-over
Closed

ilevkivskyi wants to merge 1 commit into
python:masterfrom
ilevkivskyi:fix-alias-over

Conversation

Copy link
Copy Markdown
Member

Fixes #5425

The solution is to just prohibit overriding type aliases in subclass. In some sense they are implicitly final, because we need to know them statically (they can be used as type sin annotations).

The assert that was triggered missed two cases for superclass node: TypeAlias and Var, for Var I just return Any since there are no way to determine type if deferring failed (currently there is fixed number of type-checking passes).

JukkaL left a comment

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I'm a little worried that doesn't fix all related issues (see comments).

Comment thread mypy/checker.py
base_type = base_var.type

if isinstance(base_node, TypeAlias):
return None, base_node

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Slightly unrelated: Could you update the docstring to describe the return value? Now it's not immediately clear why this is correct.

Comment thread mypy/checker.py
elif isinstance(original_node, Decorator):
original_type = self.function_type(original_node.func)
elif isinstance(original_node, Var):
original_type = AnyType(TypeOfAny.implementation_artifact)

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

It's not clear to me how this is related to the title of the PR, but the description seems to indicate that this fixes another, related issue with Var nodes. Maybe tweak the title of the PR?

Also, this looks like it could cause false negatives. It's better than crashing, but maybe we should generate a "Cannot determine type" error instead? At least there should be a comment about this, and potentially a follow-up issue.

Comment thread mypy/checker.py
# it can be checked for compatibility.
original_type = base_attr.type
original_node = base_attr.node
if isinstance(original_node, TypeAlias):

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Should we reject other kinds of nodes as well, such as TypeInfo, TypeVarExpr or module reference? Some of these could cause crashes as well. It would be good to fix other related issues at the same time.

I think that it would be best to check all combinations of base class and subclass definitions, such as 1) type alias 2) class 3) function 4) variable 5) type variable 6) module reference 7) other magic assignments (NewType or NamedTuple or TypedDict). Some of these are already tested, so they can be left out (like function vs function).

Comment thread mypy/checker.py

base_type, base_node = self.lvalue_type_from_base(lvalue_node, base)

if isinstance(base_node, TypeAlias):

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Similar to above, should we check for other kinds of things that shouldn't be overridden?

Why do we this check in two places? If we need to have the check in two places, it may be slightly better to move it to a helper method instead of repeating the code, at least if the check becomes more complex.

foo = Callable[..., int]

class Child(Parent):
foo: Callable[..., int] # E: Cannot override type alias "foo" defined in base class "Parent"

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I'd merge all these test into a single test case. Having many test cases that test almost the same thing arguably doesn't help maintainability but is kind of expensive to run.

Copy link
Copy Markdown
Member Author

Should we reject other kinds of nodes as well, such as TypeInfo, TypeVarExpr or module reference? Some of these could cause crashes as well. It would be good to fix other related issues at the same time.

I think that it would be best to check all combinations of base class and subclass definitions, such as 1) type alias 2) class 3) function 4) variable 5) type variable 6) module reference 7) other magic assignments (NewType or NamedTuple or TypedDict). Some of these are already tested, so they can be left out (like function vs function).

Yes, indeed, there are much more problems here:

  • There are actually three places where we check Liskov: assignments, function definitions, and multiple inheritance, all with slightly different logic that causes some code duplication and is generally fragile.
  • Indeed other (more "exotic") kinds of nodes are not treated carefully in all these places, causing some other issues, like Multiple inheritance: Cannot determine type of "X" in base class "Y" error #2871

I don't think however I want to open this can of worms, we can look at it later when we will have time.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Overriding definition such as type alias in a subclass causes a crash

2 participants


Back | FazBrowse Home | New Git URL