-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
stubgen: generate valid dataclass stubs #15625
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.
Please, add test cases for:
InitVar
annotationdataclass()
with other keywords, not onlyinit=False
- Fields defined with
= field()
(it is special enough to be tested) _: dataclasses.KW_ONLY
mark
[out] | ||
from dataclasses import dataclass | ||
|
||
@dataclass |
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 that init=False
is assumed here.
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.
According to the dataclass documentation,
init: If true (the default), a
__init__()
method will be generated.
If the class already defines__init__()
, this parameter is ignored.
So it is ignored in this case. This was not the goal of the test anyway, it was to test that user defined methods are always included in the stub.
We cannot safely remove `__init__` and depend on the plugin because its signature depends on dataclass field assignments to `dataclasses.field` and these assignments are not included in the stub
Thanks for the review, I added more tests.
Added more keywords in the tests but the goal of the test is make sure keywords are not stripped out and call expressions are recognized as dataclasses, it is not to test each keyword individually as they are all handled the same way.
Thanks. Since a
It was indeed special because it was considered private name, added a test. |
Hmm, how can I restrict a stubgen test case to a certain python version? |
Sorry to ping you @sobolevn. Could you please take another look? This came up again in a new project of mine. Thank you |
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.
Thank you!
i: InitVar[str] | ||
j: InitVar = ... | ||
non_field = ... | ||
def __init__(self, a, b, f, g, h, i, j) -> None: ... |
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.
Sorry to comment on an old, merged PR, but I wanted to ask if it's expected that the arguments to __init__()
are missing type annotations in the generated stub.
If I install this stub and then try to typecheck
X(a="foo", ...)
I would expect mypy to error with
error: Argument "a" to "X" has incompatible type "str"; expected "int" [arg-type]
but instead it passes (I think the type annotation for a
is implicitly Any
when it's not annotated in the signature, which is incorrect I think - I think the type of a
should be int
, not Any
).
Let me know if this is actually better positioned as a new issue (with reproducible example etc.), but I just wanted to see if I was missing something obvious before opening a new one.
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.
Stubgen doesn't use inferred types of parameters in generated stubs unless it sees a parameter with a primitive default value. You'll always need to tweak the generated stubs by hand if you want better experience with the type checker.
Also note that the __init__
method can be safely deleted from the stub most of the time. It is included because a field declaration like some_field: int = field(init=False)
that affects the signature of __init__
cannot be currently represented in the stub.
With that being said, I agree that perhaps we can do better but I am not a mypy maintainer. So yes please open a new issue asking for this feature.
Fixes #12441
Edit:
Also fixes #9986
Edit 2:
Fixes #15966