Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

100
Vistas
How to alias generic types for decorators

Consider the example of a typed decorator bound to certain classes.

import unittest
from typing import *

T = TypeVar("T", bound=unittest.TestCase)

def decorate(func: Callable[[T], None]) -> Callable[[T], None]:
    def decorated_function(self: T) -> None:
        return func(self)
    return decorated_function

Now I even have a generator that creates these decorators and want to shorthand these decorators. What type do I to the variables variables storing the decorator (simplified example omitting the generator).

my_decorate: Callable[[Callable[[T], None]], Callable[[T], None]] = decorate

This works, but is clunky. So the question is:

How can I alias this type to avoid having to write the the full signature?


Things that don't work:

TD = Callable[[Callable[[T], None]], Callable[[T], None]]
my_decorate: TD[T] = decorator_variable

Gives the error

error: Type variable "mypytest.T" is unbound
note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
note: (Hint: Use "T" in function signature to bind "T" inside a function)

In contrast, I can use TD[T] as argument type for a function.

Just using my_decorate: TD = ... yields a --strict error

error: Missing type parameters for generic type "TD"

And it no longer detects wrong applications of my_decorate.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

What about this? It is shorter than the full signature:

import unittest
from typing import *

T = TypeVar("T", bound=unittest.TestCase)


def decorate(func: Callable[[T], None]) -> Callable[[T], None]:
    def decorated_function(self: T) -> None:
        return func(self)

    return decorated_function


decorator_variable: Callable[[Callable[[T], None]], Callable[[T], None]] = decorate

U = Callable[[T], None]
my_decorate: Callable[[U[T]], U[T]] = decorator_variable
over 4 years ago · Santiago Trujillo Denunciar

0

As in many cases, when Callable is too limited use a Protocol instead:

class TD(Protocol):
    """Type of any callable `(T -> None) -> (T -> None)` for all `T`"""
    def __call__(self, __original: Callable[[T], None]) -> Callable[[T], None]:
        ...

TD is not a generic type and thus does not need "filling in" a type variable. It can be used directly as an annotation:

my_decorate: TD = decorate

Notably, TD.__call__ is still a generic callable even though TD is not generic. Its T is filled by the context of each call as desired.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda