Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

How can I type annotate a factory helper's **kwargs to match that of the __init__ of the type being created?#1775

Unanswered
cjw296 asked this question inQ&A
Discussion options

So, for this code:

classCollection:defmake(self,type_:Type[T],**attrs)->T:        ...

How can I annotate**attrs such that a type checker, mypy in particular, will correctly ensure that any keywords passed are a valid subset of those that could be passed toT's constructor?

You must be logged in to vote

Replies: 2 comments 15 replies

Comment options

You can use aParamSpec. There's no way to constrain it to only keyword parameters though. After all, the constructor may support positional parameters.

fromtypingimportCallableclassCollection:defmake[**P,T](self,type_:Callable[P,T],*args:P.args,**kwargs:P.kwargs    )->T: ...

Here's the same thing using older (pre-3.12) syntax:

fromtypingimportCallable,ParamSpec,TypeVarP=ParamSpec("P")T=TypeVar("T")classCollection:defmake(self,type_:Callable[P,T],*args:P.args,**kwargs:P.kwargs)->T: ...
You must be logged in to vote
14 replies
@cjw296
Comment options

but that wouldn't necessarily change the requirement that you always need to unpack both components of P.

Sorry, not following this, could you provide a code example of what you mean?

So the type checker would ensure that no positional arguments can be passed in, but your generic signature would still need to include them anyways

This sounds pretty sub-optimal :-/

What's pytype? That's not a phrase I've heard before...

@Daverball
Comment options

Sorry, not following this, could you provide a code example of what you mean?

The spec forParamSpec currently states that ifP.args is used in a function's signatureP.kwargs must also be used and vice versa, there also can't be any arguments in between, the only thing you're allowed to do is prepend arguments, like you would withConcatenate. This is to ensure that no matter whatP solves to, the call is still possible. Otherwise the same P would need to check every single place it's used in order to ensure consistency.

defallowed[**P](self,*args:P.args,**kwargs:P.kwargs): ...defpositional_only_prepend_allowed[**P](self,arg:int,/,*args:P.args,**kwargs:P.kwargs): ...defno_kwargs_disallowed[**P](self,*args:P.args): ...defno_args_disallowed[**P](self,**kwargs:P.kwargs): ...defmiddle_extra_kwarg_disallowed[**P](self,*args:P.args,my_new_kwarg:int=0,**kwargs:P.kwargs): ...

With upper bounds onP this restriction could potentially be relaxed in some cases, e.g. with an upper bound ofdef (**kwargs: Any) you may be allowed to omitP.args and define an arbitrary number of preceding positional only arguments. Although the required implementation complexity makes this probably almost certainly not worth it.

What's pytype? That's not a phrase I've heard before...

It's a Python type checker made by Google. It performs very deep type inference and allows a lot of things other type checkers would disallow because their inference is too shallow to ensure type safety without an explicit type annotation. So it can be useful in code that doesn't make heavy use of type annotations, since it will still be able to detect a lot of problems anyways.

@cjw296
Comment options

The irony's not lost on me that some of the things that have made Python so powerful over the last two or three decades end up being the things that are hardest to express in static typing...

Thanks for the pytype pointer; is this one, right?https://github.com/google/pytype

@Daverball
Comment options

Correct

@cjw296
Comment options

Hmm, unfortunately, pytype seems to trip up onmuch simpler stuff that mypy is happy with :-/

Comment options

#1500 seems to be the same ballpark as this.

You must be logged in to vote
1 reply
@Daverball
Comment options

That sounds more like a proxy type to me, which has been requested many times before, e.g.#802 but we don't have anything like that yet.

There definitely are some open questions for proxy types, like should a proxy be allowed to stand-in for the real type, what about partial proxies that don't proxy everything etc. It would definitely need a PEP to explore and answer some of those questions, so we have a concrete proposal that can be implemented in a type checker as a proof of concept.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Category
Q&A
Labels
None yet
4 participants
@cjw296@Daverball@erictraut@bzoracler

[8]ページ先頭

©2009-2025 Movatter.jp