Closed giannitedesco closed 3 years ago
Ah, it looks like mypy has a plugin to handle these types of classes, that makes sense: https://github.com/python/mypy/blob/master/mypy/plugins/dataclasses.py
What I did was add type-stubs based on the default dataclass type stubs in to my typeshed. Then I added dataclassy.dataclass
to dataclass_makers
in mypy/plugin/dataclasses.py
then it works well in simple cases.
Of course, that breaks things for the new inheritance features of dataclassy.
So it looks like the solution is in two parts:
py.typed
to dataclassy
dataclassy
in to the existing plugin, and then extend that pluggin to support dataclassy's inheritance (and any other?) features.For typeshed:
--- dataclasses.pyi 2020-10-31 02:10:14.585767164 +0900
+++ dataclassy.pyi 2021-02-03 11:30:54.065126147 +0900
@@ -19,7 +19,7 @@
def dataclass(_cls: None) -> Callable[[Type[_T]], Type[_T]]: ...
@overload
def dataclass(
- *, init: bool = ..., repr: bool = ..., eq: bool = ..., order: bool = ..., unsafe_hash: bool = ..., frozen: bool = ...
+ *, init: bool = ..., slots: bool = ..., repr: bool = ..., eq: bool = ..., order: bool = ..., unsafe_hash: bool = ..., frozen: bool = ...
) -> Callable[[Type[_T]], Type[_T]]: ...
class Field(Generic[_T]):
For mypy:
--- dataclasses.py.orig 2021-02-03 11:39:08.509598332 +0900
+++ dataclasses.py 2021-02-03 11:33:04.036571514 +0900
@@ -19,6 +19,7 @@
dataclass_makers = {
'dataclass',
'dataclasses.dataclass',
+ 'dataclassy.dataclass',
} # type: Final
SELF_TVAR_NAME = '_DT' # type: Final
Interesting, thanks for this. Tool incompatibility has been raised before (#5) and is something I'd love to improve if possible. I have never used either of these tools, so please excuse my ignorance, but are there files that I can include in dataclassy's wheel package that would help with this? Or would it require an upstream revision of those rules? I'm guessing from your diffs that it's the latter, in which case my only concern is whether they would accept PRs for a relatively unknown library like this...
Partly. There are things which can be added to the dataclassy wheel which will help. That is to add "py.typed" file and to add a "dataclassy.pyi" file. That would achieve the following: the decorators themselves would be type-checked and you wouldn't get the "error: unknown module" thing from mypy. The procedure for this is described in PEP-561. I can help with that at the weekend, if you like. I actually did it in one of my own projects recently.
Next step would be a one-liner PR for mypy, I can't see a downside for them but who knows :) That would make type-checking work for most (but not all) dataclassy use-cases. Most significantly, the inheritance features would still cause type-check failures.
If that goes well, maybe we (again I would be interested in doing this provided I can find time at weekends), can add full support to mypy by editing the current dataclasses plugin or by creating a new plugin. I've been trying to grok the code and not yet sure which approach is best, probably the latter.
PS. Surprised that this library is relatively unknown, I've run in to the need for it in, like, half a dozen projects and the workarounds I've gone to before discovering dataclassy are kind of nuts. I heard about it on a stackoverflow question and just assumed it was something that "everyone knew" :)
Those PRs would be appreciated! I just tried adding (ReST) parameter specifications to the docstring for @dataclass
and they seem to be recognised and used for autocompletion by both PyCharm and VSCode! I don't know if mypy is smart enough to read them too, obviating the need for an extra file, but no matter if it doesn't.
Funnily enough, the Stack Overflow answer you saw was probably by me - I ran into the same issues with dataclasses that everyone does eventually, stared aghast at the workarounds required, then wrote dataclassy and came back to a couple of the questions I'd found with it as a solution.
So yes, I think it is relatively unknown in terms of the number of stars etc., but I hope once discovered it's the sort of thing people find useful again and again. I'm glad that was the case for you!
Added #20 to enable type-checked installations. It seems to work pretty well.
I will look at forking mypy to figure out the issues around inheritance and so on, and post any updates here.
OK, I've gotten a proof-of-concept mypy plugin. I just need to make it put default-assigned attributes at the end of the parameter list and support all the various permutations of decorator options and so on. I think I'll be ready to share something next weekend.
The other thing I've discovered is that we could distribute the plugin as part of dataclassy (or as a separate module) if we can't merge it with mypy (or until that happens). That way, users can just add a mypy.ini
with plugins=dataclassy.mypy
if they want type-checking to work for a dataclassy project.
Great news on both fronts, thanks for your continued work on this.
I'm really looking forward to trying dataclassy once full mypy support will be there!
Closing this issue now that basic mypy support has been released. Feel free to open new issues for enhancements!
First of all, love dataclassy, it solves all of my problems with dataclasses/namedtuples and the like wonderfully :)
Only problem is lack of checking with mypy! Following demonstrates the issue:
Am not sure what the solution is here. Can this be solved by simply adding a
dataclassy.pyi
stub file and settingpy.typed
to the module ?I tried stubgen, which at least got the arguments for the decorator...