10000 Loosen base class attribute compatibility checks when attribute is redefined by syastrov · Pull Request #6585 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Loosen base class attribute compatibility checks when attribute is redefined #6585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10000 Prev Previous commit
Next Next commit
Remove extra newlines.
  • Loading branch information
syastrov committed Apr 10, 2019
commit 8adafdb664946e296c33739fca0bb56b9657e085
1 change: 0 additions & 1 deletion test-data/unit/check-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -4020,7 +4020,6 @@ class C(B):
[out]
main:6: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")
Copy link
Member

Choose a reason for hiding this comment

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

Same as above. A user might want to ignore the error once in the base class, instead of ignoring it in every subclass.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is slightly different than the above situation, as here, there was no error before.

I think it depends on how you want to interpret the # type: ignore.
In the current behavior, because B.x has an ignore, you are no longer warned when you redefine x in C.x that that redefinition is actually incompatible with ancestor's A.x.

A library author may have defined B.x with the ignore comment, and let us say that you are writing class C yourself. I would find it unexpected that because the library author chose to add an ignore comment on B.x that that would suppress a certain type of error when defining my own class.
I may not know in detail how B is defined/type-annotated, so I may reasonably expect that the type checker would perform its normal checks for my definition of class C (in this case, that it is compatible with A).

Are there other places in mypy where # type: ignore comments "spread" in that sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops:
(in this case, that it is compatible with A)
should be:
(in this case, that C.x is actually compatible with A.x)

Copy link
Member

Choose a reason for hiding this comment

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

Are there other places in mypy where # type: ignore comments "spread" in that sense?

Practically everywhere, an invalid type, a failed attribute access, an operator, or sometimes even failed function call, produce an Any type thus preventing subsequent errors.



[case testClassIgnoreType_RedefinedAttributeTypeIgnoredInChildren]
class A:
x = 0
Expand Down
11 changes: 2 additions & 9 deletions test-data/unit/check-multiple-inheritance.test
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,6 @@ class Combo(Base2, Base1): ...
main:10: error: Definition of "NestedVar" in base class "Base2" is incompatible with definition in base class "Base1"

[case testMultipleInheritance_NestedVariableOverriddenWithCompatibleType]

from typing import TypeVar, Generic
T = TypeVar('T', covariant=True)
class GenericBase(Generic[T]):
Expand All @@ -476,7 +475,6 @@ class A(Base1, Base2):
[out]

[case testMultipleInheritance_NestedVariableOverriddenWithIncompatibleType1]

from typing import TypeVar, Generic
T = TypeVar('T', covariant=True)
class GenericBase(Generic[T]):
Expand All @@ -488,10 +486,9 @@ class Base2:
class A(Base1, Base2):
Nested: GenericBase['Base1']
[out]
main:11: error: Incompatible types in assignment (expression has type "GenericBase[Base1]", base class "Base2" defined the type as "GenericBase[Base2]")
main:10: error: Incompatible types in assignment (expression has type "GenericBase[Base1]", base class "Base2" defined the type as "GenericBase[Base2]")

[case testMultipleInheritance_NestedVariableOverriddenWithIncompatibleType2]

from typing import TypeVar, Generic
T = TypeVar('T', covariant=True)
class GenericBase(Generic[T]):
Expand All @@ -503,11 +500,9 @@ class Base2:
class A(Base1, Base2):
Nested: GenericBase['Base2']
[out]
main:11: error: Incompatible types in assignment (expression has type "GenericBase[Base2]", base class "Base1" defined the type as "GenericBase[Base1]")

main:10: error: Incompatible types in assignment (expression has type "GenericBase[Base2]", base class "Base1" defined the type as "GenericBase[Base1]")

[case testMultipleInheritance_NestedVariableOverriddenWithCompatibleType]

from typing import TypeVar, Generic
T = TypeVar('T', covariant=True)
class GenericBase(Generic[T]):
Expand All @@ -520,8 +515,6 @@ class A(Base1, Base2):
Nested: GenericBase['Base1']
[out]



[case testMultipleInheritance_MethodDefinitionsCompatibleWithOverride]
from typing import TypeVar, Union
_T = TypeVar('_T')
Expand Down
0