-
Notifications
You must be signed in to change notification settings - Fork 410
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
mypy cannot typecheck event classes decorated with @attrs_event #592
Comments
I've been wanting to enable Same with No matter what, we could also just drop Python 3.5 support, and then we wouldn't have to generate the conditional |
So for my use case, I was just talking about using mypy on a project which depends on fbchat, not using mypy on fbchat itself. I performed my tests by editing the code for fbchat in my project's venv. I tested using 1) kw_only=True and 2) kw_only=kw_only, and in both cases my project's code would typechecked after making those changes. In both cases I also cleared my mypy cache before typechecking. I just repeated test 2) by cloning fbchat from github, changing # Test creating an event
def copyMessageEvent(self, event: fbchat.MessageEvent):
return fbchat.MessageEvent(
thread=event.thread, author=event.author, message=event.message, at=event.at
)
# Test creating an event with incorrect args (should not type check)
bad_message = fbchat.MessageEvent(
thread="not a thread",
author="not a user",
message="not a message",
at="not a datetime",
)
# Test inheriting
@attr.s
class MyEvent(fbchat.MessageEvent):
def makeMyEvent(self, event: fbchat.MessageEvent):
return MyEvent(
thread=event.thread, author=event.author, message=event.message, at=event.at
) I committed the changes to the event code, so I can test mypy on test.py with or without my changes applied. Without my changes, I get the "Unexpected keyword argument..." errors for each use of With my changes, I no longer get type errors for Further investigations into kw_only=kw_onlyI do get more mypy errors for the files I changed, because of the use of kw_only=kw_only. But I'm guessing when mypy typechecks third-party imports, it only collects type information necessary for typechecking and ignores any errors it finds in the third-party code. mypy doesn't need to parse kw_only in order to collect the necessary type info to typecheck test.py. mypy parsing kw_only is only necessary to reject the following code: def copyMessageEvent_no_kw(self, event: fbchat.MessageEvent):
return fbchat.MessageEvent(event.author, event.thread, event.message, event.at) Before my changes, this does not typecheck, failing with "Too many arguments for "MessageEvent"". After my changes, this typechecks, but since kw_only evaluates to True, it shouldn't. This code will fail at runtime, because fbchat.MessageEvent doesn't accept positional arguments. If I replace all the occurrences of kw_only=kw_only to kw_only=True in the events code, then mypy will correctly reject the code, so that's what mypy needs to be able to parse kw_only for So I guess there is a tradeoff here:
In either situation it's possible to create a runtime error because of faulty typechecking. However, I think it's worth it to replace @attrs_event, because it's less likely someone will try to create an event without using kwargs, since that's not used in any examples. Sorry this got so long, and thanks for your time maintaining this package! |
Description of the problem
Due to a known bug/missing feature in the mypy plugin for attrs, mypy cannot correctly infer keyword arguments for a class which is decorated with @attrs_event, or inherits from a class decorated with @attrs_event.
The relevant issues on mypy: python/mypy#5406
Two related issues: python-attrs/attrs#594, python/mypy#6239
There are workarounds provided in the issues. However, as a quick fix, it's possible to just replace all instances of @attrs_event with @attr.s(slots=True, kw_only=kw_only, frozen=True), after which mypy seems to typecheck fine. Since the @attrs_event decorator is not exported from fbchat anyway, this seems like an acceptable fix,
While this project doesn't seem to use mypy, it would be nice to fix this so that other projects that use fbchat can use mypy. It's a shame having type hints in fbchat that can't be leveraged by dependants.
For now, I can just workaround with
# type: ignore
, but this means I can't get the benefit of typechecking for any events I subclass from those provided by fbchat.Code to reproduce
Traceback
Environment information
fbchat
version 2.0.0a2The text was updated successfully, but these errors were encountered: