Incompatible function override in InlineProcessor
#1472
Description
Hello! I was creating a custom extension that uses an InlineProcessor
to implement custom escape logic. This is what the function and class signature look like:
class EscapeInlineProcessor(InlineProcessor):
def handleMatch(self, m: Match[str], data: str) -> tuple[str | None, int, int]:
...
The type signature does not exactly match that of InlineProcessor.handleMatch
, but it is compatible. However, when type checking with mypy, I was getting the following error:
error: Signature of "handleMatch" incompatible with supertype "Pattern" [override]
note: Superclass:
note: def handleMatch(self, m: Match[str]) -> str | Element | None
note: Subclass:
note: def handleMatch(self, m: Match[str], data: str) -> tuple[str | None, int, int]
After digging around for a bit, I realized that the internal definition of InlineProcessor.handleMatch
is not compatible with its superclass's definition of Pattern.handleMatch
. The extra parameter is fine, but the return type is completely incompatible.
class Pattern:
def handleMatch(self, m: Match[str]) -> Element | str:
...
class InlineProcessor(Pattern):
def handleMatch(self, m: Match[str], data: str) -> tuple[Element | str | None, int | None, int | None]:
...
I have looked at some of the prior discussions regarding typings, and I understand that the general sentiment is that an entirely statically typed library is not desirable. That is not the issue here. The issue is one of ergonomics for developers using both mypy (and perhaps other static type checkers) and your library together. Having to use # type: ignore[override]
just to silence a bug coming from a dependency is frustrating and should not be necessary.
I would also like to mention that #1399 did have a fix for this issue, but the substitute PR #1401 failed to address this.