9

Suppose I have an interface A with a single function.

class A(metaclass=ABCMeta):

    @abstractmethod
    def spam(self, x: int) -> str:
        pass

There are classes B and C that implement this interface, but they will not be directly initialized. I will have some factory method (say) that will return to me a suitable object implementing A. So in this case, when I implement spam in B and C, should I repeat the type hints? Practically, since B and C aren't directly used, the type hints for A seem sufficient. But I'm curious about the best practice in this situation; and if there are other issues to be considered.

Jayanth Koushik
  • 9,476
  • 1
  • 44
  • 52
  • 1
    if you're performing static analysis, the safest option is to supply hints everywhere. This question really depends on how static analyzers are implemented, I don't believe that any analyzers will realize that your class implements an abstractmethod and, as a result, use the types supplied there. – Dimitris Fasarakis Hilliard Mar 22 '17 at 21:54
  • See https://stackoverflow.com/questions/54087885/static-type-check-for-abstract-method-in-python and https://stackoverflow.com/questions/25183424/can-a-python-abstract-base-class-enforce-function-signatures – Wesley Smith Aug 20 '19 at 15:01

1 Answers1

1

Presumably, since you implement B.spam, it won't be a trivial implementation (otherwise, why bother overriding A.spam?). So you probably should type check the body of B.spam. In that case, you need to provide type hints for the arguments and return values of B.spam; otherwise, mypy will treat those types as Any.

Note that if you do provide type hints, mypy will check that the type of B.spam is compatible with A.spam using its rules for subclassing, but only if B derives from A non-virtually; if you just A.register(B), mypy will ignore the inheritance relationship entirely. This is consistent with how the runtime will not look up .spam in the virtual base classes.

max
  • 49,282
  • 56
  • 208
  • 355