-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
False positive unnecessary-dunder-call
when overriding dunder method
#6074
Comments
@jacobtylerwalls apologies, this was an oversight on my behalf. Let's update C2801 so that it only raises iff there is no alternate operator (current behaviour) AND the dunder method is not being called on Will pull together a PR for this now 😄 |
Thanks @jpy-git! The last change (to exclude I'm just wondering if it would make sense to also exclude calls to names other than class CustomRegistry(dict):
def __init__(self) -> None:
super().__init__()
self._entry_ids = {}
def __setitem__(self, key, entry) -> None:
super().__setitem__(key, entry)
self._entry_ids.__setitem__(entry.id, entry) # !
...
def __delitem__(self, key: str) -> None:
entry = self[key]
self._entry_ids.__delitem__(entry.id) # !
super().__delitem__(key)
# ----
class CustomState(State)
def __init__(self, state):
self._state = state
def __eq__(self, other: Any) -> bool:
...
return self._state.__eq__(other) # !
# ----
class CustomDict(OrderedDict):
def __init__(self, *args, **kwds):
OrderedDict.__init__(self, *args, **kwds)
...
def __setitem__(self, key, value):
OrderedDict.__setitem__(self, key, value) # !
... -- class A:
def __getattr__(self, name):
...
return self.__getattribute__(name) |
So the first example isn't a false positive (at least by the current definition). The class CustomRegistry(dict):
def __init__(self) -> None:
super().__init__()
self._entry_ids = {}
def __setitem__(self, key, entry) -> None:
super().__setitem__(key, entry)
self._entry_ids[entry.id] = entry
...
def __delitem__(self, key: str) -> None:
entry = self[key]
del self._entry_ids[entry.id]
super().__delitem__(key) Likewise in the second case this is fine: class CustomState(State):
def __init__(self, state):
self._state = state
def __eq__(self, other: Any) -> bool:
...
return self._state == other |
Think there's a typo in that third case, you'll need a class CustomDict(OrderedDict):
def __init__(self, *args, **kwds):
OrderedDict.__init__(self, *args, **kwds)
...
def __setitem__(self, key, value):
OrderedDict.__setitem__(self, key, value)
... It's slightly oddly written as given that class structure this should probably be written class CustomDict(OrderedDict):
def __init__(self, *args, **kwds):
super().__init__(*args, **kwds)
...
def __setitem__(self, key, value):
super().__setitem__(key, value)
... This one does seem like a false positive so another exception would be calling the dunder method on an uninstantiated class and manually passing As noted above though |
Yeah this one's tricky! When invoking I'd probably suggest the pragmatic approach here is that we exclude these two dunder methods from |
Technically true, however the way I see it is that reasoning about a dunder method is much easier if the same method names are used in the body. You just don't have to think that much if inside a
What about a more general approach? I believe we do get the most value of this check for normal functions / methods. What about skipping dunder methods itself all together? That way, we don't need to special case --
👍🏻 Got lost in copy - past and trying out
In this case yes, |
Thanks for elaborating!
Yeah that seems a pretty sensible suggestion 😄 class CustomRegistry(dict):
def __setitem__(self, key, entry) -> None:
super().__setitem__(key, entry) # This is fine
def some_non_dunder_method(self, key, entry) -> None:
super().__setitem__(key, entry) # This is flagged
Makes sense, I've fixed this case in #6142 ☝️ |
Exactly. At least that's what I was thinking of. |
Yeah the reason there was a |
Will update #6142 to reflect this 👌 |
Bug description
Configuration
No response
Command used
Pylint output
Expected behavior
No message, since the example cannot be rewritten as
return item in super()
:This wasn't happening for
__init__
because it was allow-listed, but I think all dunder methods could be overridden in subclasses, so they all need to be made compatible withsuper().__...
Pylint version
OS / Environment
No response
Additional dependencies
No response
The text was updated successfully, but these errors were encountered: