Skip to content

Commit

Permalink
Support using collections.abc.Callable in type stubs.
Browse files Browse the repository at this point in the history
See python/typeshed#5055.

typeshed is moving toward using types from builtins and collections.abc rather
than typing (PEP 585). Mostly, this should just work with pytype, since we
rewrite typing.X to builtins.x anyway, and the collections.abc types are
represented as aliases of the typing ones.

However, typing.Callable has its own pytd node type, so we need to special-case
collections.abc.Callable in the parser. Since Tuple also has a special node
type, I added a test for Tuple as well - that appears to already be working.

PiperOrigin-RevId: 359096397
  • Loading branch information
rchen152 committed Feb 23, 2021
1 parent 52f3332 commit bc9ccb5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
3 changes: 2 additions & 1 deletion pytype/pyi/typed_ast/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ def _is_heterogeneous_tuple(self, t):

def _is_callable_base_type(self, t):
return (isinstance(t, pytd.NamedType) and
self._matches_full_name(t, "typing.Callable"))
(self._matches_full_name(t, "typing.Callable") or
self._matches_full_name(t, "collections.abc.Callable")))

def _is_literal_base_type(self, t):
return isinstance(t, pytd.NamedType) and (
Expand Down
19 changes: 19 additions & 0 deletions pytype/tests/py3/test_pyi.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,24 @@ def f() -> bytes: ...
x = ... # type: bytes
""")

def test_collections_abc_callable(self):
with file_utils.Tempdir() as d:
d.create_file("foo.pyi", """
from collections.abc import Callable
def f() -> Callable[[], float]: ...
""")
ty, _ = self.InferWithErrors("""
import foo
func = foo.f()
func(0.0) # wrong-arg-count
x = func()
""", pythonpath=[d.path])
self.assertTypesMatchPytd(ty, """
from typing import Callable
foo: module
func: Callable[[], float]
x: float
""")


test_base.main(globals(), __name__ == "__main__")
16 changes: 16 additions & 0 deletions pytype/tests/test_pyi.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,5 +836,21 @@ def f(x: _typing.Tuple[str, str]) -> None: ...
""")
self.Check("import foo", pythonpath=[d.path])

def test_parameterize_builtin_tuple(self):
with file_utils.Tempdir() as d:
d.create_file("foo.pyi", """
def f(x: tuple[int]) -> tuple[int, int]: ...
""")
ty, _ = self.InferWithErrors("""
import foo
foo.f((0, 0)) # wrong-arg-types
x = foo.f((0,))
""", pythonpath=[d.path])
self.assertTypesMatchPytd(ty, """
from typing import Tuple
foo: module
x: Tuple[int, int]
""")


test_base.main(globals(), __name__ == "__main__")

0 comments on commit bc9ccb5

Please sign in to comment.