Python: typing a generic function that receives a type and returns an instance of that type

Viewed 984

I want to add typing to a Python function that takes in a type as an argument (actually, a subtype of a specific class), and return an instance of that type. Think a factory that takes in the specific type as an argument, e.g.:

T = TypeVar('T', bound=Animal)

def make_animal(animal_type: Type[T]) -> T:  # <-- what should `Type[T]` be?
    return animal_type()

(obviously this is a very simplistic example, but it demonstrates the case)

This feels like something that should be possible, but I couldn't find how to properly type-hint this.

2 Answers

Not sure what your question is, the code you posted is perfectly valid Python code. There is typing.Type that does exactly what you want:

from typing import Type, TypeVar

class Animal: ...
class Snake(Animal): ...

T = TypeVar('T', bound=Animal)

def make_animal(animal_type: Type[T]) -> T:
    return animal_type()

reveal_type(make_animal(Animal))  # Revealed type is 'main.Animal*'
reveal_type(make_animal(Snake))   # Revealed type is 'main.Snake*'

See mypy output on mypy-play.

How about something like this?

from __future__ import annotations
from typing import Type


class Animal:
    ...


def make_animal(animal_type: Type[Animal]) -> Animal:
    return animal_type()
Related