Skip to content

Skip error if attribute or method is private to class #6790

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
Merged
Show file tree
Hide file tree
Changes from all commits
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
13 changes: 13 additions & 0 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,9 @@ def check_override(self, override: FunctionLike, original: FunctionLike,
if original_class_or_static and not override_class_or_static:
fail = True

if is_private(name):
fail = False

if fail:
emitted_msg = False
if (isinstance(override, CallableType) and
Expand Down Expand Up @@ -1649,6 +1652,8 @@ def check_multiple_inheritance(self, typ: TypeInfo) -> None:
# Normal checks for attribute compatibility should catch any problems elsewhere.
non_overridden_attrs = base.names.keys() - typ.names.keys()
for name in non_overridden_attrs:
if is_private(name):
continue
for base2 in mro[i + 1:]:
# We only need to check compatibility of attributes from classes not
# in a subclass relationship. For subclasses, normal (single inheritance)
Expand Down Expand Up @@ -1940,6 +1945,9 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, lvalue_type: Optional[
if lvalue_node.name() == "__slots__" and base.fullname() != "builtins.object":
continue

if is_private(lvalue_node.name()):
continue

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

if base_type:
Expand Down Expand Up @@ -4396,3 +4404,8 @@ def is_subtype_no_promote(left: Type, right: Type) -> bool:

def is_overlapping_types_no_promote(left: Type, right: Type) -> bool:
return is_overlapping_types(left, right, ignore_promotions=True)


def is_private(node_name: str) -> bool:
"""Check if node is private to class definition."""
return node_name.startswith('__') and not node_name.endswith('__')
31 changes: 31 additions & 0 deletions test-data/unit/check-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -5899,3 +5899,34 @@ class A:
class B:
@dec # E: Unsupported decorated constructor type
def __new__(cls, x: int) -> B: ...

[case testIgnorePrivateAttributesTypeCheck]
class B:
__foo_: int
class C(B):
__foo_: str
[out]

[case testIgnorePrivateMethodsTypeCheck]
class B:
def __foo_(self) -> int: ...
class C(B):
def __foo_(self) -> str: ...
[out]

[case testCheckForPrivateMethodsWhenPublicCheck]
class B:
__foo__: int
class C(B):
__foo__: str
[out]
main:4: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int")

[case testIgnorePrivateMethodsTypeCheck]
class A:
def __foo_(self) -> int: ...
class B:
def __foo_(self) -> str: ...

class C(A, B): pass
[out]