You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Enhance stubgen to include types for @dataclass private methods #9986
Methods generated by the @dataclass decorator are missing type annotations
The optional argument is not marked as a default argument (i.e. an = ... is missing)
At least the first issue (maybe the second too) is caused by the fact that __init__ is not present in the original code but generated by mypy.plugins.dataclasses. stubgen uses the original/unanalyzed code for adding type annotations to the functions it outputs (see https://github.com/python/mypy/blob/master/mypy/stubgen.py#L625-L626) but this doesn't exist in the case of these generated methods, so we end up without type annotations at all.
The generated methods still provide "analyzed" type information and I tried naively patching stubgen to use that, which resulted in:
Now there are type annotations and they are also correct, but the right imports (builtins and Union) are missing. I'm not sure if it is viable to try to add them. For this special case it seems easy enough, but what if we were dealing with custom classes defined in some other module?
Maybe a more feasible approach would be to simply leave the @dataclass decorator in the generated type stubs. If stubgen would output this:
stubgen needs to retain the @dataclass decorator. This seems easy enough to me.
stubgen needs to stop emitting the generated dataclass methods (like __init__, __lt__, ...). Maybe there is a way to disable the mypy.plugin.dataclasses plugin when we analyze the code for stubgen?
The = ... needs to be added for fields that have default values. This would require extra logic to differentiate between stuff like optional: int = field(default=1) and required: int = field(init=True).
Thanks for the analysis! I also think leaving @dataclass in the stub is the right approach. Type checkers are expected to support @dataclass decorators in stubs.
Activity
teskje commentedon Aug 18, 2021
At the moment,
stubgendoesn't seem to handle dataclasses very well in general. I've looked into this a bit.With the current master branch, if I generate stubs for this dataclass:
It outputs:
The issues are:
@dataclassdecorator are missing type annotationsoptionalargument is not marked as a default argument (i.e. an= ...is missing)At least the first issue (maybe the second too) is caused by the fact that
__init__is not present in the original code but generated bymypy.plugins.dataclasses.stubgenuses the original/unanalyzed code for adding type annotations to the functions it outputs (see https://github.com/python/mypy/blob/master/mypy/stubgen.py#L625-L626) but this doesn't exist in the case of these generated methods, so we end up without type annotations at all.The generated methods still provide "analyzed" type information and I tried naively patching stubgen to use that, which resulted in:
Now there are type annotations and they are also correct, but the right imports (
builtinsandUnion) are missing. I'm not sure if it is viable to try to add them. For this special case it seems easy enough, but what if we were dealing with custom classes defined in some other module?Maybe a more feasible approach would be to simply leave the
@dataclassdecorator in the generated type stubs. If stubgen would output this:... then everything should work nicely, no?
To get there, the following needs to change:
stubgenneeds to retain the@dataclassdecorator. This seems easy enough to me.stubgenneeds to stop emitting the generated dataclass methods (like__init__,__lt__, ...). Maybe there is a way to disable themypy.plugin.dataclassesplugin when we analyze the code for stubgen?= ...needs to be added for fields that have default values. This would require extra logic to differentiate between stuff likeoptional: int = field(default=1)andrequired: int = field(init=True).JelleZijlstra commentedon Aug 18, 2021
Thanks for the analysis! I also think leaving
@dataclassin the stub is the right approach. Type checkers are expected to support@dataclassdecorators in stubs.Cireo commentedon Aug 25, 2021
That approach works for me too, seems like a good separation of responsibilities.
MinsungKim-BlockCrafters commentedon Oct 7, 2022
I tested following code with Mypy 0.961. The issues @teskje said still persists.
By the way, why there is no
--versionparameter on stubgen?stubgen: generate valid dataclass stubs (#15625)