I have a custom test runner that uses inspect to find all the functions starting with with test_
. At one point I add an attribute to the function object. This is done so the test runner has access to the docstring information later.
I’d really like to create a type hint for the list of functions so that my IDE (pycharm) knows that tdi
is indeed an attribute of the function object.
How do you build such a type hint?
for m, fn in module.__dict__.items(): if m.startswith(prefix): if callable(fn): tdi = getTestDocInfo(fn) # reads the docstring for tags and puts the info in a dataclass fn.tdi = tdi tests.append(fn)
edit:
In this case, the type hint should convey the object is a function AND that it has the attribute tdi
.
As @chepner pointed out the Protocol
building block for a type hint is what was needed here.
This is what worked.
@runtime_checkable class TestFunc(Protocol): tdi: TestDocInfo def __call__(self, testresult: TestResult, shareditems: SharedItems): pass tests: List[TestFunc]. #type hint I am looking for.
Advertisement
Answer
This seems like a job for typing.Protocol
and typing.runtime_checkable
:
from typing import Protocol, runtime_checkable @runtime_checkable class HasTDI(Protocol): tdi: int # Or whatever type is appropriate.
Then
isinstance(fn, HasTDI)
should be true if fn.tdi
exists and is an int
.
I’m afraid I don’t know if PyCharm will make use of this information, though.