Replies: 1 comment
-
|
@rsokl, thanks for posting here. I've already commented on an earlier iteration of this proposal in a pyright discussion thread, so I won't repeat my full response here. In summary, the specifics of this proposal strike me as very problematic. The solution doesn't compose well with other features in the type system. My recommendation is to try to reframe the problem or look for an alternative solution that doesn't involve the use of a |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I would love for type checkers to have better support dynamically-generated dataclass types. Specifically, I would like them to be able to infer the fields on a dynamically-generated dataclass type based on a statically-typed
__init__signature. E.g.PEP 681 enables you to statically declare fields on a class to inform the
__init__of that class in the eyes of type checkers. What I am proposing is enabling this to go in the opposite direction, so to speak.Proposal
A PEP that specifies, for type checkers, a dataclass-type protocol decorator
In the context of a
@dataclass_protocol-decorated protocol:__init__and attributes are inferred fromParamSpecThese would represent no-init fields on the returned type and would have to be non-overlapping with
ParamSpec.@dataclass_protocolwould not have any runtime details, it is meant to serve as a marker for type checkers to infer attributes fromParamSpec. Otherwise the behavior ofParamSpecremains unchanged for non-decorated protocols.Limitations
In this proposal,
Pis only valid in this context if there are no*args,**kw, or positional-only entries in the function's signature - these are not supported by dataclass types. Furthermore, declaringInitVar(i.e. init-only) entries in the signature would not be supported. (There may be other dataclass features that I am overlooking here.)Motivation
Many experiment / configuration framework libraries (including hydra-zen) have gravitated towards using dataclass types to represent "configs" for functions. The following pattern is quite common:
Configis acting like a floating, mutable signature forfunc. Its defaults can be modified/overwritten via inheritance, and you can create and store many instances ofConfigas a way to callfuncin various ways later. These are the upsides to this approach. The downsides, however, are numerous - such as decouplingConfigfrom the implementationfuncthat you care about, and no longer being able to callfuncin an ergonomic way. Soon, your code base is littered with this pattern instead of having simple functions.This pattern can be seen throughout nerfstudio and many many ML code bases.
Far preferable would be to leave
funcas a normal function and then generate theConfigtype dynamically, based off of its signature.then it is simple enough to write a wrapper that lets you do
call_via_config(foo)(Config(x=1, y="b"))to call the function using your config instance. Now, the simple functionfoois the star player in your code base once again and your desire to create a type that configure it can be done automatically and as an afterthought.Indeed this is the pattern that hydra-zen enables. But a major downside to this dynamic approach is the lack of type-checking/autocomplete support for the attributes on the generated type, which is where the present proposal comes in.
I have to imagine that libraries like
pydanticand other heavy users of PEP 681 would have use for this feature as well for purposes well beyond that of code configuration.Closing Remarks
The introduction of
@typing.dataclass_protocolis meant to enable basic type check support for the attributes of dynamically generated dataclass types. It is not meant to provide the same level of type information / specification as a statically-defined dataclass.I am keen to get feedback on this. Thank you for your attention! 😄
Beta Was this translation helpful? Give feedback.
All reactions