I am using Pylance with vscode and have set the type checking mode to 'strict'
My understanding is that Pylance should flag Bar as not conforming to the Foo Protocol because of the commented foo method in Bar, but it does not.
I if uncomment the line it does correctly complain that 'Method "foo" overrides class "Foo" in an incompatible manner'
Is there something I am missing?
from typing import Protocol
class Foo(Protocol):
def foo(self, a: str): ...
class Bar(Foo):
# def foo(self, b: str): ...
...
# The above code generates no errors, however the following line does
a: Foo = Bar() # this generates a 'Cannot instantiate abstract class "Bar"' error in pylance
# but the file does run cleanly
The bottom line here is all I want to do is say that Bar implements Foo and have Pylance tell me if it does not, before I let someone try to create an instance of it.
I am subclassing Foo for 2 reasons.
I am basing this on part of mypy documentation found here
As I said above, this works fine and flags incorrect method signatures right here in the file defining the Bar class. The only thing it does not do is flag the missing method. For that I can add something like the following:
bar: Foo = Bar()
This will highlight the missing method (because the Protocol makes Bar abstract), however it seems hacky to include this in the file defining Bar and also gets complicated if Bar has an __init__
function that takes several argument.
portion of mypy documentation linked above:
I found the solution I was looking for here.
Importing final
from typing and decorating the class that I expect to implement the full protocol with @final
does flag the missing method.
from typing import Protocol, final
class Foo(Protocol):
def foo(self, a: str): ...
@final
class Bar(Foo): #pylance error here
# def foo(self, b: str): ...
...
If I ever actually want to subclass Bar I can just ignore that type error.
class FooBar(Bar): # type: ignore - Bar is only marked final to ensure all protocol members are implemented
pass