0
votes

You can use type hinting with stub files in Python 2.7 per https://www.python.org/dev/peps/pep-0484/#stub-files

However I cannot make it work for method signatures in subclasses.

In stub file a.pyi:

class A(object):
    def foo(self, timestamp: float): ...

In Python 2.7 file b.py

class B(A):
    def foo(self, timestamp):
        print(timestamp)  # Inferred type of timestamp is not float!

PyCharm 2017.3.3 does not infer timestamp as float. I did not check the behavior of mypy.

There are two workarounds which bring code redundancies (not preferred)

Workaround 1

In stub file b.pyi

class B(A):
    def foo(self, timestamp: float): ...

Workaround 2

In Python 2.7 file b.py

class B(A):
def foo(self, timestamp):  # type: (float) -> None
    print(timestamp)
1

1 Answers

1
votes

If you do not add type annotations to a function, you are indicating that you do NOT want PEP-484 compliant type checkers to check that function.

What this means is that you need to do approach 2: explicitly add type hints so that Pycharm (and mypy) knows you want that function to be typechecked.

Note that your workaround 1 doesn't really work: if you add a *.pyi file, you're telling the typechecker to completely ignore the corresponding *.py file. This is probably not what you want to happen here.

More broadly, it would actually be incorrect for Pycharm (or mypy) to infer that timestamp is always of type float: it's legal for the subtype to actually widen the parameter type. For example, it could be the case that B's timestamp method accepts floats OR strs:

class B(A):
    def timestamp(self, timestamp):
        # type: (Union[float, str]) -> None
        print(timestamp)

Or maybe it could be widened to accept any type:

class B(A):
    def timestamp(self, timestamp):
        # type: (object) -> None
        print(timestamp)

Both of these definitions are valid subtypes of A: they both match A.timestamp's signature without violating the Liskov substitution principle.

Consequently, since we can't easily automatically infer what the subtype's signatures should be, Pycharm (and mypy) don't try.