-
-
Notifications
You must be signed in to change notification settings - Fork 162
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
Fix and improve pygame.typing
module
#3080
Conversation
To use mypy you can pip install it and run the file inside buildconfig called stubcheck.py. remember to install your branch locally before doing so. I will do that for this changes on my machine too |
The mypy on CI is failing with the following error
|
I think I fixed the error (caused by bad type inference). I'd like to hear your thoughts on two possible removals: Remove Remove `PathLike` union type
@damusss, one question, what is the reasoning behind |
So this PR brings up a question for me. Do we need type stub files for python modules, or can we just put type information into python source for those modules?
This part of https://peps.python.org/pep-0561/ makes me think no. Rather than a typing.pyi we can put it with the runtime? And @Matiiss can make sprite groups (#3053) typed in the normal way in the python source instead of needing to worry without the difference between source and stubs? |
Although @zoldalma999 is working on putting docstrings into stubs (or something like that), so maybe it's advantageous to keep them. |
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.
I think your older commit that added the [(3, 3.2), pygame.Vector2()]
testcase was technically acceptable. If the typechecker is rejecting it, then I believe there is a bug somewhere
I agree, this change should not have user facing consequences I believe |
@aatle PathLike didn't exist in the os library before python 3.9, that's the reason |
I can side with this, but note that it would require quite a bit of effort to move all Python source typing from the stubs to the source code, but I'm not against it. However, it does mean that all the protocol stuff will have to be implemented in the source code as well, which I'm not against either and it will help expose all these internal types to the end user, but it's just something to be noted. This also means that |
I checked and it's only used inside rwobject.pyi, so I guess you can add the current value of PathLike inside FileLike and define PathLike internally just for rwobject.pyi only (prefixed by an underscore, similar to how formats are annotated for pygame.image). You might want the opinion of the steering council aswell on this one, since PathLike depends on os.PathLike which is not available before 3.9, and _typeshed is not a valid module at runtime. |
There are a few reasons why it is preferable to have separate
About your quote from PEP 561, I don't think it is relevant to the question. It refers to what type checkers like mypy should do, not programmers. It does not say to combine the stub files with source files; rather, it says to combine the stub directories with source directories. (Equivalent to putting all of the |
The error was a result of normal assumptions and inferences by mypy. Mypy, when seeing an unannotated list with multiple types inside, will find a common base class to use (not a union). In this case, it chooses |
@damusss I must be missing something, wasn't |
@aatle my bad, what I said was BS, but there's still an issue before 3.9: |
Ahh, okay. I had actually found that reason before but forgot and couldn't remember. from os import PathLike as _PathProtocol
if sys.version_info >= (3, 9):
PathLike = Union[str, bytes, _PathProtocol[str], _PathProtocol[bytes]]
else:
# os.PathLike is not generic in python 3.8
PathLike = Union[str, bytes, _PathProtocol] |
@aatle I don't think so. Without specifying str or bytes, one could make this code and it would pass, which is obviously wrong: class MyPath:
def __fspath__(self) -> int: return 0
pygame.rwobject.encode_string(MyPath()) # or whatever function that needs PathLike I checked and mypy passes. |
I like this solution you just posted.
Yeah this makes sense, thanks for the explanation. Now I'm wondering if this can somehow be fixed by declaring |
@damusss @ankith26 Probably not 'fixable', it is a small and easily fixable issue, and we shouldn't require |
Need more opinions on removal of |
@aatle what exactly do you mean with typeshed version? Also I don't disagree with the removal of PathLike if the SC if ok with it. |
@damusss, if I understand correctly, the standard library alone does not have type hints (such as for what the return value of |
@aatle but what exactly is the typeshed? _typeshed.pyi does not exist at runtime |
I mean https://github.com/python/typeshed, according to the info in the readme. E.g. https://github.com/python/typeshed/blob/main/stdlib/os/__init__.pyi |
I think for the purposes of this PR, we should retain |
@aatle I just realized you can probably import StrOrBytesPath from _typeshed by guarding it inside a typing.TYPE_CHECKING block. not sure it would work in 3.8 but it's worth a try. |
I'm going to wrap up this PR for merging. |
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.
I agree to keep this PR as bugfix/improvement, and modify the API in other PRs.
I've looked at the code and tested locally, LGTM! 👍
Thank you for improving my beloved module :)
(do you think abstractmethod can be del
eted at the end of the file? just wondering)
Yes, it can. I'll just add that in real quick. |
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.
LGTM, thanks for contributing! 🥳
Fixes and changes from #3074 and more. (Addresses various typing problems about correctness.)
This draft includes all of my proposed fixes, though some of them may need more discussion.
I wasn't able to fully test with mypy because of my current setup.
Also, perhaps an
__all__
list can be created for thistyping
module?