-
Hello! I'm attempting to do this: from types import UnionType
from typing import List, Type, TypeAliasType, TypeVar, get_args
class Dog:
pass
class Sphynx:
pass
class Tabby:
pass
animal_types = [Dog, Sphynx, Tabby]
CatsUnion = Sphynx | Tabby
type CatsAlias = Sphynx | Tabby
ACat = Sphynx
T = TypeVar("T")
def create_animal_instances(animal_type: Type[T]) -> List[T]:
a = []
req_types = []
print(type(animal_type))
if isinstance(animal_type, UnionType):
req_types = get_args(animal_type)
elif isinstance(animal_type, TypeAliasType):
req_types = get_args(animal_type.__value__)
else:
req_types = [animal_type]
for ani in animal_types:
if ani in req_types:
a.append(ani())
return a
some_union_cats = create_animal_instances(CatsUnion)
print(some_union_cats)
some_alias_cats = create_animal_instances(CatsAlias)
print(some_alias_cats)
some_acats = create_animal_instances(ACat)
print(some_acats) but getting these type errors when calling with
However when running the output is what I'd expect:
I may be misusing types here, but I'm really eager to learn the specifics of why. thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
For details about the type annotation BTW, the uppercase version of There is a new PEP under development that would introduce a way to support what you're doing here. However, I recommend against this approach. You're trying to use the runtime machinery of the static type system in a dynamic manner. In other words, you're using static types in a way they were not really designed to be used. There are some cases where such introspection is necessary (e.g. if you're implementing a runtime type checker), but I wouldn't recommend it for normal, every-day code. Here's an alternative approach: Code sample in pyright playground class Dog:
pass
class Sphynx:
pass
class Tabby:
pass
def create_animal_instances[T](animal_type: tuple[type[T], ...]) -> list[T]:
return [ani() for ani in animal_type]
some_union_cats = create_animal_instances((Sphynx, Tabby))
print(some_union_cats)
some_acats = create_animal_instances((Sphynx, ))
print(some_acats) |
Beta Was this translation helpful? Give feedback.
For details about the type annotation
Type[T]
, refer to this section of the Python typing spec. As indicated in the spec, a union type is not compatible withtype[T]
. Nor is aTypeAliasType
value. That's becausetype[T]
should be an instantiable class, and an attempt to call the a union type orTypeAliasType
object will result in a runtime exception.BTW, the uppercase version of
Type
andList
are deprecated as of Python 3.9. You can now usetype
andlist
(the lowercase builtin symbols).There is a new PEP under development that would introduce a way to support what you're doing here. However, I recommend against this approach. You're trying to use the runtime machinery of the static type…