Reputation: 26678
Trying out type hinting, and I'm having a bit of trouble wrapping my head around something:
class Node(object):
credentials_class = credentials.BaseCredentials
@property
def credentials_instance(self) -> [credentials_class]:
return self.credentials_class(self.credentials_data)
class OtherNode(Node):
credentials_class = credentials.OtherCredentials # subclass of BaseCredentials
How can I make it so that OtherNode().credentials_instance
returns the type that is specified in credentials_class
, for all subclasses of Node
?
The credentials_class
attribute is not required, if there is some other way for me to tell the system that "this node's credentials_instance property returns this instance type", that would be fine.
Upvotes: 3
Views: 1182
Reputation: 89
The answer is generics. By making Node
generic and parametrizing with the credentials class, you can specify the types as you want them to work. The downside is, the topmost class cannot assign a default value to credentials_class
, because it'd conflict with it being generic.
from typing import Type, Generic, TypeVar
CredentialsClassT = TypeVar("CredentialsClassT", bound=credentials.BaseCredentials)
class Node(Generic[CredentialsClassT]):
credentials_class: Type[CredentialsClassT]
@property
def credentials_instance(self) -> CredentialsClassT:
return self.credentials_class(self.credentials_data)
# example usage
class BaseNode(Node[credentials.BaseCredentials]):
credentials_class = credentials.BaseCredentials
class OtherNode(Node[credentials.OtherCredentials]):
credentials_class = credentials.OtherCredentials # subclass of BaseCredentials
With that typing in place, eg.
reveal_type(OtherNode.credentials_instance)
will make MyPy print not: Revealed type is 'credentials.OtherCredentials'
as expected.
Upvotes: 3