Issue
My method requires an object with the attribute pattern
and the function handle
. To this end, I wrote a Protocol
instance with these two members. Consider the following code:
class Handler(typing.Protocol):
"""Handler protocol"""
pattern: re.Pattern
@staticmethod
def handle(match: re.Match) -> str:
pass
def f(obj: Handler, text: str):
output = []
for match in re.finditer(obj.pattern, text):
output.append(obj.handle(match))
return output
class MyHandler(Handler):
pattern = re.compile("hello world")
@staticmethod
def handle(match: re.Match) -> str:
return "hi there"
f(MyHandler, 'hello world, what a nice morning!')
However, when I call this function with MyHandler
, my IDE (PyCharm) issues the following warning:
Expected type 'ReplacerProtocol', got 'Type[CitationReplacer]' instead
This warning goes away when I remove the pattern
attribute from the protocol class. When I change the protocol to require a @property
or a function with the name pattern
, the same warning is issued.
What is the correct way to define my interface in Python?
Solution
As per suggested by Sterliakov, I made edits to my code. I removed the use of @property in the implementation of MyHandler as it was deemed unnecessary for the protocol. Additionally, I incorporated generics (re.Pattern[str] and re.Match[str]) as advised.
import typing
class Handler(typing.Protocol):
"""Handler protocol"""
pattern: re.Pattern[str]
@staticmethod
def handle(match: re.Match[str]) -> str:
...
def f(obj: Handler, text: str) -> list[str]:
output = []
for match in re.finditer(obj.pattern, text):
output.append(obj.handle(match))
return output
class MyHandler:
pattern: re.Pattern[str] = re.compile("hello world")
@staticmethod
def handle(match: re.Match[str]) -> str:
return "hi there"
result = f(MyHandler(), 'hello world, what a nice morning!')
print(result)
Answered By - Umar
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.