Reputation: 23955
Please consider this snippet of python 3.5 code:
class Foo:
pass
class Bar(Foo):
pass
class AbstractSomething:
def get_foobinator_type(self):
return Foo
I'd like to annotate (using PEP-0484 annotations) return value of get_foobinator_type
method to say: "It returns a type, that is either a Foo
or any subtype of it".
I din't find any sensible way to do it in Python. Here are approaches that are obviously wrong:
Following: def get_foobinator_type(self) -> Foo
means that this method returns an instance of Foo
.
Following: def get_foobinator_type(self) -> type
means that this method returns a type, but sadly, there is no information about that this is needs to be a subtype of Foo
.
In Java terms I'd like to have method with signature like: Class<Foo> getFoobinatorType()
.
Upvotes: 1
Views: 486
Reputation: 23955
Lately (in Python 3.5.2
) a generic Type
was introduced, so solution is:
class AbstractSomething:
def get_foobinator_type(self) -> typing.Type[Foo]:
return Bar
See: python docs.
Upvotes: 2
Reputation: 160377
As far as I understand, you really cannot. You're looking for a way to indicate the return type of a class; to check based on what the type of the class is, i.e its metaclass.
The problem with that is that a metaclass doesn't help a type checker evaluate what the inheritance of an object might be, if it's of type type
it's alright.
Apart from that, and, not being sure what type-checker you use, mypy
for example doesn't have support yet for custom metaclasses which you might use to group your objects in a more custom group.
The way I see it, you either don't annotate at all all, or, you change the implementation and annotate with Foo
.
Upvotes: 2
Reputation: 1342
I think what you need is TypeVar from the typing module.
from typing import TypeVar
class Foo:
pass
class Bar(Foo):
pass
T = TypeVar('T', bound=Foo)
class AbstractSomething:
def get_foobinator_type(self) -> T:
return Foo
From the documentation of typing:
Alternatively, a type variable may specify an upper bound using bound=. This means that an actual type substituted (explicitly or implicitly) for the type variable must be a subclass of the boundary type, see PEP 484
Upvotes: 0