From e99db3da05b939acc4e88aac466e95f048098743 Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Fri, 3 Nov 2023 18:06:55 +0100 Subject: [PATCH] Markdown: add fake base class to Pattern to fix overrides Currently `InlineProcessor` and every subclass of it violates the `override` rule as per Liskov Substitution Principle. Signature of "handleMatch" incompatible with supertype "Pattern" [override] Superclass: def handleMatch(self, m: Match[str]) -> Element | str Subclass: def handleMatch(self, m: Match[str], data: str) -> tuple[Element | str | None, int | None, int | None] For all *usage* purposes these aren't actual subclasses to one another, they're handled totally separately inside `__applyPattern`. However yes, this change totally disagrees with actual `isinstance` checks at run time (though even that is still for the best). --- stubs/Markdown/markdown/core.pyi | 2 +- stubs/Markdown/markdown/extensions/smarty.pyi | 2 +- stubs/Markdown/markdown/inlinepatterns.pyi | 12 +++++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/stubs/Markdown/markdown/core.pyi b/stubs/Markdown/markdown/core.pyi index d8f7152ca25a..23374f8406fc 100644 --- a/stubs/Markdown/markdown/core.pyi +++ b/stubs/Markdown/markdown/core.pyi @@ -21,7 +21,7 @@ class _ReadableStream(Protocol): class Markdown: preprocessors: Registry[preprocessors.Preprocessor] - inlinePatterns: Registry[inlinepatterns.Pattern] + inlinePatterns: Registry[inlinepatterns.InlineProcessor | inlinepatterns.Pattern] treeprocessors: Registry[treeprocessors.Treeprocessor] postprocessors: Registry[postprocessors.Postprocessor] parser: blockparser.BlockParser diff --git a/stubs/Markdown/markdown/extensions/smarty.pyi b/stubs/Markdown/markdown/extensions/smarty.pyi index b3706d99afd2..d8d19ad8afe7 100644 --- a/stubs/Markdown/markdown/extensions/smarty.pyi +++ b/stubs/Markdown/markdown/extensions/smarty.pyi @@ -38,6 +38,6 @@ class SmartyExtension(Extension): def educateEllipses(self, md: Markdown) -> None: ... def educateAngledQuotes(self, md: Markdown) -> None: ... def educateQuotes(self, md: Markdown) -> None: ... - inlinePatterns: util.Registry[inlinepatterns.Pattern] + inlinePatterns: util.Registry[inlinepatterns.InlineProcessor | inlinepatterns.Pattern] def makeExtension(**kwargs) -> SmartyExtension: ... diff --git a/stubs/Markdown/markdown/inlinepatterns.pyi b/stubs/Markdown/markdown/inlinepatterns.pyi index ea4f415ac0d4..e24c367b6c85 100644 --- a/stubs/Markdown/markdown/inlinepatterns.pyi +++ b/stubs/Markdown/markdown/inlinepatterns.pyi @@ -6,7 +6,7 @@ from xml.etree.ElementTree import Element from markdown import util from markdown.core import Markdown -def build_inlinepatterns(md: Markdown, **kwargs) -> util.Registry[Pattern]: ... +def build_inlinepatterns(md: Markdown, **kwargs) -> util.Registry[InlineProcessor | Pattern]: ... NOIMG: str BACKTICK_RE: str @@ -39,21 +39,23 @@ class EmStrongItem(NamedTuple): builder: str tags: str -class Pattern: +class _BasePattern: ANCESTOR_EXCLUDES: ClassVar[Collection[str]] pattern: str compiled_re: re.Pattern[str] md: Markdown def __init__(self, pattern: str, md: Markdown | None = None) -> None: ... def getCompiledRegExp(self) -> re.Pattern[str]: ... - def handleMatch(self, m: re.Match[str]) -> str | Element | None: ... def type(self) -> str: ... def unescape(self, text: str) -> str: ... -class InlineProcessor(Pattern): +class Pattern(_BasePattern): + def handleMatch(self, m: re.Match[str]) -> str | Element | None: ... + +class InlineProcessor(_BasePattern): safe_mode: bool def __init__(self, pattern: str, md: Markdown | None = None) -> None: ... - def handleMatch(self, m: re.Match[str], data) -> tuple[Element, int, int] | tuple[None, None, None]: ... # type: ignore[override] + def handleMatch(self, m: re.Match[str], data: str) -> tuple[Element, int, int] | tuple[None, None, None]: ... class SimpleTextPattern(Pattern): ... class SimpleTextInlineProcessor(InlineProcessor): ...