The Feature Request
It would be awesome if it were possible to create a partial type spec for Callable. For example, I might want to be able to specify that the first argument of a function must be an integer, but that any other parameters are allowed. This could be accomplished with the following extension to PEP-484 which would allow ... to be included in the argument list to Callable if it followed any extended callable types. As a result we could write a type spec FirstArgIsInt which would match all the following functions and any number of other arbitrary functions so long as their first argument is an integer:
FirstArgIsInt = Callable[[Arg(int), ...], int]
f1: FirstArgIsInt
def f1(x: int) -> int: ...
f2: FirstArgIsInt
def f2(x: int, y: int) -> int: ...
f3: FirstArgIsInt
def f3(x: int, *args, **kwargs) -> int: ...
A Real World Use Case
Partial type specifications for Callable are useful if parameters are being passed on to a function from a decorator as in request handlers for many web frameworks like Django's view funtions or Sanic's routes:
def route_1(request: Request) -> Response: ...
def route_2(request: Request, username: str) -> Response: ...
def route_3(request: Request, comment_id: int, content: str) -> Response: ...
# adinfinitum...
Imagine that you wanted to write an authenticated decorator which ensures a user who accesses any particular route is logged in. What would be the type of RouteHandler if not Callable[..., Response]:
RouteHandler = ?
def authenticated(r: RouteHandler) -> RouteHandler: ...
It would be Callable[[Arg(Request), ...], Any], or some other expression of the same idea.
Current Work Arounds
Callable[..., Response], however this provides no precision for the function parameters.
- Use
Callable[[Arg(Request), VarArg(), KwArg()], Response] however this is problematic since, these route handlers don't actually need to be able to accept arbitrary arguments.
- Use
Protocol with overloads, however there are cases (e.g. decorators for route handlers as above) where it's not feasible to enumerate all possible route handler implementations.
The Feature Request
It would be awesome if it were possible to create a partial type spec for
Callable. For example, I might want to be able to specify that the first argument of a function must be an integer, but that any other parameters are allowed. This could be accomplished with the following extension to PEP-484 which would allow...to be included in the argument list toCallableif it followed any extended callable types. As a result we could write a type specFirstArgIsIntwhich would match all the following functions and any number of other arbitrary functions so long as their first argument is an integer:A Real World Use Case
Partial type specifications for
Callableare useful if parameters are being passed on to a function from a decorator as in request handlers for many web frameworks like Django's view funtions or Sanic's routes:Imagine that you wanted to write an
authenticateddecorator which ensures a user who accesses any particular route is logged in. What would be the type ofRouteHandlerif notCallable[..., Response]:It would be
Callable[[Arg(Request), ...], Any], or some other expression of the same idea.Current Work Arounds
Callable[..., Response], however this provides no precision for the function parameters.Callable[[Arg(Request), VarArg(), KwArg()], Response]however this is problematic since, these route handlers don't actually need to be able to accept arbitrary arguments.Protocolwith overloads, however there are cases (e.g. decorators for route handlers as above) where it's not feasible to enumerate all possible route handler implementations.