예제 #1
0
 def testMatchType(self):
   with utils.Tempdir() as d:
     d.create_file("a.pyi", """
       from typing import Type
       class A(object): ...
       class B(A): ...
       class C(object): ...
       def f(x: Type[A]) -> bool
     """)
     ty, errors = self.InferAndCheck("""\
       import a
       x = a.f(a.A)
       y = a.f(a.B)
       z = a.f(a.C)
     """, pythonpath=[d.path], deep=True)
     error = r"Expected.*Type\[a\.A\].*Actual.*Type\[a\.C\]"
     self.assertErrorLogIs(errors, [(4, "wrong-arg-types", error)])
     self.assertTypesMatchPytd(ty, """
       from typing import Any
       a = ...  # type: module
       x = ...  # type: bool
       y = ...  # type: bool
       z = ...  # type: Any
     """)
예제 #2
0
 def testCallable(self):
     with utils.Tempdir() as d:
         d.create_file(
             "foo.pyi", """
     from typing import Any
     from typing import Callable
     def process_function(func: Callable[..., Any]) -> None: ...
   """)
         ty = self.Infer("""\
     import foo
     def bar():
       pass
     x = foo.process_function(bar)
   """,
                         deep=False,
                         pythonpath=[d.path],
                         solve_unknowns=True)
         self.assertTypesMatchPytd(
             ty, """
     from typing import Any
     foo = ...  # type: module
     def bar() -> Any: ...   # 'Any' because deep=False
     x = ...  # type: NoneType
   """)
예제 #3
0
 def testMaybeIdentityDecorators(self):
     foo = self.Infer("""
   def maybe_decorate(f):
     return f or (lambda *args: 42)
 """,
                      deep=True)
     with utils.Tempdir() as d:
         d.create_file("foo.pyi", pytd.Print(foo))
         ty = self.Infer("""
     import foo
     @foo.maybe_decorate
     def f():
       return 3
     def g():
       return f()
   """,
                         deep=True,
                         pythonpath=[d.path])
         self.assertTypesMatchPytd(
             ty, """
     foo = ...  # type: module
     def f() -> int
     def g() -> int
   """)
예제 #4
0
 def testInterpreterSubclass(self):
   with utils.Tempdir() as d:
     d.create_file("a.pyi", """
       from typing import List, TypeVar
       T = TypeVar("T")
       class A(List[T]):
         def __init__(self) -> None:
           self := A[str]
         def f(self) -> T
     """)
     ty = self.Infer("""
       import a
       class B(a.A): pass
       def foo():
         return B().f()
       def bar():
         return B()[0]
     """, pythonpath=[d.path], deep=True)
     self.assertTypesMatchPytd(ty, """
       a = ...  # type: module
       class B(a.A): pass
       def foo() -> str
       def bar() -> str
     """)
예제 #5
0
 def testInstanceAttributeInherited(self):
   with utils.Tempdir() as d:
     d.create_file("a.pyi", """
       from typing import List, TypeVar
       T = TypeVar("T", int, float)
       class A(List[T]):
         x = ...  # type: T
     """)
     ty = self.Infer("""
       import a
       class B(a.A): pass
       def f():
         return B().x
       def g():
         return B([42]).x
     """, pythonpath=[d.path], deep=True)
     self.assertTypesMatchPytd(ty, """
       from typing import Any
       a = ...  # type: module
       class B(a.A):
         x = ...  # type: int or float
       def f() -> int or float
       def g() -> int
     """)
예제 #6
0
 def test_mutableset(self):
     with utils.Tempdir() as d:
         d.create_file(
             "foo.pyi", """
     from typing import MutableSet
     def f() -> MutableSet[str]
   """)
         ty = self.Infer("""\
     import foo
     x = foo.f()
     x.add(1)
     a = x.pop()
     x.discard(2)
     x.clear()
     x.add(3j)
     x.remove(3j)
     b = x & {1,2,3}
     c = x | {1,2,3}
     d = x ^ {1,2,3}
     e = 3 in x
   """,
                         deep=False,
                         pythonpath=[d.path])
         self.assertTypesMatchPytd(
             ty, """
     from typing import MutableSet, Union
     foo = ...  # type: module
     a = ...  # type: Union[int, str]
     # TODO(kramm): We do a clear() after adding "int".
     #              Why does "int" still appear for b?
     b = ...  # type: MutableSet[Union[complex, int, str]]
     c = ...  # type: MutableSet[Union[complex, int, str]]
     d = ...  # type: MutableSet[Union[complex, int, str]]
     e = ...  # type: bool
     x = ...  # type: MutableSet[Union[complex, int, str]]
   """)
예제 #7
0
    def testLoadWithDifferentModuleName(self):
        with utils.Tempdir() as d:
            original_module_name = "module1"
            pickled_ast_filename = os.path.join(d.path, "module1.pyi.pickled")
            module_map = self._StoreAst(d, original_module_name,
                                        pickled_ast_filename)
            original_ast = module_map[original_module_name]
            del module_map[original_module_name]

            new_module_name = "wurstbrot.module2"
            serializable_ast = pytd_utils.LoadPickle(pickled_ast_filename)
            serializable_ast = serialize_ast.EnsureAstName(serializable_ast,
                                                           new_module_name,
                                                           fix=True)
            loaded_ast = serialize_ast.ProcessAst(serializable_ast, module_map)

            self.assertTrue(loaded_ast)
            self.assertIsNot(loaded_ast, original_ast)
            self.assertEqual(loaded_ast.name, new_module_name)
            loaded_ast.Visit(visitors.VerifyLookup())
            self.assertFalse(original_ast.ASTeq(loaded_ast))
            ast_new_module, _ = self._GetAst(temp_dir=d,
                                             module_name=new_module_name)
            self.assertTrue(ast_new_module.ASTeq(loaded_ast))
예제 #8
0
    def testRenameModuleWithTypeParameter(self):
        module_name = "foo.bar"
        src = """
      import typing

      T = TypeVar('T')

      class SomeClass(typing.Generic[T]):
        def __init__(self, foo: T) -> None:
          pass
    """
        with utils.Tempdir() as d:
            ast, _ = self._GetAst(temp_dir=d, module_name=module_name, src=src)
        new_ast = ast.Visit(
            serialize_ast.RenameModuleVisitor(module_name, "other.name"))

        some_class = new_ast.Lookup("other.name.SomeClass")
        self.assertTrue(some_class)
        init_function = some_class.Lookup("__init__")
        self.assertTrue(init_function)
        self.assertEqual(len(init_function.signatures), 1)
        signature, = init_function.signatures
        _, param2 = signature.params
        self.assertEqual(param2.type.scope, "other.name.SomeClass")
예제 #9
0
파일: utils_test.py 프로젝트: runt18/pytype
 def testTempdir(self):
     with utils.Tempdir() as d:
         filename1 = d.create_file("foo.txt")
         filename2 = d.create_file("bar.txt", "\tdata2")
         filename3 = d.create_file("baz.txt", "data3")
         filename4 = d.create_file("d1/d2/qqsv.txt", "  data4.1\n  data4.2")
         filename5 = d.create_directory("directory")
         self.assertEquals(filename1, d["foo.txt"])
         self.assertEquals(filename2, d["bar.txt"])
         self.assertEquals(filename3, d["baz.txt"])
         self.assertEquals(filename4, d["d1/d2/qqsv.txt"])
         self.assertTrue(os.path.isdir(d.path))
         self.assertTrue(os.path.isfile(filename1))
         self.assertTrue(os.path.isfile(filename2))
         self.assertTrue(os.path.isfile(filename3))
         self.assertTrue(os.path.isfile(filename4))
         self.assertTrue(os.path.isdir(os.path.join(d.path, "d1")))
         self.assertTrue(os.path.isdir(os.path.join(d.path, "d1", "d2")))
         self.assertTrue(os.path.isdir(filename5))
         self.assertEqual(filename4,
                          os.path.join(d.path, "d1", "d2", "qqsv.txt"))
         for filename, contents in [
             (filename1, ""),
             (filename2, "data2"),  # dedented
             (filename3, "data3"),
             (filename4, "data4.1\ndata4.2"),  # dedented
         ]:
             with open(filename, "rb") as fi:
                 self.assertEquals(fi.read(), contents)
     self.assertFalse(os.path.isdir(d.path))
     self.assertFalse(os.path.isfile(filename1))
     self.assertFalse(os.path.isfile(filename2))
     self.assertFalse(os.path.isfile(filename3))
     self.assertFalse(os.path.isdir(os.path.join(d.path, "d1")))
     self.assertFalse(os.path.isdir(os.path.join(d.path, "d1", "d2")))
     self.assertFalse(os.path.isdir(filename5))
예제 #10
0
 def testDontPropagatePyval(self):
     # in functions like f(x: T) -> T, if T has constraints we should not copy
     # the value of constant types between instances of the typevar.
     with utils.Tempdir() as d:
         d.create_file(
             "a.pyi", """
     from typing import TypeVar
     AnyInt = TypeVar('AnyInt', int)
     def f(x: AnyInt) -> AnyInt
   """)
         ty = self.Infer("""
     import a
     if a.f(0):
       x = 3
     if a.f(1):
       y = 3
   """,
                         pythonpath=[d.path])
         self.assertTypesMatchPytd(
             ty, """
     a = ...  # type: module
     x = ...  # type: int
     y = ...  # type: int
   """)
예제 #11
0
 def testInferCalledDecoratedMethod(self):
     with utils.Tempdir() as d:
         d.create_file(
             "foo.pyi", """
     from typing import Any, Callable, List, TypeVar
     T = TypeVar("T")
     def decorator(x: Callable[Any, T]) -> Callable[Any, T]: ...
   """)
         ty = self.Infer("""
     import foo
     class A(object):
       @foo.decorator
       def f(self, x=None):
         pass
     A().f(42)
   """,
                         pythonpath=[d.path])
         self.assertTypesMatchPytd(
             ty, """
     from typing import Any, Callable
     foo = ...  # type: module
     class A(object):
       f = ...  # type: Callable
   """)
예제 #12
0
 def test_function_class(self):
     with utils.Tempdir() as d:
         d.create_file("foo.pyi", """
     def f() -> None: ...
   """)
         ty = self.Infer("""
     import foo
     def f(): pass
     v1 = (foo.f,)
     v2 = type(foo.f)
     w1 = (f,)
     w2 = type(f)
   """,
                         pythonpath=[d.path])
         self.assertTypesMatchPytd(
             ty, """
     from typing import Any, Callable, Tuple, Type
     foo = ...  # type: module
     def f() -> None: ...
     v1 = ...  # type: Tuple[Callable[[], None]]
     v2 = ...  # type: Type[Callable]
     w1 = ...  # type: Tuple[Callable[[], Any]]
     w2 = ...  # type: Type[Callable]
   """)
예제 #13
0
    def test_type_parameter_in_return(self):
        with utils.Tempdir() as d:
            d.create_file(
                "foo.pyi", """
        from typing import Generic, TypeVar
        T = TypeVar("T")
        class MyPattern(Generic[T]):
          def match(self, string: T) -> MyMatch[T]
        class MyMatch(Generic[T]):
          pass
        def compile() -> MyPattern[T]: ...
      """)
            ty = self.Infer("""\
        import foo
        x = foo.compile().match("")
      """,
                            pythonpath=[d.path])
            self.assertTypesMatchPytd(
                ty, """
        import typing

        foo = ...  # type: module
        x = ...  # type: foo.MyMatch[str]
      """)
예제 #14
0
 def test_namedtuple_item(self):
     with utils.Tempdir() as d:
         d.create_file(
             "foo.pyi", """
     from typing import NamedTuple
     def f() -> NamedTuple("ret", [("x", int), ("y", unicode)])
   """)
         ty = self.Infer("""
     import foo
     w = foo.f()[-1]
     x = foo.f()[0]
     y = foo.f()[1]
     z = foo.f()[2]  # out of bounds, fall back to the combined element type
   """,
                         deep=False,
                         pythonpath=[d.path])
         self.assertTypesMatchPytd(
             ty, """
     foo = ...  # type: module
     w = ...  # type: unicode
     x = ...  # type: int
     y = ...  # type: unicode
     z = ...  # type: int or unicode
   """)
예제 #15
0
  def testCallableParameters(self):
    with utils.Tempdir() as d:
      d.create_file("foo.pyi", """
        from typing import Any, Callable, List, TypeVar
        T = TypeVar("T")
        def f1(x: Callable[..., T]) -> List[T]: ...
        def f2(x: Callable[[T], Any]) -> List[T]: ...
      """)
      ty = self.Infer("""\
        from __future__ import google_type_annotations
        from typing import Any, Callable
        import foo

        def g1(): pass
        def g2() -> int: pass
        v1 = foo.f1(g1)
        v2 = foo.f1(g2)

        def g3(x): pass
        def g4(x: int): pass
        w1 = foo.f2(g3)
        w2 = foo.f2(g4)
      """, deep=False, pythonpath=[d.path])
      self.assertTypesMatchPytd(ty, """
        from typing import Any, List
        foo = ...  # type: module
        def g1() -> Any: ...
        def g2() -> int: ...
        def g3(x) -> Any: ...
        def g4(x: int) -> Any: ...

        v1 = ...  # type: list
        v2 = ...  # type: List[int]
        w1 = ...  # type: list
        w2 = ...  # type: List[int]
      """)
예제 #16
0
 def testRaises(self):
     with utils.Tempdir() as d:
         d.create_file("foo.pyi", """
     def f(raises): ...
   """)
         self.Check("import foo", pythonpath=[d.path])
예제 #17
0
 def testNoInit(self):
   with utils.Tempdir() as d:
     d.create_directory("baz")
     self.options.tweak(pythonpath=[d.path])
     loader = load_pytd.Loader("base", self.options)
     self.assertTrue(loader.import_name("baz"))
예제 #18
0
 def testInit(self):
   with utils.Tempdir() as d1:
     d1.create_file("baz/__init__.pyi", "x = ... # type: int")
     self.options.tweak(pythonpath=[d1.path])
     loader = load_pytd.Loader("base", self.options)
     self.assertTrue(loader.import_name("baz").Lookup("baz.x"))
예제 #19
0
    def testUnrestorableChild(self):
        # Assume .cls in a ClassType X in module1 was referencing something for
        # which, Visitors.LookupExternalTypes returned AnythingType.
        # Now if something in module1 is referencing X external types need to be
        # resolved before local types, so that we can resolve local types to the
        # correct ClassType, as the ClassType instance changes, if .cls can not be
        # filled and instead AnythingType is used.

        class RenameVisitor(visitors.Visitor):
            def __init__(self, *args, **kwargs):
                super(RenameVisitor, self).__init__(*args, **kwargs)
                self._init = False

            def EnterFunction(self, func):
                if func.name == "__init__":
                    self._init = True
                    return None
                return False

            def LeaveFunction(self, func):
                self._init = False

            def VisitClassType(self, cls_type):
                if self._init:
                    cls_type = cls_type.Replace(
                        name="other_module.unknown_Reference")
                    # Needs to be copied manually as it is not part of the NamedTuple.
                    cls_type.cls = None
                return cls_type

        with utils.Tempdir() as d:
            src = ("""
        import other_module
        x = other_module.UnusedReferenceNeededToKeepTheImport

        class SomeClass(object):
          def __init__(will_be_replaced_with_visitor) -> None:
            pass

        def func(a:SomeClass) -> None:
          pass
      """)
            d.create_file(
                "other_module.pyi", """
          from typing import Any
          def __getattr__(self, name) -> Any: ...""")
            ast, loader = self._GetAst(temp_dir=d,
                                       module_name="module1",
                                       src=src)

            ast = ast.Visit(RenameVisitor())

            pickled_ast_filename = os.path.join(d.path, "module1.pyi.pickled")
            module_map = self._StoreAst(d,
                                        "module1",
                                        pickled_ast_filename,
                                        ast=ast,
                                        loader=loader)
            del module_map["module1"]

            serialized_ast = pytd_utils.LoadPickle(pickled_ast_filename)
            loaded_ast = serialize_ast.ProcessAst(serialized_ast, module_map)
            # Look up the "SomeClass" in "def func(a: SomeClass), then run
            # VerifyLookup on it. We can't run VerifyLookup on the root node, since
            # visitors don't descend into the "cls" attribute of ClassType.
            cls = loaded_ast.functions[0].signatures[0].params[0].type.cls
            cls.Visit(visitors.VerifyLookup())
예제 #20
0
 def testNoInit(self):
   with utils.Tempdir() as d:
     d.create_directory("baz")
     loader = load_pytd.Loader(
         "base", self.PYTHON_VERSION, pythonpath=[d.path])
     self.assertTrue(loader.import_name("baz"))
예제 #21
0
 def _load_ast(self, name, src):
     with utils.Tempdir() as d:
         d.create_file(name + ".pyi", src)
         self._vm.options.tweak(pythonpath=[d.path])
         return self._vm.loader.import_name(name)
예제 #22
0
 def _load_ast(self, name, src):
     with utils.Tempdir() as d:
         d.create_file(name + ".pyi", src)
         self._vm.loader.pythonpath = [d.path]  # monkeypatch
         return self._vm.loader.import_name(name)
예제 #23
0
 def testInit(self):
   with utils.Tempdir() as d1:
     d1.create_file("baz/__init__.pytd", "x = ... # type: int")
     loader = load_pytd.Loader("base", python_version=self.PYTHON_VERSION,
                               pythonpath=[d1.path])
     self.assertTrue(loader.import_name("baz").Lookup("baz.x"))