Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python typing: declare type of callable when give it instance method

Consider the following code:

import typing

def a(x: int, y: int) -> int:
    return x + y

class F(object):
    def b(self, x: int, y: int) -> int:
        return x + y

def call(operation: typing.Callable[[int, int], int]) -> int:
    return operation(2, 2)

call(a)

f = F()
call(f.b)

My PyCharm IDE indicates a typing error for the last line:

1

Is it a typing/type declaration error? Is the PyCharm type checker failing? If it's a typing error, what should it be?

like image 687
bux Avatar asked Oct 30 '22 13:10

bux


1 Answers

This is a PyCharm typechecker bug. The mypy typechecker accepts your example without warnings or errors:

$ bin/mypy --verbose so_41869174.py
LOG:  Mypy version 0.470
LOG:  Parsing so_41869174.py (so_41869174)
LOG:  Parsing lib/mypy/typeshed/stdlib/3/typing.pyi (typing)
LOG:  Parsing lib/mypy/typeshed/stdlib/3/builtins.pyi (builtins)
LOG:  Parsing lib/mypy/typeshed/stdlib/3/sys.pyi (sys)
LOG:  Parsing lib/mypy/typeshed/stdlib/3/abc.pyi (abc)
LOG:  Parsing lib/mypy/typeshed/stdlib/3/types.pyi (types)
LOG:  Parsing lib/mypy/typeshed/third_party/2and3/mypy_extensions.pyi (mypy_extensions)
LOG:  Parsing lib/mypy/typeshed/stdlib/3/_importlib_modulespec.pyi (_importlib_modulespec)
LOG:  Loaded graph with 8 nodes
LOG:  Found 2 SCCs; largest has 7 nodes
LOG:  Processing SCC of size 7 (_importlib_modulespec mypy_extensions types abc typing sys builtins) as inherently stale
LOG:  Processing SCC singleton (so_41869174) as inherently stale
LOG:  No fresh SCCs left in queue
LOG:  Build finished in 0.482 seconds with 8 modules, 1708 types, and 0 errors

Because F().b is a bound method, it inherits the signature of the underlying function without the self argument (as it is the job of the bound method to pass in the bound instance).

For example, the typing.get_type_hints() function, applied to the bound method, correctly omits self:

>>> typing.get_type_hints(f.b)
{'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
like image 93
Martijn Pieters Avatar answered Nov 15 '22 07:11

Martijn Pieters