I have a class which is a list of instances of classes which extend
and those extending classes could themselves have a
I want an
of_type function which will let me filter to the concrete class.
First naive attempt:
class Base: ... T = TypeVar('T', bound=Base) class BaseList(list[Base]): def of_type(self, klass: type[T]) -> list[T]: return [m for m in self if isinstance(m, klass)]
Trivial case is fine:
class TrivialSub(Base): ... list = BaseList() list.append(TrivialSub()) print(list.of_type(TrivialSub)) # ok
S = TypeVar('S') class GenericSub(Base, Generic[S]): val: S list.append(GenericSub[int]()) print(list.of_type(GenericSub[int])) # fails: # TypeError: Subscripted generics cannot be used with class and instance checks
Annoying, but makes sense.
Best I can come up with to satisfy type checker and at run time:
def of_type(self, klass: type[T]) -> list[T]: maybe_origin = get_origin(klass) klass_ = maybe_origin if maybe_origin else klass return [cast(klass, m) for m in self if isinstance(m, klass_)]
Does anyone have any better ideas how to implement this?
I know my solution loses type safety on
S and I feel like I could also handle that with
get_args, but I wanted to see if I’m going down a rabbit hole first