Why does Concatenate
only work one way?
#2167
-
What's the rationale behind I wanted to make a decorator that added authentication and authorization handling on HTTP controllers: @requires("admin")
async def delete_everything(req: Request, user: AuthenticatedUser) -> Response:
...
# delete_everything becomes:
# async (req: Request) -> Response
# which can be then used as a standard handler in framework, in my case Starlette Because I wanted it to work on methods as well as with other similar decorators: @requires("admin")
@parse_body_as(UserMention)
def ban_user(self, mention: UserMention, user: AuthenticatedUser) -> Response:
...
# ban_user becomes:
# async (self, req: Request) -> Response
# and then I can use the bound method as a handler Traditionally things like this have been done without adding arguments, but with adding extra attributes to the I am aware that this is just how the grammar is defined in the PEP, but maybe there's some deeper reason why what I wanted isn't possible? This is possible in TypeScript, so I was surprised it doesn't work with PEP 612. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
It's because |
Beta Was this translation helpful? Give feedback.
It's because
Callable
only supports expressing positional arguments. If you haveCallable[Concatenate[P, int], None]
, then what shouldP
capture? It can't capturekwargs
so that's a limitation that'd have to be imposed onParamSpec
in this context. But also, if you imagine this asdef foo(*args, bar: int)
, what that means is theint
would have to be a keyword-only argument, and keyword-only arguments are not supported byCallable
.