pylint
pylint copied to clipboard
protected-access false positive in class method of child class
Bug description
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,too-few-public-methods
class Parent:
def __init__(self):
self._foo = 1
@classmethod
def create_instance(cls):
return cls()
class Child(Parent):
def __init__(self):
super().__init__()
self._bar = 'a'
@classmethod
def create_instance(cls):
inst = super().create_instance()
inst._foo = 2 # protected-access warning here
inst._bar = 'b' # protected-access warning here
@classmethod
def create_instance2(cls):
inst = cls()
inst._foo = 3 # no warning here thanks to #4267
inst._bar = 'c' # no warning here thanks to #4267
def get_var(self):
return self._foo # no warning here
Configuration
No response
Command used
pylint test.py
Pylint output
************* Module test
test.py:18:8: W0212: Access to a protected member _foo of a client class (protected-access)
test.py:19:8: W0212: Access to a protected member _bar of a client class (protected-access)
------------------------------------------------------------------
Your code has been rated at 8.95/10 (previous run: 8.95/10, +0.00)
Expected behavior
This is a derived case from the circumstance addressed by #4267. That pull request addressed accessing a protected member on an instance created in a class method through a direct call to the cls
parameter. In this case, the derived class overrides the parent's class method, creates an instance by calling super() and then accesses the protected method on that instance. A child class's class method can access a protected member on an instance it creates directly, and it should also be able to access a protected member on an instance created in an overridden class method by a call to super().
Pylint version
pylint 3.0.3
astroid 3.0.2
Python 3.11.7 | packaged by conda-forge | (main, Dec 23 2023, 14:38:07) [Clang 16.0.6 ]
OS / Environment
MacOS Sonoma MacBook Pro M1 Max
Additional dependencies
none
This issue doesn't seem to have gotten any attention, but I'm adding another example with a regular (not class) method, including the __copy__
method, which seems like is a common case that pylint should be able to handle.
class Base:
def foo(self):
return self
def __copy__(self):
return type(self)()
class Child(Base):
def bar(self):
pass
def foo(self):
inst = super().foo()
inst.bar()
def __copy__(self):
inst = super().__copy__()
inst.bar()
running pylint -E on this code produces: test.py:14:8: E1101: Instance of 'Base' has no 'bar' member (no-member) test.py:18:8: E1101: Instance of 'Base' has no 'bar' member (no-member)