-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Pygments: fix get_style_by_name return type #9803
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Hmm, the It's interesting that you say in PrairieLearn/PrairieLearn#7185 (comment) that this fixes a pyright issue in that PR -- I thought type checkers were generally pretty grumpy with you if you had a dynamic base class of any kind, anywhere. |
(Cc. @Akuli, who contributed these stubs and is also the maintainer of |
What is the reason for changing this? What is the practical problem that this PR solves? |
@Akuli This PR makes the type information reflect what actually happens at runtime, which is that |
it is annotated as returning an instance of StyleMeta though, which is (approximately) the same as returning |
The old annotation is correct, because the returned type is an instance of
It seems to me that this PR introduces one practical problem without solving other practical problems, while from a theorethical point being equally correct as the old annotation. |
Sorry, I somehow missed that you mentioned inheriting from the returned object. It is going to be annoying for someone either way: if we return I'm fine with merging this, and equally fine with not merging this. |
Hmm, I'm admittedly not a Python expert. Is the issue I'm hitting when trying to treat the return value as a type a limitation of type checkers, or the types, or something else? Or is Pygments trying to be overly clever by making something both a class and an iterable? |
I think these are just type checker limitations. As I understand it, the current annotations will make it so Pyright doesn't let you inherit from the returned class, and the PR's annotations will make it so that mypy doesn't let you iterate over the returned class even though it is iterable. Neither issue is obviously worse than the other, so I'd prefer to stick with the current annotations so we don't introduce churn for users. If mypy or pyright change their behavior here, we can reconsider. |
To me, it is both pygments being overly clever, and limitations of type checkers. Ideally libraries wouldn't try to make classes iterable :) Maybe the correct solution would be to make mypy recognize |
This might already be implemented on mypy master actually, via: |
It is fixed on mypy master. Let's wait for the next mypy release and then merge :) I checked locally by mypying this script: from typing import Iterator
class StyleMeta(type):
def __iter__(self) -> Iterator[str]:
yield 'a'
yield 'b'
yield 'c'
class Style(metaclass=StyleMeta):
pass
x: type[Style] = Style
lel = iter(x) On mypy's |
The next mypy release should hopefully be coming out in the next week or so: |
Closing and re-opening to run mypy_primer again. |
Diff from mypy_primer, showing the effect of this PR on open source code: sphinx (https://github.com/sphinx-doc/sphinx)
- sphinx/highlighting.py:114:20: error: Incompatible return value type (got "StyleMeta", expected "Style") [return-value]
+ sphinx/highlighting.py:114:20: error: Incompatible return value type (got "Type[Style]", expected "Style") [return-value]
|
As seen in the example from https://pygments.org/docs/styles/,
get_style_by_name
returns a class, not an instance: