Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

106
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda