2

I have a use case where I would like to define a common function in a base class, but annotate the return type from an overridden property in a subclass. This is a silly example, but clearly demonstrates what I would like to do:

from typing import Any class BaseCls: RETURNS_TYPE: Any = NotImplemented # This is what I am not sure how to do, this does not work # Have tried a few different things, but hoping someone just knows def cast_to_return_type(self: 'BaseCls', value: Any) -> 'BaseCls.RETURNS_TYPE': return some_work_that_returns_self_RETURNS_TYPE() class IntCls(BaseCls): RETURNS_TYPE = int class StrCls(BaseCls): RETURNS_TYPE = str 

How can I type hint the return value of cast_to_return_type so that a a regular old IDE would be able to detect what the return type should be when doing StrCls().cast_to_return_type(some_var) (tried on pycharm and vscode, neither knew what to do any decided Any was the return type, which makes sense if it cant infer the child class value)

3
  • 2
    This might help you, have you checked this: stackoverflow.com/questions/61146406/… Commented Oct 28, 2021 at 20:17
  • What do you mean by "a regular old IDE"? Commented Oct 28, 2021 at 20:40
  • 1
    I think this goes against the LSP, use generics Commented Oct 28, 2021 at 21:08

1 Answer 1

3

The closest thing that typing has to type variables is typing.TypeVar. Their use is to create a generic class, in the same way that you write list[int] or Mapping[str, str].

So we can rewrite your code so that BaseCls is a generic type, with a type variable ReturnsType. (You should only use all caps for constants.)

The subclasses IntCls and StrCls "assign" to the type variable by including the type inside square braces after the type they are subclassing.

from typing import TypeVar, Generic, Any ReturnsType = TypeVar('ReturnsType') class BaseCls(Generic[ReturnsType]): def cast_to_return_type(self, value: Any) -> ReturnsType: return some_work_that_returns_self_RETURNS_TYPE() class IntCls(BaseCls[int]): pass class StrCls(BaseCls[str]): pass 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.