-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Markdown: add fake base class to Pattern to fix overrides #10970
Conversation
This comment has been minimized.
This comment has been minimized.
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).
43593a4
to
e99db3d
Compare
|
This comment has been minimized.
This comment has been minimized.
I'm not sure we need the fake class. From what I understand, the inheritance hierarchy at runtime is That mypy has a bug/misfeature, where the classes derived from |
This comment has been minimized.
This comment has been minimized.
I agree with @srittau here. Having to I wouldn't do such a change just to remove a There is however, still an underlying issue that affects downstream users and is worth looking at: If it's common enough, then the base class should account for all of its expected subtypes' signature to get "correct" polymorphism. But that will lead you to the Union return issue (python/typing#566) def returns_processor() -> InlineProcessor: ...
def accepts_pattern(pattern: Pattern):
foo = pattern.handleMatch(...)
is_instance(foo, tuple) # Always false, currently type-checkers don't see that foo can be a tuple
accepts_pattern(return_processor()) A potential solution (not saying it's the right one, just throwing ideas) could be to expand the Union of |
@Avasam I can be fine with that position, but I think your comment does not really match real situations. All the problems really are just with writing subclasses (which is very common). |
I'm sorry I just noticed the subclass' method has an extra parameter, it's not just about return types. Yeah that's gonna be more problematic :/ |
Oh and by the way, it's not just an extra parameter, these two work completely differently to the point of being unrelated. Other than isinstance checks, the actual project would also definitely be better off with them being unrelated. |
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
Agree with @srittau that we shouldn't change this. |
Currently
InlineProcessor
and every subclass of it violates theoverride
rule as per Liskov Substitution Principle.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).I further describe this here: Python-Markdown/markdown#1402 (comment)
There are plenty of cases of existing ignores due to this already
https://github.com/search?q=%2FInlineProcessor%5C%29%2F+%2FhandleMatch.%2Bignore%2F+path%3A%2Fpy%24%2F+NOT+path%3Azerver&type=code