-
Notifications
You must be signed in to change notification settings - Fork 258
Option to type default default arguments in Callable types - WithDefault
#1232
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
Comments
This makes me want to re-submit PEP 677… |
I agree, a good callable syntax would have been nice but I don't see that happening anytime soon. Adding a special type might be verbose, but it's a least something that can be done. -- |
A special type also has the benefit that it could be used in other places, too. See #1231 |
I'm confused by meaning of this statement. I use callback protocols like class TriggerCondition(Protocol[_P]):
__name__: str
def __call__(
self,
job_id: str,
*args: _P.args,
**kwargs: _P.kwargs,
) -> object:
... Can you clarify the statement? I'm a bit skeptical that protocol is much more complex then knowing when to use WithDefault. If you need to deal with callbacks where default/positional status of argument matters I'd be surprised if you weren't already familiar with protocols. The one brevity it gives you is skipping names and staying positional only, but I'm meh on having more variety for typing callables (unlesss pep 677 or variation becomes feasible). I like callback protocols as they just follow normal def syntax. |
It's not about using ParamSpec within a Callback protocol. Rather how you type a generic ParamSpec to indicate it has default arguments. from typing import Callable, ParamSpec, Generic, Protocol
_P = ParamSpec("_P")
class Func(Protocol):
def __call__(self, a: str, b: int = 0) -> None: ...
class Job(Generic[_P]):
def __init__(self, target: Callable[_P, None]) -> None:
self.target = target
def f(action: Func) -> Job: # How should Job be typed here?
return Job(action)
reveal_type(Job(action)
# pyright
# Job[(a: str, b: int = ...)]
# mypy
# Job[[a: builtins.str, b: builtins.int =]] This is only a simplified example. I'm aware that it's probably better to use a normal TypeVar for the whole Callable type instead of the ParamSpec. That isn't possible in the specific case though. |
At the moment it's only possible to type callables with default arguments by using a Callback protocol . This adds a lot of additional code for just a few default arguments. Moreover it requires that users have at least a basic understanding of
Protocols
which is one of the more advanced typing concepts. Lastly, a Callback protocol can't be used to type a generic ParamSpec argument.Proposal
Add a new
WithDefault
special type which can be used to annotate arguments in callable types.Examples
For generic ParamSpec types
The text was updated successfully, but these errors were encountered: