@@ -501,23 +501,47 @@ for a decorator.
501501Different type checkers handle ``TypeAlias `` involving ``Callable `` in a
502502different manner, so the most portable and easy way to create a shortcut
503503is to define a callable ``Protocol `` as described in `PEP
504- 544 <https://peps.python.org/pep-0544/#callback-protocols> `_:
504+ 544 <https://peps.python.org/pep-0544/#callback-protocols> `_.
505+
506+ There is already a ``Protcol `` called ``IndentityFunction `` defined in ``_typeshed ``:
505507
506508.. code :: python
507509
508- _F = TypeVar(" _F" , bound = Callable[... , Any])
510+ if TYPE_CHECKING :
511+ from _typeshed import IdentityFunction
512+
513+ def decorator_factory (* , mode : str ) -> " IdentityFunction" :
514+ """
515+ Decorator factory is invoked with arguments like this:
516+ @decorator_factory(mode="easy")
517+ def my_function(): ...
518+ """
519+ ...
520+
521+ For non-trivial decorators with custom logic, it is still possible
522+ to define a custom protocol using ``ParamSpec `` and ``Concatenate ``
523+ mechanisms described in `PEP 612
524+ <https://www.python.org/dev/peps/pep-0612/> `__:
525+
526+ .. code :: python
527+
528+ class Client : ...
509529
510- class PDecorator (Protocol ):
511- def __call__ (self , _ : _F, / ) -> _F:
530+ P = ParamSpec(" P" )
531+ R = TypeVar(" R" )
532+
533+ class PClientInjector (Protocol ):
534+ def __call__ (self , _ : Callable[Concatenate[Client, P], R], / ) -> Callable[P, R]:
512535 ...
513536
514- def decorator_factory (* , mode : str ) -> PDecorator:
515- """
516- Decorator factory is invoked with arguments like this:
517- @decorator_factory(mode="easy")
518- def my_function(): ...
519- """
520- ...
537+ def inject_client (service : str ) -> PClientInjector:
538+ """
539+ Decorator factory is invoked with arguments like this:
540+ @inject_client("testing")
541+ def my_function(client: Client, value: int): ...
542+
543+ my_function then takes only value
544+ """
521545
522546
523547 Generic Classes and Functions
0 commit comments