Search code examples
pythontype-hintingpython-3.10

How to use python generic hints to indicate value type in parent class?


I have a static member that will be some implementation of ToolInterface interface. I inherit the class that has that member and want to specify what implementation is used.

I tried this:

tool_test_base.py

from typing import Generic, TypeVar

from abstract_tool import ToolInterface


TToolImpl = TypeVar("TToolImpl", ToolInterface)

class ToolTestBase(Generic[TToolImpl]):

    tool_impl = None # type: TToolImpl

    @test_case
    test_do_something(self):
        assert self.tool_impl.do_something() == "hello"

abstract_tool.py

def ToolInterface:
    def do_something():
        assert False, "Tool method not implemented"

Now I have a class that extends the tool test and also provides a specific implementation:

my_tool.py

from abstract_tool import ToolInterface
class MyTool(ToolInterface):
    do_something(self):
        return "hello"
    do_something_special(self):
        return "🎁"

my_tool_test.py

from tool_test_base import ToolTestBase
from my_tool import MyTool

class MyToolTest(ToolTestBase[MyTool]):
    test_something_special(self):
    assert self.tool_impl.do_something_special() == "🎁"

Now by writing ToolTestBase[MyTool] I was hoping to indicate that TToolImpl is MyTool and not MyToolBase. However, it is not working as intended. I see tool_impl hints for MyToolBase but not for MyTool


Solution

  • I had it almost correct. The only mistake is that writing this:

    TToolImpl = TypeVar("TToolImpl", ToolInterface)
    

    means TToolImpl can only be ToolInterface. The correct formulation is:

    TToolImpl = TypeVar("TToolImpl", bound=ToolInterface)
    

    This says that TToolImpl is any sub type of ToolInterface. After that, it worked for me.