Python 3 type hinting for decorator

前端 未结 1 1855
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-16 10:48

Considere the following code:

from typing import Callable, Any

TFunc = Callable[..., Any]

def get_authenticated_user(): return \"John\"

def require_auth()         


        
相关标签:
1条回答
  • 2020-12-16 11:48

    You can't use Callable to say anything about additional arguments; they are not generic. Your only option is to say that your decorator takes a Callable and that a different Callable is returned.

    In your case you can nail down the return type with a typevar:

    RT = TypeVar('RT')  # return type
    
    def inject_user() -> Callable[[Callable[..., RT]], Callable[..., RT]]:
        def decorator(func: Callable[..., RT]) -> Callable[..., RT]:
            def wrapper(*args, **kwargs) -> RT:
                # ...
    

    Even then the resulting decorated foo() function has a typing signature of def (*Any, **Any) -> builtins.bool* when you use reveal_type().

    Various proposals are currently being discussed to make Callable more flexible but those have not yet come to fruition. See

    • Allow variadic generics
    • Proposal: Generalize Callable to be able to specify argument names and kinds
    • TypeVar to represent a Callable's arguments
    • Support function decorators excellently

    for some examples. The last one in that list is an umbrella ticket that includes your specific usecase, the decorator that alters the callable signature:

    Mess with the return type or with arguments

    For an arbitrary function you can't do this at all yet -- there isn't even a syntax. Here's me making up some syntax for it.

    0 讨论(0)
提交回复
热议问题