-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 for unnecessary-ellipsis
on Protocol
methods
#9319
Comments
Hi!
However, mypy does not notify anything with and without the ellipsis. For Pylint it is just a warning, so I prefer to disable the pylint warning on the line of the ellipsis. Regards. |
To make this actionable: See the discussion in The discussion also says something about them not being unused in methods with Perhaps @erictraut can help me understand why this would be needed. And also comment on whether there is any effort on getting this spelled out in the typing spec. I'm very sympathetic to the arguments of Sorry Eric for the ping, I think you're the best person I know to reflect on this issue. |
In a protocol or abstract class, if a method has an implementation, it can't be an abstract method, because this is a non sense. So this method can be overridden in an implementation class, but this is not mandatory, contrary to an abstract method. It is useful to provide an implementation of a method in a protocol or an abstact class for several cases:
|
Thanks for that explanation @vtgn but that doesn't really answer my question. Specifically I'm wondering why you would ever need: from abc import ABC, abstractmethod
class A(ABC):
@abstractmethod
def method(self) -> str:
return "This is a base implementation" Having a base implementation on something that is decorated with @abstractmethod
def method(self) -> str:
"""Implement this method in the subclass"""
...
@abstractmethod
def method(self) -> str:
"""Implement this method in the subclass""" With the |
@DanielNoord Personally I find this totally illogical, because by definition, an abstract method has no implementation. I've just tested, and even if a method decorated by abstractmethod has a default implementation, the method is still considered as abstract in the subclass, so the subclass is also considered as abstract if it doesn't override the method. In fact, the only definition of an abstract method is a method decorated by abstractmethod: the methods not decorated by abstractmethod and having empty, pass or ... body are not considered as abstract. You can check it at runtime by watching the In addition, at runtime a method with an empty, pass or ... body is callable without any error and returns None. And a protocol class always raises an error if you try to instantiate it, but you can call class methods and static methods on it. Impossible to find an official definition and specification for the use of the ellipsis as method's body. :/ Same for empty bodies. For the use of the pass : def f(arg): pass # a function that does nothing (yet)
class C: pass # a class with no methods (yet) Source: https://docs.python.org/3.13/reference/simple_stmts.html#the-pass-statement This lack of specification and definition forces the linters developers to choose their own, or else if they don't want to choose, they must accept and consider all these cases the same way as during code execution (i.e they return None) and so check typing as it. The only official definition we have is the one of "pass" (see above). It's purely a syntactic feature useful only to fix syntax problems in the cases for which nothing must be executed. I think that an empty body should be considered the same, but only when there is no syntax problem, for example when a method docstring block is written. This definition of pass (and so of empty body) allows to use it for:
According to ChatGPT: So by taking into account all these informations:
1.2. For implemented abstract methods (i.e. decorated by abstractmethod):
1.3. For non abstract methods (i.e. not decorated by abstractmethod)
2.1. For unimplemented abstract methods (i.e. decorated by abstractmethod):
2.2. For implemented abstract methods (i.e. decorated by abstractmethod):
2.3. For unimplemented non abstract methods
2.4. For implemented non abstract methods:
As you can see, there are several ambiguities in these specifications, so choices must be done by the linters:
These 3 ambiguities have the same origin: impossible to determine if the method is unimplemented or implemented. So the linters must take a decision for each case to choose if it means the method is unimplemented or implemented. And it would be better if they all choose the same decision, and so if an official Python specification does it. Is it possible to make a demand? |
@vtgn, I agree that this is an area that would benefit from standardization. The Python typing spec is probably the best place to do this. We (members of the Python typing community) have made good progress in the past year augmenting and clarifying the typing spec, but there is more work to do. I recently gave a talk where I proposed a list of priorities for the typing spec. The topic of "unimplemented methods (in protocols and ABCs)" is on that list, but I don't think anyone has made progress in that area yet. If you or someone else would like to spearhead the effort to document and ratify a standard in this area, here is the process you can follow. As a start, you could create a new discussion in the Python typing forum. |
This comment has been minimized.
This comment has been minimized.
I think one of the issues we would face in writing this spec is that it is incredibly hard to separate the linting concerns and the type checking. |
This comment has been minimized.
This comment has been minimized.
For me, implementing an abstract method should be forbidden because it is a non sense. This fixes the ambiguities 1 and 2. |
While we wait for Python specifiers to decide, I think @DanielNoord is right, and the linters should apply what I said on my previous comment:
|
Bug description
pyright
uses...
to determine the body of this method is not implemented here. Without using...
,pyright
rightfully (IMHO, as is the only way it has to know the user is intentionally omitting the body) complains about a missing return to match the declared return type of the function.Example:
When removing the
...
pylint passes bypyright
says:Configuration
None.
Steps to reproduce:
Command used
`pylint t.py`
Pylint output
Expected behavior
No failures.
Pylint version
OS / Environment
Debian testing
Additional dependencies
The text was updated successfully, but these errors were encountered: