From b4b7de98d016287e2147f603a1fdd19ea7c43b8a Mon Sep 17 00:00:00 2001 From: Brian Weber Date: Tue, 23 May 2017 14:28:03 -0700 Subject: [PATCH 01/27] Consistent quote wrapping around MessageBuilder.format as per issue #3409 --- mypy/messages.py | 25 ++++--- test-data/unit/check-async-await.test | 40 +++++----- test-data/unit/check-class-namedtuple.test | 6 +- test-data/unit/check-classes.test | 52 ++++++------- test-data/unit/check-dynamic-typing.test | 2 +- test-data/unit/check-enum.test | 2 +- test-data/unit/check-expressions.test | 36 ++++----- test-data/unit/check-flags.test | 4 +- test-data/unit/check-functions.test | 16 ++-- test-data/unit/check-generic-subtyping.test | 66 ++++++++--------- test-data/unit/check-generics.test | 66 ++++++++--------- test-data/unit/check-ignore.test | 6 +- test-data/unit/check-incremental.test | 6 +- test-data/unit/check-inference-context.test | 46 ++++++------ test-data/unit/check-inference.test | 82 ++++++++++----------- test-data/unit/check-isinstance.test | 16 ++-- test-data/unit/check-kwargs.test | 24 +++--- test-data/unit/check-modules.test | 44 +++++------ test-data/unit/check-namedtuple.test | 6 +- test-data/unit/check-newsyntax.test | 14 ++-- test-data/unit/check-optional.test | 24 +++--- test-data/unit/check-overloading.test | 12 +-- test-data/unit/check-python2.test | 4 +- test-data/unit/check-statements.test | 10 +-- test-data/unit/check-tuples.test | 24 +++--- test-data/unit/check-type-checks.test | 2 +- test-data/unit/check-typeddict.test | 8 +- test-data/unit/check-typevar-values.test | 2 +- test-data/unit/check-unreachable-code.test | 2 +- test-data/unit/check-varargs.test | 44 +++++------ 30 files changed, 347 insertions(+), 344 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index e8fb537f6fa5..ad158d4edc9f 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -183,7 +183,7 @@ def format(self, typ: Type, verbosity: int = 0) -> str: Mostly behave like format_simple below, but never return an empty string. """ s = self.format_simple(typ, verbosity) - if s != '': + if s != '' and s != '""': # If format_simple returns a non-trivial result, use that. return s elif isinstance(typ, FunctionLike): @@ -241,6 +241,9 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: None -> None callable type -> "" (empty string) """ + return '"{}"'.format(self._format_simple(typ, verbosity)) + + def _format_simple(self, typ: Type, verbosity: int = 0) -> str: if isinstance(typ, Instance): itype = typ # Get the short name of the type. @@ -256,7 +259,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: # No type arguments. Place the type name in quotes to avoid # potential for confusion: otherwise, the type name could be # interpreted as a normal word. - return '"{}"'.format(base_str) + return base_str elif itype.type.fullname() == 'builtins.tuple': item_type_str = strip_quotes(self.format(itype.args[0])) return 'Tuple[{}, ...]'.format(item_type_str) @@ -280,15 +283,15 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: return '{}[...]'.format(base_str) elif isinstance(typ, TypeVarType): # This is similar to non-generic instance types. - return '"{}"'.format(typ.name) + return typ.name elif isinstance(typ, TupleType): # Prefer the name of the fallback class (if not tuple), as it's more informative. if typ.fallback.type.fullname() != 'builtins.tuple': - return self.format_simple(typ.fallback) + return self._format_simple(typ.fallback) items = [] for t in typ.items: items.append(strip_quotes(self.format(t))) - s = '"Tuple[{}]"'.format(', '.join(items)) + s = 'Tuple[{}]'.format(', '.join(items)) if len(s) < 400: return s else: @@ -296,11 +299,11 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: elif isinstance(typ, TypedDictType): # If the TypedDictType is named, return the name if typ.fallback.type.fullname() != 'typing.Mapping': - return self.format_simple(typ.fallback) + return self._format_simple(typ.fallback) items = [] for (item_name, item_type) in typ.items.items(): items.append('{}={}'.format(item_name, strip_quotes(self.format(item_type)))) - s = '"TypedDict({})"'.format(', '.join(items)) + s = 'TypedDict({})'.format(', '.join(items)) return s elif isinstance(typ, UnionType): # Only print Unions as Optionals if the Optional wouldn't have to contain another Union @@ -308,12 +311,12 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: sum(isinstance(t, NoneTyp) for t in typ.items) == 1) if print_as_optional: rest = [t for t in typ.items if not isinstance(t, NoneTyp)] - return '"Optional[{}]"'.format(strip_quotes(self.format(rest[0]))) + return 'Optional[{}]'.format(strip_quotes(self.format(rest[0]))) else: items = [] for t in typ.items: items.append(strip_quotes(self.format(t))) - s = '"Union[{}]"'.format(', '.join(items)) + s = 'Union[{}]'.format(', '.join(items)) if len(s) < 400: return s else: @@ -321,7 +324,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: elif isinstance(typ, NoneTyp): return 'None' elif isinstance(typ, AnyType): - return '"Any"' + return 'Any' elif isinstance(typ, DeletedType): return '' elif isinstance(typ, UninhabitedType): @@ -331,7 +334,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: return '' elif isinstance(typ, TypeType): return 'Type[{}]'.format( - strip_quotes(self.format_simple(typ.item, verbosity))) + strip_quotes(self._format_simple(typ.item, verbosity))) elif typ is None: raise RuntimeError('Type is None') else: diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 672bf2b408b8..7d9f7bde2a13 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -84,7 +84,7 @@ async def f() -> int: x = await g() return x [out] -main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type Awaitable[Any]) +main:7: error: Incompatible types in await (actual type "Generator[int, None, str]", expected type "Awaitable[Any]") [case testAwaitIteratorError] @@ -95,7 +95,7 @@ async def f() -> int: x = await g() return x [out] -main:6: error: Incompatible types in await (actual type Iterator[Any], expected type Awaitable[Any]) +main:6: error: Incompatible types in await (actual type "Iterator[Any]", expected type "Awaitable[Any]") [case testAwaitArgumentError] @@ -106,7 +106,7 @@ async def f() -> int: return x [builtins fixtures/async_await.pyi] [out] -main:5: error: Incompatible types in await (actual type "int", expected type Awaitable[Any]) +main:5: error: Incompatible types in await (actual type "int", expected type "Awaitable[Any]") [case testAwaitResultError] @@ -150,7 +150,7 @@ async def f() -> None: [builtins fixtures/async_await.pyi] [out] main:4: error: AsyncIterable expected -main:4: error: List[int] has no attribute "__aiter__" +main:4: error: "List[int]" has no attribute "__aiter__" [case testAsyncForTypeComments] @@ -232,13 +232,13 @@ async def wrong_iterable(obj: Iterable[int]): [out] main:18: error: AsyncIterable expected -main:18: error: Iterable[int] has no attribute "__aiter__"; maybe "__iter__"? +main:18: error: "Iterable[int]" has no attribute "__aiter__"; maybe "__iter__"? main:19: error: Iterable expected -main:19: error: asyncify[int] has no attribute "__iter__"; maybe "__aiter__"? +main:19: error: "asyncify[int]" has no attribute "__iter__"; maybe "__aiter__"? main:20: error: AsyncIterable expected -main:20: error: Iterable[int] has no attribute "__aiter__"; maybe "__iter__"? +main:20: error: "Iterable[int]" has no attribute "__aiter__"; maybe "__iter__"? main:21: error: Iterable expected -main:21: error: asyncify[int] has no attribute "__iter__"; maybe "__aiter__"? +main:21: error: "asyncify[int]" has no attribute "__iter__"; maybe "__aiter__"? [builtins fixtures/async_await.pyi] [case testAsyncWith] @@ -271,7 +271,7 @@ class C: def __aenter__(self) -> int: pass async def __aexit__(self, x, y, z) -> None: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type Awaitable[Any]) + async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type "Awaitable[Any]") pass [builtins fixtures/async_await.pyi] [out] @@ -282,7 +282,7 @@ class C: def __aenter__(self) -> None: pass async def __aexit__(self, x, y, z) -> None: pass async def f() -> None: - async with C() as x: # E: None has no attribute "__await__" + async with C() as x: # E: "None" has no attribute "__await__" pass [builtins fixtures/async_await.pyi] [out] @@ -293,7 +293,7 @@ class C: async def __aenter__(self) -> int: pass def __aexit__(self, x, y, z) -> int: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type Awaitable[Any]) + async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type "Awaitable[Any]") pass [builtins fixtures/async_await.pyi] [out] @@ -304,7 +304,7 @@ class C: async def __aenter__(self) -> int: pass def __aexit__(self, x, y, z) -> None: pass async def f() -> None: - async with C() as x: # E: None has no attribute "__await__" + async with C() as x: # E: "None" has no attribute "__await__" pass [builtins fixtures/async_await.pyi] [out] @@ -362,7 +362,7 @@ def g() -> Generator[Any, None, str]: return x [builtins fixtures/async_await.pyi] [out] -main:6: error: "yield from" can't be applied to Awaitable[str] +main:6: error: "yield from" can't be applied to "Awaitable[str]" [case testAwaitableSubclass] @@ -523,7 +523,7 @@ def h() -> None: [out] main:9: error: Iterable expected -main:9: error: AsyncGenerator[int, None] has no attribute "__iter__"; maybe "__aiter__"? +main:9: error: "AsyncGenerator[int, None]" has no attribute "__iter__"; maybe "__aiter__"? [case testAsyncGeneratorNoYieldFrom] # flags: --fast-parser --python-version 3.6 @@ -607,19 +607,19 @@ def plain_host_generator() -> Generator[str, None, None]: yield 'a' x = 0 x = yield from plain_generator() - x = yield from plain_coroutine() # E: "yield from" can't be applied to Awaitable[int] + x = yield from plain_coroutine() # E: "yield from" can't be applied to "Awaitable[int]" x = yield from decorated_generator() - x = yield from decorated_coroutine() # E: "yield from" can't be applied to AwaitableGenerator[Any, Any, int, Awaitable[int]] + x = yield from decorated_coroutine() # E: "yield from" can't be applied to "AwaitableGenerator[Any, Any, int, Awaitable[int]]" x = yield from other_iterator() x = yield from other_coroutine() # E: "yield from" can't be applied to "Aw" async def plain_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) + x = await plain_generator() # E: Incompatible types in await (actual type "Generator[str, None, int]", expected type "Awaitable[Any]") x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable[Any]") x = await other_coroutine() @coroutine @@ -636,11 +636,11 @@ def decorated_host_generator() -> Generator[str, None, None]: @coroutine async def decorated_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) + x = await plain_generator() # E: Incompatible types in await (actual type "Generator[str, None, int]", expected type "Awaitable[Any]") x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable[Any]") x = await other_coroutine() [builtins fixtures/async_await.pyi] diff --git a/test-data/unit/check-class-namedtuple.test b/test-data/unit/check-class-namedtuple.test index 7a81adb0a672..7ae6c1f936bf 100644 --- a/test-data/unit/check-class-namedtuple.test +++ b/test-data/unit/check-class-namedtuple.test @@ -221,7 +221,7 @@ class MyNamedTuple(NamedTuple): a: int b: str -MyNamedTuple.x # E: Type[MyNamedTuple] has no attribute "x" +MyNamedTuple.x # E: "Type[MyNamedTuple]" has no attribute "x" [case testNewNamedTupleEmptyItems] # flags: --python-version 3.6 @@ -439,13 +439,13 @@ class HasNone(NamedTuple): y: Optional[int] = None reveal_type(HasNone(1)) # E: Revealed type is 'Tuple[builtins.int, Union[builtins.int, builtins.None], fallback=__main__.HasNone]' -HasNone(None) # E: Argument 1 to "HasNone" has incompatible type None; expected "int" +HasNone(None) # E: Argument 1 to "HasNone" has incompatible type "None"; expected "int" HasNone(1, y=None) HasNone(1, y=2) class CannotBeNone(NamedTuple): x: int - y: int = None # E: Incompatible types in assignment (expression has type None, variable has type "int") + y: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [builtins fixtures/list.pyi] diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index a257fa0375f0..f1c9373ba580 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -514,7 +514,7 @@ b = A.x # type: B # E: Incompatible types in assignment (expression has type "A" [case testAccessingUndefinedAttributeViaClass] import typing class A: pass -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAccessingUndefinedAttributeViaClassWithOverloadedInit] from foo import * @@ -525,7 +525,7 @@ class A: def __init__(self): pass @overload def __init__(self, x): pass -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAccessMethodOfClassWithOverloadedInit] from foo import * @@ -812,7 +812,7 @@ class C: cls(1) # E: Too many arguments for "C" cls.bar() cls.bar(1) # E: Too many arguments for "bar" of "C" - cls.bozo() # E: Type[C] has no attribute "bozo" + cls.bozo() # E: "Type[C]" has no attribute "bozo" [builtins fixtures/classmethod.pyi] [out] @@ -823,7 +823,7 @@ class C: def foo(cls) -> None: pass C.foo() C.foo(1) # E: Too many arguments for "foo" of "C" -C.bozo() # E: Type[C] has no attribute "bozo" +C.bozo() # E: "Type[C]" has no attribute "bozo" [builtins fixtures/classmethod.pyi] [case testClassMethodCalledOnInstance] @@ -833,7 +833,7 @@ class C: def foo(cls) -> None: pass C().foo() C().foo(1) # E: Too many arguments for "foo" of "C" -C.bozo() # E: Type[C] has no attribute "bozo" +C.bozo() # E: "Type[C]" has no attribute "bozo" [builtins fixtures/classmethod.pyi] [case testClassMethodMayCallAbstractMethod] @@ -1278,7 +1278,7 @@ class D: def __get__(self, inst: Any, own: str) -> Any: pass class A: f = D() -A().f # E: Argument 2 to "__get__" of "D" has incompatible type Type[A]; expected "str" +A().f # E: Argument 2 to "__get__" of "D" has incompatible type "Type[A]"; expected "str" [case testDescriptorGetSetDifferentTypes] from typing import Any @@ -1722,7 +1722,7 @@ class C: def f(x: type) -> None: pass def g(x: int) -> None: pass f(C) -g(C) # E: Argument 1 to "g" has incompatible type Type[C]; expected "int" +g(C) # E: Argument 1 to "g" has incompatible type "Type[C]"; expected "int" [builtins fixtures/__new__.pyi] [case testClassWith__new__AndCompatibilityWithType2] @@ -1733,7 +1733,7 @@ class C: def f(x: type) -> None: pass def g(x: int) -> None: pass f(C) -g(C) # E: Argument 1 to "g" has incompatible type Type[C]; expected "int" +g(C) # E: Argument 1 to "g" has incompatible type "Type[C]"; expected "int" [builtins fixtures/__new__.pyi] [case testGenericClassWith__new__] @@ -1813,7 +1813,7 @@ class B: [case testClassVsInstanceDisambiguation] class A: pass def f(x: A) -> None: pass -f(A) # E: Argument 1 to "f" has incompatible type Type[A]; expected "A" +f(A) # E: Argument 1 to "f" has incompatible type "Type[A]"; expected "A" [out] -- TODO @@ -2020,7 +2020,7 @@ class User: pass def new_user(user_class: Type[User]): return user_class() def foo(arg: Type[int]): - new_user(arg) # E: Argument 1 to "new_user" has incompatible type Type[int]; expected Type[User] + new_user(arg) # E: Argument 1 to "new_user" has incompatible type "Type[int]"; expected "Type[User]" [out] [case testTypeUsingTypeCUnionOverload] @@ -2059,7 +2059,7 @@ def foo(arg: Type[Any]): # Member access is ok and types as Any reveal_type(x) # E: Revealed type is 'Any' # But Type[Any] is distinct from Any - y: int = arg # E: Incompatible types in assignment (expression has type Type[Any], variable has type "int") + y: int = arg # E: Incompatible types in assignment (expression has type "Type[Any]", variable has type "int") [out] [case testTypeUsingTypeCTypeAnyMemberFallback] @@ -2100,7 +2100,7 @@ def process(cls: Type[User]): obj = cls() reveal_type(cls.bar(obj)) # E: Revealed type is 'builtins.int' cls.mro() # Defined in class type - cls.error # E: Type[User] has no attribute "error" + cls.error # E: "Type[User]" has no attribute "error" [builtins fixtures/classmethod.pyi] [out] @@ -2114,11 +2114,11 @@ class User: class ProUser(User): pass class BasicUser(User): pass def process(cls: Type[Union[BasicUser, ProUser]]): - cls.foo() # E: Type[Union[BasicUser, ProUser]] has no attribute "foo" + cls.foo() # E: "Type[Union[BasicUser, ProUser]]" has no attribute "foo" obj = cls() - cls.bar(obj) # E: Type[Union[BasicUser, ProUser]] has no attribute "bar" + cls.bar(obj) # E: "Type[Union[BasicUser, ProUser]]" has no attribute "bar" cls.mro() # Defined in class type - cls.error # E: Type[Union[BasicUser, ProUser]] has no attribute "error" + cls.error # E: "Type[Union[BasicUser, ProUser]]" has no attribute "error" [builtins fixtures/classmethod.pyi] [out] @@ -2134,7 +2134,7 @@ def process(cls: Type[U]): obj = cls() reveal_type(cls.bar(obj)) # E: Revealed type is 'builtins.int' cls.mro() # Defined in class type - cls.error # E: Type[U] has no attribute "error" + cls.error # E: "Type[U]" has no attribute "error" [builtins fixtures/classmethod.pyi] [out] @@ -2149,11 +2149,11 @@ class ProUser(User): pass class BasicUser(User): pass U = TypeVar('U', bound=Union[ProUser, BasicUser]) def process(cls: Type[U]): - cls.foo() # E: Type[U] has no attribute "foo" + cls.foo() # E: "Type[U]" has no attribute "foo" obj = cls() - cls.bar(obj) # E: Type[U] has no attribute "bar" + cls.bar(obj) # E: "Type[U]" has no attribute "bar" cls.mro() # Defined in class type - cls.error # E: Type[U] has no attribute "error" + cls.error # E: "Type[U]" has no attribute "error" [builtins fixtures/classmethod.pyi] [out] @@ -2621,7 +2621,7 @@ int.__eq__(3, 4) [builtins fixtures/args.pyi] [out] main:33: error: Too few arguments for "__eq__" of "int" -main:33: error: Unsupported operand types for == ("int" and Type[int]) +main:33: error: Unsupported operand types for == ("int" and "Type[int]") [case testMroSetAfterError] class C(str, str): @@ -2986,7 +2986,7 @@ class M: class A(metaclass=M): pass # E: Metaclasses not inheriting from 'type' are not supported -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testMetaclassTypeReveal] from typing import Type @@ -3057,7 +3057,7 @@ class Concrete(metaclass=Meta): pass reveal_type(Concrete + X()) # E: Revealed type is 'builtins.str' -Concrete + "hello" # E: Unsupported operand types for + (Type[Concrete] and "str") +Concrete + "hello" # E: Unsupported operand types for + ("Type[Concrete]" and "str") [case testMetaclassGetitem] class M(type): @@ -3085,7 +3085,7 @@ from missing import M class A(metaclass=M): y = 0 reveal_type(A.y) # E: Revealed type is 'builtins.int' -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAnyMetaclass] from typing import Any @@ -3093,7 +3093,7 @@ M = None # type: Any class A(metaclass=M): y = 0 reveal_type(A.y) # E: Revealed type is 'builtins.int' -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testInvalidVariableAsMetaclass] from typing import Any @@ -3104,7 +3104,7 @@ class A(metaclass=M): # E: Invalid metaclass 'M' class B(metaclass=MM): # E: Invalid metaclass 'MM' y = 0 reveal_type(A.y) # E: Revealed type is 'builtins.int' -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAnyAsBaseOfMetaclass] from typing import Any, Type @@ -3119,7 +3119,7 @@ class A(metaclass=MM): def h(a: Type[A], b: Type[object]) -> None: h(a, a) - h(b, a) # E: Argument 1 to "h" has incompatible type Type[object]; expected Type[A] + h(b, a) # E: Argument 1 to "h" has incompatible type "Type[object]"; expected "Type[A]" a.f(1) # E: Too many arguments for "f" of "A" reveal_type(a.y) # E: Revealed type is 'builtins.int' diff --git a/test-data/unit/check-dynamic-typing.test b/test-data/unit/check-dynamic-typing.test index 68a174e3cc81..22626cfffd88 100644 --- a/test-data/unit/check-dynamic-typing.test +++ b/test-data/unit/check-dynamic-typing.test @@ -485,7 +485,7 @@ class A: def __init__(self, a, b): pass [out] main:6: error: Too few arguments for "A" -main:7: error: Incompatible types in assignment (expression has type Type[A], variable has type Callable[[A], A]) +main:7: error: Incompatible types in assignment (expression has type "Type[A]", variable has type Callable[[A], A]) [case testUsingImplicitTypeObjectWithIs] diff --git a/test-data/unit/check-enum.test b/test-data/unit/check-enum.test index 011580effb35..d6e7a65abfc4 100644 --- a/test-data/unit/check-enum.test +++ b/test-data/unit/check-enum.test @@ -325,7 +325,7 @@ main:17: error: Enum() with dict literal requires string literals main:18: error: Unexpected arguments to Enum() main:19: error: Unexpected arguments to Enum() main:20: error: Unexpected arguments to Enum() -main:22: error: Type[W] has no attribute "c" +main:22: error: "Type[W]" has no attribute "c" [case testFunctionalEnumFlag] from enum import Flag, IntFlag diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index 1d840269da42..8ecdb19f4ec0 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -1125,7 +1125,7 @@ b'%a' % 3 from typing import Any, Dict a = None # type: Any ds, do, di = None, None, None # type: Dict[str, int], Dict[object, int], Dict[int, int] -'%(a)' % 1 # E: Format requires a mapping (expression has type "int", expected type for mapping is Dict[Any, Any]) +'%(a)' % 1 # E: Format requires a mapping (expression has type "int", expected type for mapping is "Dict[Any, Any]") '%()d' % a '%()d' % ds '%()d' % do @@ -1298,7 +1298,7 @@ class B: pass [out] main:5: error: Key expression in dictionary comprehension has incompatible type "A"; expected type "B" main:5: error: Value expression in dictionary comprehension has incompatible type "B"; expected type "A" -main:6: error: Incompatible types in assignment (expression has type Dict[A, B], variable has type "A") +main:6: error: Incompatible types in assignment (expression has type "Dict[A, B]", variable has type "A") [case testDictionaryComprehensionWithNonDirectMapping] @@ -1384,7 +1384,7 @@ cast(A, f) def f() -> None: pass [out] -main:5: error: Unsupported left operand type for + (None) +main:5: error: Unsupported left operand type for + ("None") main:6: error: Unsupported left operand type for + (Callable[[], None]) main:7: error: Unsupported operand types for + ("A" and Callable[[], None]) @@ -1522,7 +1522,7 @@ d1 = dict(a=1, b=2) # type: Dict[str, int] d2 = dict(a=1, b='') # type: Dict[str, int] # E: Dict entry 1 has incompatible type "str": "str" d3 = dict(a=1) # type: Dict[int, int] # E: Dict entry 0 has incompatible type "str": "int" d4 = dict(a=1, b=1) -d4.xyz # E: Dict[str, int] has no attribute "xyz" +d4.xyz # E: "Dict[str, int]" has no attribute "xyz" d5 = dict(a=1, b='') # type: Dict[str, Any] [builtins fixtures/dict.pyi] @@ -1536,7 +1536,7 @@ dict(undefined) # E: Name 'undefined' is not defined [case testDictFromList] from typing import Dict d = dict([(1, 'x'), (2, 'y')]) -d() # E: Dict[int, str] not callable +d() # E: "Dict[int, str]" not callable d2 = dict([(1, 'x')]) # type: Dict[str, str] # E: List item 0 has incompatible type "Tuple[int, str]" [builtins fixtures/dict.pyi] @@ -1545,10 +1545,10 @@ from typing import Dict it = [('x', 1)] d = dict(it, x=1) -d() # E: Dict[str, int] not callable +d() # E: "Dict[str, int]" not callable d2 = dict(it, x='') # E: Cannot infer type argument 2 of "dict" -d2() # E: Dict[Any, Any] not callable +d2() # E: "Dict[Any, Any]" not callable d3 = dict(it, x='') # type: Dict[str, int] # E: Argument 2 to "dict" has incompatible type "str"; expected "int" [builtins fixtures/dict.pyi] @@ -1560,7 +1560,7 @@ dict(it, x='y') # E: Keyword argument only valid with "str" key type in call to [case testDictFromIterableAndKeywordArg3] d = dict([], x=1) -d() # E: Dict[str, int] not callable +d() # E: "Dict[str, int]" not callable [builtins fixtures/dict.pyi] [case testDictFromIterableAndStarStarArgs] @@ -1569,20 +1569,20 @@ it = [('x', 1)] kw = {'x': 1} d = dict(it, **kw) -d() # E: Dict[str, int] not callable +d() # E: "Dict[str, int]" not callable kw2 = {'x': ''} d2 = dict(it, **kw2) # E: Cannot infer type argument 2 of "dict" -d2() # E: Dict[Any, Any] not callable +d2() # E: "Dict[Any, Any]" not callable -d3 = dict(it, **kw2) # type: Dict[str, int] # E: Argument 2 to "dict" has incompatible type **Dict[str, str]; expected "int" +d3 = dict(it, **kw2) # type: Dict[str, int] # E: Argument 2 to "dict" has incompatible type **"Dict[str, str]"; expected "int" [builtins fixtures/dict.pyi] [case testDictFromIterableAndStarStarArgs2] it = [(1, 'x')] kw = {'x': 'y'} d = dict(it, **kw) # E: Keyword argument only valid with "str" key type in call to "dict" -d() # E: Dict[int, str] not callable +d() # E: "Dict[int, str]" not callable [builtins fixtures/dict.pyi] [case testUserDefinedClassNamedDict] @@ -1602,10 +1602,10 @@ class D1(dict): pass # Implicit base class Dict[Any, Any] D1([(1, 2)], x=1) class D2(Dict[T, S], Generic[T, S]): pass da = D2([('x', 2)], x=1) -da() # E: D2[str, int] not callable +da() # E: "D2[str, int]" not callable D2([(1, 2)], x=1) # E: Keyword argument only valid with "str" key type in call to "dict" db = D2(x=1) -db() # E: D2[str, int] not callable +db() # E: "D2[str, int]" not callable [builtins fixtures/dict.pyi] [case testSpecialSignatureForSubclassOfDict2] @@ -1622,7 +1622,7 @@ S = TypeVar('S') class D(Dict[T, S], Generic[T, S]): def __init__(self, x: S, y: T) -> None: pass d = D(1, y='') -d() # E: D[str, int] not callable +d() # E: "D[str, int]" not callable [builtins fixtures/dict.pyi] [case testRevealType] @@ -1654,7 +1654,7 @@ None == None [builtins fixtures/ops.pyi] [case testLtNone] -None < None # E: Unsupported left operand type for < (None) +None < None # E: Unsupported left operand type for < ("None") [builtins fixtures/ops.pyi] [case testDictWithStarExpr] @@ -1669,6 +1669,6 @@ a = {'a': 1} b = {'z': 26, **a} c = {**b} d = {**a, **b, 'c': 3} -e = {1: 'a', **a} # E: Argument 1 to "update" of "dict" has incompatible type Dict[str, int]; expected Mapping[int, str] -f = {**b} # type: Dict[int, int] # E: List item 0 has incompatible type Dict[str, int] +e = {1: 'a', **a} # E: Argument 1 to "update" of "dict" has incompatible type "Dict[str, int]"; expected "Mapping[int, str]" +f = {**b} # type: Dict[int, int] # E: List item 0 has incompatible type "Dict[str, int]" [builtins fixtures/dict.pyi] diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test index 2b0e5549589a..b270ec8b854c 100644 --- a/test-data/unit/check-flags.test +++ b/test-data/unit/check-flags.test @@ -190,7 +190,7 @@ reveal_type(f() or no_return()) # E: Revealed type is 'builtins.int' # flags: --warn-no-return from mypy_extensions import NoReturn -x = 0 # type: NoReturn # E: Incompatible types in assignment (expression has type "int", variable has type NoReturn) +x = 0 # type: NoReturn # E: Incompatible types in assignment (expression has type "int", variable has type "NoReturn") [builtins fixtures/dict.pyi] [case testNoReturnImportFromTyping] @@ -206,7 +206,7 @@ def no_return() -> NoReturn: pass def f() -> NoReturn: no_return() -x: NoReturn = 0 # E: Incompatible types in assignment (expression has type "int", variable has type NoReturn) +x: NoReturn = 0 # E: Incompatible types in assignment (expression has type "int", variable has type "NoReturn") [builtins fixtures/dict.pyi] [case testShowErrorContextFunction] diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index e4a155a748ed..963c8caba5a3 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -254,7 +254,7 @@ class A: pass t = None # type: type a = None # type: A -a = A # E: Incompatible types in assignment (expression has type Type[A], variable has type "A") +a = A # E: Incompatible types in assignment (expression has type "Type[A]", variable has type "A") t = f # E: Incompatible types in assignment (expression has type Callable[[], None], variable has type "type") t = A @@ -334,10 +334,10 @@ def f(x: C) -> C: pass from typing import Any, Callable, List def f(fields: List[Callable[[Any], Any]]): pass class C: pass -f([C]) # E: List item 0 has incompatible type +f([C]) # E: List item 0 has incompatible type "" class D: def __init__(self, a, b): pass -f([D]) # E: List item 0 has incompatible type +f([D]) # E: List item 0 has incompatible type "" [builtins fixtures/list.pyi] [case testSubtypingTypeTypeAsCallable] @@ -352,7 +352,7 @@ from typing import Callable, Type class A: pass x = None # type: Callable[..., A] y = None # type: Type[A] -y = x # E: Incompatible types in assignment (expression has type Callable[..., A], variable has type Type[A]) +y = x # E: Incompatible types in assignment (expression has type Callable[..., A], variable has type "Type[A]") -- Default argument values -- ----------------------- @@ -517,7 +517,7 @@ class A(Generic[t]): g = f a = None # type: A[B] a.g(B()) -a.g(a) # E: Argument 1 has incompatible type A[B]; expected "B" +a.g(a) # E: Argument 1 has incompatible type "A[B]"; expected "B" [case testInvalidMethodAsDataAttributeInGenericClass] from typing import Any, TypeVar, Generic, Callable @@ -1479,7 +1479,7 @@ L = Callable[[Arg(name='x', type=int)], int] # ok # I have commented out the following test because I don't know how to expect the "defined here" note part of the error. # M = Callable[[Arg(gnome='x', type=int)], int] E: Invalid type alias E: Unexpected keyword argument "gnome" for "Arg" N = Callable[[Arg(name=None, type=int)], int] # ok -O = Callable[[List[Arg(int)]], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: Type expected within [...] # E: The type Type[List[Any]] is not generic and not indexable +O = Callable[[List[Arg(int)]], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: Type expected within [...] # E: The type "Type[List[Any]]" is not generic and not indexable P = Callable[[mypy_extensions.VarArg(int)], int] # ok Q = Callable[[Arg(int, type=int)], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "type" R = Callable[[Arg(int, 'x', name='y')], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "name" @@ -1735,7 +1735,7 @@ f(x=1, y="hello", z=[]) from typing import Dict def f(x, **kwargs): # type: (...) -> None success_dict_type = kwargs # type: Dict[str, str] - failure_dict_type = kwargs # type: Dict[int, str] # E: Incompatible types in assignment (expression has type Dict[str, Any], variable has type Dict[int, str]) + failure_dict_type = kwargs # type: Dict[int, str] # E: Incompatible types in assignment (expression has type "Dict[str, Any]", variable has type "Dict[int, str]") f(1, thing_in_kwargs=["hey"]) [builtins fixtures/dict.pyi] [out] @@ -1744,7 +1744,7 @@ f(1, thing_in_kwargs=["hey"]) from typing import Tuple, Any def f(x, *args): # type: (...) -> None success_tuple_type = args # type: Tuple[Any, ...] - fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type Tuple[Any, ...], variable has type None) + fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type "Tuple[Any, ...]", variable has type "None") f(1, "hello") [builtins fixtures/tuple.pyi] [out] diff --git a/test-data/unit/check-generic-subtyping.test b/test-data/unit/check-generic-subtyping.test index 6cae196bbe80..9c5d242368a8 100644 --- a/test-data/unit/check-generic-subtyping.test +++ b/test-data/unit/check-generic-subtyping.test @@ -13,9 +13,9 @@ ac = None # type: A[C] ad = None # type: A[D] b = None # type: B -b = ad # E: Incompatible types in assignment (expression has type A[D], variable has type "B") -ad = b # E: Incompatible types in assignment (expression has type "B", variable has type A[D]) -b = ac # E: Incompatible types in assignment (expression has type A[C], variable has type "B") +b = ad # E: Incompatible types in assignment (expression has type "A[D]", variable has type "B") +ad = b # E: Incompatible types in assignment (expression has type "B", variable has type "A[D]") +b = ac # E: Incompatible types in assignment (expression has type "A[C]", variable has type "B") b = b ac = b @@ -32,10 +32,10 @@ a = None # type: A bc = None # type: B[C] bd = None # type: B[D] -bc = bd # E: Incompatible types in assignment (expression has type B[D], variable has type B[C]) -bd = bc # E: Incompatible types in assignment (expression has type B[C], variable has type B[D]) -bc = a # E: Incompatible types in assignment (expression has type "A", variable has type B[C]) -bd = a # E: Incompatible types in assignment (expression has type "A", variable has type B[D]) +bc = bd # E: Incompatible types in assignment (expression has type "B[D]", variable has type "B[C]") +bd = bc # E: Incompatible types in assignment (expression has type "B[C]", variable has type "B[D]") +bc = a # E: Incompatible types in assignment (expression has type "A", variable has type "B[C]") +bd = a # E: Incompatible types in assignment (expression has type "A", variable has type "B[D]") a = bc a = bd @@ -54,10 +54,10 @@ ad = None # type: A[D] bcc = None # type: B[C, C] bdc = None # type: B[D, C] -ad = bcc # E: Incompatible types in assignment (expression has type B[C, C], variable has type A[D]) -ad = bdc # E: Incompatible types in assignment (expression has type B[D, C], variable has type A[D]) -bcc = ac # E: Incompatible types in assignment (expression has type A[C], variable has type B[C, C]) -bdc = ac # E: Incompatible types in assignment (expression has type A[C], variable has type B[D, C]) +ad = bcc # E: Incompatible types in assignment (expression has type "B[C, C]", variable has type "A[D]") +ad = bdc # E: Incompatible types in assignment (expression has type "B[D, C]", variable has type "A[D]") +bcc = ac # E: Incompatible types in assignment (expression has type "A[C]", variable has type "B[C, C]") +bdc = ac # E: Incompatible types in assignment (expression has type "A[C]", variable has type "B[D, C]") bcc = bcc bdc = bdc @@ -82,8 +82,8 @@ cef = None # type: C[E, F] cff = None # type: C[F, F] cfe = None # type: C[F, E] -ae = cef # E: Incompatible types in assignment (expression has type C[E, F], variable has type A[A[E]]) -af = cfe # E: Incompatible types in assignment (expression has type C[F, E], variable has type A[A[F]]) +ae = cef # E: Incompatible types in assignment (expression has type "C[E, F]", variable has type "A[A[E]]") +af = cfe # E: Incompatible types in assignment (expression has type "C[F, E]", variable has type "A[A[F]]") ae = cfe af = cef @@ -280,7 +280,7 @@ a = None # type: A bc = None # type: B[C] bd = None # type: B[D] -a = bc # E: Incompatible types in assignment (expression has type B[C], variable has type "A") +a = bc # E: Incompatible types in assignment (expression has type "B[C]", variable has type "A") bc = a bd = a @@ -305,8 +305,8 @@ a = None # type: A c = None # type: C bc = None # type: B[C] -a.x = c # E: Incompatible types in assignment (expression has type "C", variable has type B[Any]) -a.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected B[Any] +a.x = c # E: Incompatible types in assignment (expression has type "C", variable has type "B[Any]") +a.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected "B[Any]" a.x = bc a.f(bc) [out] @@ -325,8 +325,8 @@ class B(Generic[T]): class A(B): def g(self) -> None: - self.x = c # E: Incompatible types in assignment (expression has type "C", variable has type B[Any]) - self.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected B[Any] + self.x = c # E: Incompatible types in assignment (expression has type "C", variable has type "B[Any]") + self.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected "B[Any]" self.x = bc self.f(bc) @@ -394,7 +394,7 @@ B(1) C(1) C('a') # E: Argument 1 to "C" has incompatible type "str"; expected "int" D(A(1)) -D(1) # E: Argument 1 to "D" has incompatible type "int"; expected A[] +D(1) # E: Argument 1 to "D" has incompatible type "int"; expected "A[]" [case testInheritedConstructor2] @@ -427,9 +427,9 @@ adc = None # type: A[D, C] ic = None # type: I[C] id = None # type: I[D] -ic = acd # E: Incompatible types in assignment (expression has type A[C, D], variable has type I[C]) -id = adc # E: Incompatible types in assignment (expression has type A[D, C], variable has type I[D]) -adc = ic # E: Incompatible types in assignment (expression has type I[C], variable has type A[D, C]) +ic = acd # E: Incompatible types in assignment (expression has type "A[C, D]", variable has type "I[C]") +id = adc # E: Incompatible types in assignment (expression has type "A[D, C]", variable has type "I[D]") +adc = ic # E: Incompatible types in assignment (expression has type "I[C]", variable has type "A[D, C]") ic = adc id = acd @@ -451,11 +451,11 @@ class I(Generic[S]): pass class B(I[C]): pass class A(B): pass -ie = a # E: Incompatible types in assignment (expression has type "A", variable has type I[E]) -a = ic # E: Incompatible types in assignment (expression has type I[C], variable has type "A") -a = id # E: Incompatible types in assignment (expression has type I[D], variable has type "A") +ie = a # E: Incompatible types in assignment (expression has type "A", variable has type "I[E]") +a = ic # E: Incompatible types in assignment (expression has type "I[C]", variable has type "A") +a = id # E: Incompatible types in assignment (expression has type "I[D]", variable has type "A") a = b # E: Incompatible types in assignment (expression has type "B", variable has type "A") -id = a # E: Incompatible types in assignment (expression has type "A", variable has type I[D]) +id = a # E: Incompatible types in assignment (expression has type "A", variable has type "I[D]") ic = a b = a @@ -486,8 +486,8 @@ a, i, j = None, None, None # type: (A[object], I[object], J[object]) ii = a jj = a jj = i -a = i # E: Incompatible types in assignment (expression has type I[object], variable has type A[object]) -a = j # E: Incompatible types in assignment (expression has type J[object], variable has type A[object]) +a = i # E: Incompatible types in assignment (expression has type "I[object]", variable has type "A[object]") +a = j # E: Incompatible types in assignment (expression has type "J[object]", variable has type "A[object]") class J(Generic[t]): pass class X(metaclass=ABCMeta): pass @@ -546,7 +546,7 @@ class A(B): class C: pass class D: pass [out] -main:7: error: Incompatible types in assignment (expression has type "A", variable has type I[D]) +main:7: error: Incompatible types in assignment (expression has type "A", variable has type "I[D]") [case testSubclassingGenericABCWithDeepHierarchy2] from typing import Any, TypeVar, Generic @@ -704,7 +704,7 @@ a = None # type: G[A] b = None # type: G[B] c = None # type: G[C] -b = a # E: Incompatible types in assignment (expression has type G[A], variable has type G[B]) +b = a # E: Incompatible types in assignment (expression has type "G[A]", variable has type "G[B]") b = c [builtins fixtures/bool.pyi] [out] @@ -723,7 +723,7 @@ b = None # type: G[B] c = None # type: G[C] b = a -b = c # E: Incompatible types in assignment (expression has type G[C], variable has type G[B]) +b = c # E: Incompatible types in assignment (expression has type "G[C]", variable has type "G[B]") [builtins fixtures/bool.pyi] [out] @@ -740,8 +740,8 @@ a = None # type: G[A] b = None # type: G[B] c = None # type: G[C] -b = a # E: Incompatible types in assignment (expression has type G[A], variable has type G[B]) -b = c # E: Incompatible types in assignment (expression has type G[C], variable has type G[B]) +b = a # E: Incompatible types in assignment (expression has type "G[A]", variable has type "G[B]") +b = c # E: Incompatible types in assignment (expression has type "G[C]", variable has type "G[B]") [builtins fixtures/bool.pyi] [out] diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index 33106feca98d..f4a94281f8cd 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -79,8 +79,8 @@ class A(Generic[T]): pass class B: pass class C(B): pass [out] -main:4: error: Incompatible types in assignment (expression has type A[B], variable has type A[C]) -main:5: error: Incompatible types in assignment (expression has type A[C], variable has type A[B]) +main:4: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]") +main:5: error: Incompatible types in assignment (expression has type "A[C]", variable has type "A[B]") [case testGenericTypeCompatibilityWithAny] from typing import Any, TypeVar, Generic @@ -115,8 +115,8 @@ class A(Generic[T]): class B: pass class C: pass [out] -main:7: error: Incompatible types in assignment (expression has type A[C], variable has type A[B]) -main:8: error: Incompatible types in assignment (expression has type A[B], variable has type A[C]) +main:7: error: Incompatible types in assignment (expression has type "A[C]", variable has type "A[B]") +main:8: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]") [case testMultipleGenericTypeParametersWithMemberVars] from typing import TypeVar, Generic @@ -183,9 +183,9 @@ class A(Generic[S, T]): class B: pass class C(B):pass [out] -main:8: error: Incompatible types in assignment (expression has type A[B, C], variable has type A[B, B]) -main:9: error: Incompatible types in assignment (expression has type A[C, B], variable has type A[B, B]) -main:10: error: Incompatible types in assignment (expression has type A[B, B], variable has type A[B, C]) +main:8: error: Incompatible types in assignment (expression has type "A[B, C]", variable has type "A[B, B]") +main:9: error: Incompatible types in assignment (expression has type "A[C, B]", variable has type "A[B, B]") +main:10: error: Incompatible types in assignment (expression has type "A[B, B]", variable has type "A[B, C]") -- Simple generic type bodies @@ -208,7 +208,7 @@ x = None # type: B class B: pass [out] main:7: error: Argument 1 to "f" of "A" has incompatible type "B"; expected "T" -main:8: error: Incompatible types in assignment (expression has type A[T], variable has type A[B]) +main:8: error: Incompatible types in assignment (expression has type "A[T]", variable has type "A[B]") [case testGenericTypeBodyWithMultipleVariables] from typing import TypeVar, Generic @@ -229,8 +229,8 @@ class B: pass [out] main:8: error: Incompatible types in assignment (expression has type "T", variable has type "S") main:9: error: Incompatible types in assignment (expression has type "S", variable has type "T") -main:10: error: Incompatible types in assignment (expression has type A[S, T], variable has type A[S, B]) -main:11: error: Incompatible types in assignment (expression has type A[S, T], variable has type A[T, T]) +main:10: error: Incompatible types in assignment (expression has type "A[S, T]", variable has type "A[S, B]") +main:11: error: Incompatible types in assignment (expression has type "A[S, T]", variable has type "A[T, T]") [case testCompatibilityOfNoneWithTypeVar] from typing import TypeVar, Generic @@ -284,9 +284,9 @@ class B: pass class C: pass [out] main:8: error: Incompatible types in assignment (expression has type "C", variable has type "B") -main:9: error: Unsupported operand types for + (A[B, C] and "C") +main:9: error: Unsupported operand types for + ("A[B, C]" and "C") main:10: error: Incompatible types in assignment (expression has type "B", variable has type "C") -main:11: error: Invalid index type "B" for A[B, C]; expected type "C" +main:11: error: Invalid index type "B" for "A[B, C]"; expected type "C" [case testOperatorAssignmentWithIndexLvalue1] from typing import TypeVar, Generic @@ -309,7 +309,7 @@ class C: def __add__(self, o: 'C') -> 'C': pass [out] main:7: error: Unsupported operand types for + ("C" and "B") -main:8: error: Invalid index type "C" for A[C]; expected type "B" +main:8: error: Invalid index type "C" for "A[C]"; expected type "B" [case testOperatorAssignmentWithIndexLvalue2] from typing import TypeVar, Generic @@ -330,9 +330,9 @@ class B: pass class C: def __add__(self, o: 'C') -> 'C': pass [out] -main:7: error: Invalid index type "B" for A[C]; expected type "C" -main:8: error: Invalid index type "C" for A[C]; expected type "B" -main:9: error: Invalid index type "B" for A[C]; expected type "C" +main:7: error: Invalid index type "B" for "A[C]"; expected type "C" +main:8: error: Invalid index type "C" for "A[C]"; expected type "B" +main:9: error: Invalid index type "B" for "A[C]"; expected type "C" -- Nested generic types @@ -364,8 +364,8 @@ class B: class C: pass [out] -main:8: error: Incompatible types in assignment (expression has type A[B], variable has type A[C]) -main:9: error: Incompatible types in assignment (expression has type A[A[B]], variable has type A[A[C]]) +main:8: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]") +main:9: error: Incompatible types in assignment (expression has type "A[A[B]]", variable has type "A[A[C]]") -- Generic functions @@ -384,7 +384,7 @@ def f(s: S, t: T) -> p[T, A]: s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S") p_s_a = None # type: p[S, A] if s: - return p_s_a # E: Incompatible return value type (got p[S, A], expected p[T, A]) + return p_s_a # E: Incompatible return value type (got "p[S, A]", expected "p[T, A]") b = t # type: T c = s # type: S p_t_a = None # type: p[T, A] @@ -402,10 +402,10 @@ class A(Generic[T]): s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S") p_s_s = None # type: p[S, S] if s: - return p_s_s # E: Incompatible return value type (got p[S, S], expected p[S, T]) + return p_s_s # E: Incompatible return value type (got "p[S, S]", expected "p[S, T]") p_t_t = None # type: p[T, T] if t: - return p_t_t # E: Incompatible return value type (got p[T, T], expected p[S, T]) + return p_t_t # E: Incompatible return value type (got "p[T, T]", expected "p[S, T]") t = t s = s p_s_t = None # type: p[S, T] @@ -448,7 +448,7 @@ A[int, str, int]() # E: Type application has too many types (2 expected) a = None # type: A class A: pass a[A]() # E: Value of type "A" is not indexable -A[A]() # E: The type Type[A] is not generic and not indexable +A[A]() # E: The type "Type[A]" is not generic and not indexable [out] [case testTypeApplicationArgTypes] @@ -504,7 +504,7 @@ Alias[int]("a") # E: Argument 1 to "Node" has incompatible type "str"; expected [out] [case testTypeApplicationCrash] -type[int] # this was crashing, see #2302 (comment) # E: The type Type[type] is not generic and not indexable +type[int] # this was crashing, see #2302 (comment) # E: The type "Type[type]" is not generic and not indexable [out] @@ -564,7 +564,7 @@ def func(x: IntNode[T]) -> IntNode[T]: return x reveal_type(func) # E: Revealed type is 'def [T] (x: __main__.Node[builtins.int, T`-1]) -> __main__.Node[builtins.int, T`-1]' -func(1) # E: Argument 1 to "func" has incompatible type "int"; expected Node[int, ] +func(1) # E: Argument 1 to "func" has incompatible type "int"; expected "Node[int, ]" func(Node('x', 1)) # E: Argument 1 to "Node" has incompatible type "str"; expected "int" reveal_type(func(Node(1, 'x'))) # E: Revealed type is '__main__.Node[builtins.int, builtins.str*]' @@ -692,7 +692,7 @@ l.meth().append(1) reveal_type(l.meth()) # E: Revealed type is 'builtins.list*[builtins.int]' l.meth().append('x') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" -ListedNode[str]([]).x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type List[str]) +ListedNode[str]([]).x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "List[str]") [builtins fixtures/list.pyi] @@ -714,7 +714,7 @@ def f_bad(x: T) -> D[T]: return D(1) # Error, see out L[int]().append(Node((1, 1))) -L[int]().append(5) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected Node[Tuple[int, int]] +L[int]().append(5) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "Node[Tuple[int, int]]" x = D((1, 1)) # type: D[int] y = D(5) # type: D[int] # E: Argument 1 to "D" has incompatible type "int"; expected "Tuple[int, int]" @@ -778,7 +778,7 @@ if not isinstance(s, str): z = None # type: TNode # Same as TNode[Any] z.x -z.foo() # E: Item Node[int] of "Union[Any, Node[int]]" has no attribute "foo" +z.foo() # E: Item "Node[int]" of "Union[Any, Node[int]]" has no attribute "foo" [builtins fixtures/isinstance.pyi] @@ -847,7 +847,7 @@ def fun2(v: Vec[T], scale: T) -> Vec[T]: return v reveal_type(fun1([(1, 1)])) # E: Revealed type is 'builtins.int*' -fun1(1) # E: Argument 1 to "fun1" has incompatible type "int"; expected List[Tuple[int, int]] +fun1(1) # E: Argument 1 to "fun1" has incompatible type "int"; expected "List[Tuple[int, int]]" fun1([(1, 'x')]) # E: Cannot infer type argument 1 of "fun1" reveal_type(fun2([(1, 1)], 1)) # E: Revealed type is 'builtins.list[Tuple[builtins.int*, builtins.int*]]' @@ -868,7 +868,7 @@ n.y = 'x' # E: Incompatible types in assignment (expression has type "str", vari def f(x: Node[T, T]) -> TupledNode[T]: return Node(x.x, (x.x, x.x)) -f(1) # E: Argument 1 to "f" has incompatible type "int"; expected Node[, ] +f(1) # E: Argument 1 to "f" has incompatible type "int"; expected "Node[, ]" f(Node(1, 'x')) # E: Cannot infer type argument 1 of "f" reveal_type(Node('x', 'x')) # E: Revealed type is 'a.Node[builtins.str*, builtins.str*]' @@ -1221,7 +1221,7 @@ Z = TypeVar('Z') class OO: pass a = None # type: A[object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object] -f(a) # E: Argument 1 to "f" has incompatible type A[...]; expected "OO" +f(a) # E: Argument 1 to "f" has incompatible type "A[...]"; expected "OO" def f(a: OO) -> None: pass @@ -1232,7 +1232,7 @@ from typing import TypeVar, Generic S = TypeVar('S') T = TypeVar('T') a = None # type: A[object, B] -f(a) # E: Argument 1 to "f" has incompatible type A[object, B]; expected "B" +f(a) # E: Argument 1 to "f" has incompatible type "A[object, B]"; expected "B" def f(a: 'B') -> None: pass class A(Generic[S, T]): pass @@ -1243,7 +1243,7 @@ from typing import Callable, TypeVar, Generic S = TypeVar('S') T = TypeVar('T') a = None # type: A[object, Callable[[], None]] -f(a) # E: Argument 1 to "f" has incompatible type A[object, Callable[[], None]]; expected "B" +f(a) # E: Argument 1 to "f" has incompatible type "A[object, Callable[[], None]]"; expected "B" def f(a: 'B') -> None: pass class A(Generic[S, T]): pass @@ -1504,7 +1504,7 @@ T = TypeVar('T') class C(Generic[T]): def __init__(self) -> None: pass x = C # type: Callable[[], C[int]] -y = C # type: Callable[[], int] # E: Incompatible types in assignment (expression has type Type[C[Any]], variable has type Callable[[], int]) +y = C # type: Callable[[], int] # E: Incompatible types in assignment (expression has type "Type[C[Any]]", variable has type Callable[[], int]) -- Special cases diff --git a/test-data/unit/check-ignore.test b/test-data/unit/check-ignore.test index 3c81bd01d13a..5f2fd773a0c1 100644 --- a/test-data/unit/check-ignore.test +++ b/test-data/unit/check-ignore.test @@ -46,7 +46,7 @@ import b # type: ignore reveal_type(a.foo) # E: Revealed type is 'Any' reveal_type(b.foo) # E: Revealed type is 'builtins.int' a.bar() -b.bar() # E: Module has no attribute "bar" +b.bar() # E: "Module" has no attribute "bar" [file b.py] foo = 3 @@ -76,7 +76,7 @@ class B(A): import m m.x = object # type: ignore m.f() # type: ignore -m.y # E: Module has no attribute "y" +m.y # E: "Module" has no attribute "y" [file m.py] [builtins fixtures/module.pyi] @@ -194,7 +194,7 @@ foo(Child()) def bar(x: Base[str, str]) -> None: pass bar(Child()) [out] -main:19: error: Argument 1 to "bar" has incompatible type "Child"; expected Base[str, str] +main:19: error: Argument 1 to "bar" has incompatible type "Child"; expected "Base[str, str]" [case testTypeIgnoreLineNumberWithinFile] import m diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 23fafc24edf5..78da587098ec 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -325,7 +325,7 @@ const = 3 [stale mod3] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: Module has no attribute "mod4" +tmp/mod1.py:3: error: "Module" has no attribute "mod4" [case testIncrementalLongBrokenCascade] import mod1 @@ -360,7 +360,7 @@ const = 3 [stale mod6] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: Module has no attribute "mod7" +tmp/mod1.py:3: error: "Module" has no attribute "mod7" [case testIncrementalNestedBrokenCascade] import mod1 @@ -386,7 +386,7 @@ const = 3 [stale mod2.mod3] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: Module has no attribute "mod4" +tmp/mod1.py:3: error: "Module" has no attribute "mod4" [case testIncrementalNestedBrokenCascadeWithType1] import mod1, mod2.mod3.mod5 diff --git a/test-data/unit/check-inference-context.test b/test-data/unit/check-inference-context.test index 9896c1118a5a..4a8e5b1b8dc5 100644 --- a/test-data/unit/check-inference-context.test +++ b/test-data/unit/check-inference-context.test @@ -13,7 +13,7 @@ b = None # type: B ao = f() ab = f() -b = f() # E: Incompatible types in assignment (expression has type A[], variable has type "B") +b = f() # E: Incompatible types in assignment (expression has type "A[]", variable has type "B") def f() -> 'A[T]': pass @@ -29,7 +29,7 @@ b = None # type: B ao = A() ab = A() -b = A() # E: Incompatible types in assignment (expression has type A[], variable has type "B") +b = A() # E: Incompatible types in assignment (expression has type "A[]", variable has type "B") class A(Generic[T]): pass class B: pass @@ -74,10 +74,10 @@ def g() -> None: b = None # type: B x = f(o) - ab = x # E: Incompatible types in assignment (expression has type A[object], variable has type A[B]) + ab = x # E: Incompatible types in assignment (expression has type "A[object]", variable has type "A[B]") ao = x y = f(b) - ao = y # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) + ao = y # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") ab = y def f(a: T) -> 'A[T]': pass @@ -104,8 +104,8 @@ def g() -> None: ab = None # type: A[B] b = None # type: B x, y = f(b), f(b) - ao = x # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) - ao = y # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) + ao = x # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") + ao = y # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") ab = x ab = y @@ -122,8 +122,8 @@ def h() -> None: ab = None # type: A[B] b = None # type: B x, y = g(f(b)) - ao = x # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) - ao = y # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) + ao = x # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") + ao = y # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") ab = x ab = y @@ -161,8 +161,8 @@ class A(Generic[T]): pass class B: pass [builtins fixtures/tuple.pyi] [out] -main:8: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) -main:9: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) +main:8: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") +main:9: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") [case testInferenceWithTypeVariableTwiceInReturnTypeAndMultipleVariables] from typing import TypeVar, Tuple, Generic @@ -190,10 +190,10 @@ class A(Generic[T]): pass class B: pass [builtins fixtures/tuple.pyi] [out] -main:9: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) -main:10: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) -main:11: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) -main:12: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) +main:9: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") +main:10: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") +main:11: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") +main:12: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") -- Multiple tvar instances in arguments @@ -309,7 +309,7 @@ ab = None # type: A[B] ac = None # type: A[C] ab.g(f(o)) # E: Argument 1 to "f" has incompatible type "object"; expected "B" -ac = f(b).g(f(c)) # E: Incompatible types in assignment (expression has type A[B], variable has type A[C]) +ac = f(b).g(f(c)) # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]") ac = f(c).g(f(b)) # E: Argument 1 to "f" has incompatible type "B"; expected "C" ab = f(b).g(f(c)) @@ -334,7 +334,7 @@ aa = None # type: List[A] ao = None # type: List[object] a = None # type: A -a = [] # E: Incompatible types in assignment (expression has type List[], variable has type "A") +a = [] # E: Incompatible types in assignment (expression has type "List[]", variable has type "A") aa = [] ao = [] @@ -401,7 +401,7 @@ ab = None # type: List[B] b = None # type: B o = None # type: object -aao = [[o], ab] # E: List item 1 has incompatible type List[B] +aao = [[o], ab] # E: List item 1 has incompatible type "List[B]" aab = [[], [o]] # E: List item 0 has incompatible type "object" aao = [[None], [b], [], [o]] @@ -462,7 +462,7 @@ d = {A() : a_c, [case testInitializationWithInferredGenericType] from typing import TypeVar, Generic T = TypeVar('T') -c = f(A()) # type: C[A] # E: Argument 1 to "f" has incompatible type "A"; expected C[A] +c = f(A()) # type: C[A] # E: Argument 1 to "f" has incompatible type "A"; expected "C[A]" def f(x: T) -> T: pass class C(Generic[T]): pass @@ -503,7 +503,7 @@ from abc import abstractmethod, ABCMeta t = TypeVar('t') x = A() # type: I[int] a_object = A() # type: A[object] -y = a_object # type: I[int] # E: Incompatible types in assignment (expression has type A[object], variable has type I[int]) +y = a_object # type: I[int] # E: Incompatible types in assignment (expression has type "A[object]", variable has type "I[int]") class I(Generic[t]): @abstractmethod @@ -663,7 +663,7 @@ class B: pass m = map(g, [A()]) b = m # type: List[B] -a = m # type: List[A] # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) +a = m # type: List[A] # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") [builtins fixtures/list.pyi] @@ -677,8 +677,8 @@ a, b, c = None, None, None # type: (List[A], List[B], List[C]) a = a or [] a = [] or a b = b or [C()] -a = a or b # E: Incompatible types in assignment (expression has type "Union[List[A], List[B]]", variable has type List[A]) -b = b or c # E: Incompatible types in assignment (expression has type "Union[List[B], List[C]]", variable has type List[B]) +a = a or b # E: Incompatible types in assignment (expression has type "Union[List[A], List[B]]", variable has type "List[A]") +b = b or c # E: Incompatible types in assignment (expression has type "Union[List[B], List[C]]", variable has type "List[B]") class A: pass class B: pass @@ -732,7 +732,7 @@ from typing import List i = None # type: List[int] s = None # type: List[str] i = i = [] -i = s = [] # E: Incompatible types in assignment (expression has type List[str], variable has type List[int]) +i = s = [] # E: Incompatible types in assignment (expression has type "List[str]", variable has type "List[int]") [builtins fixtures/list.pyi] [case testContextForAttributeDeclaredInInit] diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 42cd312c0531..76931ad3b254 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -69,7 +69,7 @@ class B: pass import typing def f() -> None: a = g() - None(a) # E: None not callable + None(a) # E: "None" not callable a.x() def g(): pass @@ -81,7 +81,7 @@ g = None # type: Any def f(a: Any) -> None: b = g - None(b) # E: None not callable + None(b) # E: "None" not callable a.x() [out] @@ -126,7 +126,7 @@ a_s = None # type: A[str] def f() -> None: a_int = A() # type: A[int] a = a_int - a = a_s # E: Incompatible types in assignment (expression has type A[str], variable has type A[int]) + a = a_s # E: Incompatible types in assignment (expression has type "A[str]", variable has type "A[int]") a = a_i [builtins fixtures/tuple.pyi] [out] @@ -480,11 +480,11 @@ ao = None # type: A[object] ab = None # type: A[B] ac = None # type: A[C] -ab = f(ao) # E: Argument 1 to "f" has incompatible type A[object]; expected A[B] -ao = f(ab) # E: Argument 1 to "f" has incompatible type A[B]; expected A[object] -ab = f(ac) # E: Argument 1 to "f" has incompatible type A[C]; expected A[B] -ab = g(ao) # E: Argument 1 to "g" has incompatible type A[object]; expected A[B] -ao = g(ab) # E: Argument 1 to "g" has incompatible type A[B]; expected A[object] +ab = f(ao) # E: Argument 1 to "f" has incompatible type "A[object]"; expected "A[B]" +ao = f(ab) # E: Argument 1 to "f" has incompatible type "A[B]"; expected "A[object]" +ab = f(ac) # E: Argument 1 to "f" has incompatible type "A[C]"; expected "A[B]" +ab = g(ao) # E: Argument 1 to "g" has incompatible type "A[object]"; expected "A[B]" +ao = g(ab) # E: Argument 1 to "g" has incompatible type "A[B]"; expected "A[object]" ab = f(ab) ac = f(ac) @@ -648,7 +648,7 @@ def mymap(f: Callable[[t], s], a: List[t]) -> List[s]: pass l = mymap(f, [b]) l = [A()] lb = [b] -l = lb # E: Incompatible types in assignment (expression has type List[bool], variable has type List[A]) +l = lb # E: Incompatible types in assignment (expression has type "List[bool]", variable has type "List[A]") [builtins fixtures/for.pyi] [case testGenericFunctionWithTypeTypeAsCallable] @@ -676,7 +676,7 @@ f(1, 1)() # E: "int" not callable def g(x: Union[T, List[T]]) -> List[T]: pass def h(x: List[str]) -> None: pass -g('a')() # E: List[str] not callable +g('a')() # E: "List[str]" not callable # The next line is a case where there are multiple ways to satisfy a constraint # involving a Union. Either T = List[str] or T = str would turn out to be valid, @@ -684,7 +684,7 @@ g('a')() # E: List[str] not callable # to backtrack later) and defaults to T = . The result is an # awkward error message. Either a better error message, or simply accepting the # call, would be preferable here. -g(['a']) # E: Argument 1 to "g" has incompatible type List[str]; expected List[] +g(['a']) # E: Argument 1 to "g" has incompatible type "List[str]"; expected "List[]" h(g(['a'])) @@ -693,7 +693,7 @@ a = [1] b = ['b'] i(a, a, b) i(b, a, b) -i(a, b, b) # E: Argument 1 to "i" has incompatible type List[int]; expected List[str] +i(a, b, b) # E: Argument 1 to "i" has incompatible type "List[int]"; expected "List[str]" [builtins fixtures/list.pyi] [case testCallableListJoinInference] @@ -778,7 +778,7 @@ from typing import TypeVar, Union, List T = TypeVar('T') def f() -> List[T]: pass d1 = f() # type: Union[List[int], str] -d2 = f() # type: Union[int, str] # E: Incompatible types in assignment (expression has type List[], variable has type "Union[int, str]") +d2 = f() # type: Union[int, str] # E: Incompatible types in assignment (expression has type "List[]", variable has type "Union[int, str]") def g(x: T) -> List[T]: pass d3 = g(1) # type: Union[List[int], List[str]] [builtins fixtures/list.pyi] @@ -840,7 +840,7 @@ def d_aa() -> Dict[A, A]: return {} a, b = None, None # type: (A, B) d = {a:b} d = d_ab() -d = d_aa() # E: Incompatible types in assignment (expression has type Dict[A, A], variable has type Dict[A, B]) +d = d_aa() # E: Incompatible types in assignment (expression has type "Dict[A, A]", variable has type "Dict[A, B]") [builtins fixtures/dict.pyi] [case testSetLiteral] @@ -851,7 +851,7 @@ def s_s() -> Set[str]: return set() s = {a} s = {x} s = s_i() -s = s_s() # E: Incompatible types in assignment (expression has type Set[str], variable has type Set[int]) +s = s_s() # E: Incompatible types in assignment (expression has type "Set[str]", variable has type "Set[int]") [builtins fixtures/set.pyi] [case testSetWithStarExpr] @@ -1154,7 +1154,7 @@ a = None # type: List[A] o = None # type: List[object] a2 = a or [] a = a2 -a2 = o # E: Incompatible types in assignment (expression has type List[object], variable has type List[A]) +a2 = o # E: Incompatible types in assignment (expression has type "List[object]", variable has type "List[A]") class A: pass [builtins fixtures/list.pyi] @@ -1194,7 +1194,7 @@ x2 = [B(), A()] x3 = [B(), B()] a = x1 a = x2 -a = x3 # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) +a = x3 # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") [builtins fixtures/list.pyi] [case testListWithDucktypeCompatibilityAndTransitivity] @@ -1210,7 +1210,7 @@ x2 = [C(), A()] x3 = [B(), C()] a = x1 a = x2 -a = x3 # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) +a = x3 # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") [builtins fixtures/list.pyi] @@ -1256,8 +1256,8 @@ a() a, b = [], [] a.append(1) b.append('') -a() # E: List[int] not callable -b() # E: List[str] not callable +a() # E: "List[int]" not callable +b() # E: "List[str]" not callable [builtins fixtures/list.pyi] [out] @@ -1371,14 +1371,14 @@ a.add('') # E: Argument 1 to "add" of "set" has incompatible type "str"; expect [case testInferDictInitializedToEmpty] a = {} a[1] = '' -a() # E: Dict[int, str] not callable +a() # E: "Dict[int, str]" not callable [builtins fixtures/dict.pyi] [out] [case testInferDictInitializedToEmptyUsingUpdate] a = {} a.update({'': 42}) -a() # E: Dict[str, int] not callable +a() # E: "Dict[str, int]" not callable [builtins fixtures/dict.pyi] [out] @@ -1447,7 +1447,7 @@ def f() -> None: import typing def f() -> None: a = None - a.x() # E: None has no attribute "x" + a.x() # E: "None" has no attribute "x" [out] [case testGvarPartiallyInitializedToNone] @@ -1504,7 +1504,7 @@ x = None def f() -> None: x = None x = 1 -x() # E: None not callable +x() # E: "None" not callable [case testAttributePartiallyInitializedToNone] class A: @@ -1523,8 +1523,8 @@ class A: self.x = 1 self.x() [out] -main:6: error: Incompatible types in assignment (expression has type "int", variable has type None) -main:7: error: None not callable +main:6: error: Incompatible types in assignment (expression has type "int", variable has type "None") +main:7: error: "None" not callable [case testGlobalInitializedToNoneSetFromFunction] a = None @@ -1553,7 +1553,7 @@ class A: pass [builtins fixtures/for.pyi] [out] -main:5: error: None has no attribute "__iter__" +main:5: error: "None" has no attribute "__iter__" [case testPartialTypeErrorSpecialCase2] # This used to crash. @@ -1574,7 +1574,7 @@ class A: pass [builtins fixtures/for.pyi] [out] -main:4: error: None has no attribute "__iter__" +main:4: error: "None" has no attribute "__iter__" -- Multipass @@ -1680,7 +1680,7 @@ def g(d: Dict[str, int]) -> None: pass def f() -> None: x = {} x[1] = y - g(x) # E: Argument 1 to "g" has incompatible type Dict[int, str]; expected Dict[str, int] + g(x) # E: Argument 1 to "g" has incompatible type "Dict[int, str]"; expected "Dict[str, int]" x[1] = 1 # E: Incompatible types in assignment (expression has type "int", target has type "str") x[1] = '' y = '' @@ -1694,7 +1694,7 @@ def f() -> None: x = {} y x[1] = 1 - g(x) # E: Argument 1 to "g" has incompatible type Dict[int, int]; expected Dict[str, int] + g(x) # E: Argument 1 to "g" has incompatible type "Dict[int, int]"; expected "Dict[str, int]" y = '' [builtins fixtures/dict.pyi] [out] @@ -1713,7 +1713,7 @@ def f() -> None: y = o x = [] x.append(y) - x() # E: List[int] not callable + x() # E: "List[int]" not callable o = 1 [builtins fixtures/list.pyi] [out] @@ -1723,7 +1723,7 @@ def f() -> None: y = o x = {} x[''] = y - x() # E: Dict[str, int] not callable + x() # E: "Dict[str, int]" not callable o = 1 [builtins fixtures/dict.pyi] [out] @@ -1825,20 +1825,20 @@ a2.foo2() [case testUnificationEmptyListLeft] def f(): pass a = [] if f() else [0] -a() # E: List[int] not callable +a() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testUnificationEmptyListRight] def f(): pass a = [0] if f() else [] -a() # E: List[int] not callable +a() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testUnificationEmptyListLeftInContext] from typing import List def f(): pass a = [] if f() else [0] # type: List[int] -a() # E: List[int] not callable +a() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testUnificationEmptyListRightInContext] @@ -1846,37 +1846,37 @@ a() # E: List[int] not callable from typing import List def f(): pass a = [0] if f() else [] # type: List[int] -a() # E: List[int] not callable +a() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testUnificationEmptySetLeft] def f(): pass a = set() if f() else {0} -a() # E: Set[int] not callable +a() # E: "Set[int]" not callable [builtins fixtures/set.pyi] [case testUnificationEmptyDictLeft] def f(): pass a = {} if f() else {0: 0} -a() # E: Dict[int, int] not callable +a() # E: "Dict[int, int]" not callable [builtins fixtures/dict.pyi] [case testUnificationEmptyDictRight] def f(): pass a = {0: 0} if f() else {} -a() # E: Dict[int, int] not callable +a() # E: "Dict[int, int]" not callable [builtins fixtures/dict.pyi] [case testUnificationDictWithEmptyListLeft] def f(): pass a = {0: []} if f() else {0: [0]} -a() # E: Dict[int, List[int]] not callable +a() # E: "Dict[int, List[int]]" not callable [builtins fixtures/dict.pyi] [case testUnificationDictWithEmptyListRight] def f(): pass a = {0: [0]} if f() else {0: []} -a() # E: Dict[int, List[int]] not callable +a() # E: "Dict[int, List[int]]" not callable [builtins fixtures/dict.pyi] [case testMisguidedSetItem] diff --git a/test-data/unit/check-isinstance.test b/test-data/unit/check-isinstance.test index 825a5557fc63..d9a27649e4af 100644 --- a/test-data/unit/check-isinstance.test +++ b/test-data/unit/check-isinstance.test @@ -679,7 +679,7 @@ while bool(): x + 'a' break x + [1] - x + 'a' # E: Unsupported operand types for + (List[int] and "str") + x + 'a' # E: Unsupported operand types for + ("List[int]" and "str") x + [1] # E: Unsupported operand types for + (likely involving Union) [builtins fixtures/isinstancelist.pyi] @@ -1486,7 +1486,7 @@ def test_issubclass(cls: Type[Goblin]) -> None: else: reveal_type(cls) # E: Revealed type is 'Type[__main__.Goblin]' cls.level - cls.job # E: Type[Goblin] has no attribute "job" + cls.job # E: "Type[Goblin]" has no attribute "job" g = cls() g.level = 15 g.job # E: "Goblin" has no attribute "job" @@ -1511,7 +1511,7 @@ def test_issubclass(cls: Type[Mob]) -> None: if issubclass(cls, Goblin): reveal_type(cls) # E: Revealed type is 'Type[__main__.Goblin]' cls.level - cls.job # E: Type[Goblin] has no attribute "job" + cls.job # E: "Type[Goblin]" has no attribute "job" g = cls() g.level = 15 g.job # E: "Goblin" has no attribute "job" @@ -1525,8 +1525,8 @@ def test_issubclass(cls: Type[Mob]) -> None: g.job = 'Warrior' # E: Cannot assign to class variable "job" via instance else: reveal_type(cls) # E: Revealed type is 'Type[__main__.Mob]' - cls.job # E: Type[Mob] has no attribute "job" - cls.level # E: Type[Mob] has no attribute "level" + cls.job # E: "Type[Mob]" has no attribute "job" + cls.level # E: "Type[Mob]" has no attribute "level" m = cls() m.level = 15 # E: "Mob" has no attribute "level" m.job # E: "Mob" has no attribute "job" @@ -1570,7 +1570,7 @@ def test_issubclass(cls: Type[Mob]) -> None: if issubclass(cls, (Goblin, GoblinAmbusher)): reveal_type(cls) # E: Revealed type is 'Type[__main__.Goblin]' cls.level - cls.job # E: Type[Goblin] has no attribute "job" + cls.job # E: "Type[Goblin]" has no attribute "job" g = cls() g.level = 15 g.job # E: "Goblin" has no attribute "job" @@ -1584,8 +1584,8 @@ def test_issubclass(cls: Type[Mob]) -> None: ga.job = "Warrior" # E: Cannot assign to class variable "job" via instance else: reveal_type(cls) # E: Revealed type is 'Type[__main__.Mob]' - cls.job # E: Type[Mob] has no attribute "job" - cls.level # E: Type[Mob] has no attribute "level" + cls.job # E: "Type[Mob]" has no attribute "job" + cls.level # E: "Type[Mob]" has no attribute "level" m = cls() m.level = 15 # E: "Mob" has no attribute "level" m.job # E: "Mob" has no attribute "job" diff --git a/test-data/unit/check-kwargs.test b/test-data/unit/check-kwargs.test index de229c76e631..e8182b34ae8f 100644 --- a/test-data/unit/check-kwargs.test +++ b/test-data/unit/check-kwargs.test @@ -4,7 +4,7 @@ [case testTypeErrorInKeywordArgument] import typing def f(o: object) -> None: pass -f(o=None()) # E: None not callable +f(o=None()) # E: "None" not callable [case testSimpleKeywordArgument] import typing @@ -89,8 +89,8 @@ class A: pass [case testKeywordArgumentsWithDynamicallyTypedCallable] from typing import Any f = None # type: Any -f(x=f(), z=None()) # E: None not callable -f(f, zz=None()) # E: None not callable +f(x=f(), z=None()) # E: "None" not callable +f(f, zz=None()) # E: "None" not callable f(x=None) [case testKeywordArgumentWithFunctionObject] @@ -216,8 +216,8 @@ class A: pass from typing import Dict, Any def f( **kwargs: 'A') -> None: d1 = kwargs # type: Dict[str, A] - d2 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type Dict[str, A], variable has type Dict[A, Any]) - d3 = kwargs # type: Dict[Any, str] # E: Incompatible types in assignment (expression has type Dict[str, A], variable has type Dict[Any, str]) + d2 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type "Dict[str, A]", variable has type "Dict[A, Any]") + d3 = kwargs # type: Dict[Any, str] # E: Incompatible types in assignment (expression has type "Dict[str, A]", variable has type "Dict[Any, str]") class A: pass [builtins fixtures/dict.pyi] [out] @@ -227,7 +227,7 @@ from typing import Dict, Any def f(**kwargs) -> None: d1 = kwargs # type: Dict[str, A] d2 = kwargs # type: Dict[str, str] - d3 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type Dict[str, Any], variable has type Dict[A, Any]) + d3 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type "Dict[str, Any]", variable has type "Dict[A, Any]") class A: pass [builtins fixtures/dict.pyi] [out] @@ -252,8 +252,8 @@ d = None # type: Dict[str, A] f(**d) f(x=A(), **d) d2 = None # type: Dict[str, B] -f(**d2) # E: Argument 1 to "f" has incompatible type **Dict[str, B]; expected "A" -f(x=A(), **d2) # E: Argument 2 to "f" has incompatible type **Dict[str, B]; expected "A" +f(**d2) # E: Argument 1 to "f" has incompatible type **"Dict[str, B]"; expected "A" +f(x=A(), **d2) # E: Argument 2 to "f" has incompatible type **"Dict[str, B]"; expected "A" class A: pass class B: pass [builtins fixtures/dict.pyi] @@ -295,7 +295,7 @@ def f(a: 'A', b: 'B') -> None: pass d = None # type: Dict[str, Any] f(**d) d2 = None # type: Dict[str, A] -f(**d2) # E: Argument 1 to "f" has incompatible type **Dict[str, A]; expected "B" +f(**d2) # E: Argument 1 to "f" has incompatible type **"Dict[str, A]"; expected "B" class A: pass class B: pass [builtins fixtures/dict.pyi] @@ -344,12 +344,12 @@ s = ('',) f(*s) # E: Argument 1 to "f" has incompatible type *"Tuple[str]"; expected "int" a = {'': 0} -f(a) # E: Argument 1 to "f" has incompatible type Dict[str, int]; expected "int" +f(a) # E: Argument 1 to "f" has incompatible type "Dict[str, int]"; expected "int" f(**a) # okay b = {'': ''} -f(b) # E: Argument 1 to "f" has incompatible type Dict[str, str]; expected "int" -f(**b) # E: Argument 1 to "f" has incompatible type **Dict[str, str]; expected "int" +f(b) # E: Argument 1 to "f" has incompatible type "Dict[str, str]"; expected "int" +f(**b) # E: Argument 1 to "f" has incompatible type **"Dict[str, str]"; expected "int" c = {0: 0} f(**c) # E: Keywords must be strings diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test index 66050601d26f..10c6a22680d6 100644 --- a/test-data/unit/check-modules.test +++ b/test-data/unit/check-modules.test @@ -155,16 +155,16 @@ import m import typing class A: pass -m() # E: Module not callable -a = m # type: A # E: Incompatible types in assignment (expression has type Module, variable has type "A") -m + None # E: Unsupported left operand type for + (Module) +m() # E: "Module" not callable +a = m # type: A # E: Incompatible types in assignment (expression has type "Module", variable has type "A") +m + None # E: Unsupported left operand type for + ("Module") [file m.py] [builtins fixtures/module.pyi] [case testNameDefinedInDifferentModule] import m, n import typing -m.x # E: Module has no attribute "x" +m.x # E: "Module" has no attribute "x" [file m.py] y = object() [file n.py] @@ -201,7 +201,7 @@ None + '' [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testTypeCheckWithUnknownModule2] import m, nonexistent @@ -213,7 +213,7 @@ x = 1 [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") main:4: error: Incompatible types in assignment (expression has type "str", variable has type "int") [case testTypeCheckWithUnknownModule3] @@ -226,7 +226,7 @@ x = 1 [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") main:4: error: Incompatible types in assignment (expression has type "str", variable has type "int") [case testTypeCheckWithUnknownModule4] @@ -236,7 +236,7 @@ None + '' main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) main:1: error: Cannot find module named 'another' -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testTypeCheckWithUnknownModule5] import nonexistent as x @@ -244,7 +244,7 @@ None + '' [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testTypeCheckWithUnknownModuleUsingFromImport] from nonexistent import x @@ -252,7 +252,7 @@ None + '' [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testTypeCheckWithUnknownModuleUsingImportStar] from nonexistent import * @@ -260,7 +260,7 @@ None + '' [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testAccessingUnknownModule] import xyz @@ -330,7 +330,7 @@ import nonexistent [out] tmp/x.py:1: error: Cannot find module named 'nonexistent' tmp/x.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:3: error: Module has no attribute "z" +main:3: error: "Module" has no attribute "z" [case testUnknownModuleImportedWithinFunction] def f(): @@ -411,14 +411,14 @@ import typing __all__ = [1, 2, 3] [builtins fixtures/module_all.pyi] [out] -main:2: error: Type of __all__ must be Sequence[str], not List[int] +main:2: error: Type of __all__ must be "Sequence[str]", not "List[int]" [case testAllMustBeSequenceStr_python2] import typing __all__ = [1, 2, 3] [builtins_py2 fixtures/module_all_python2.pyi] [out] -main:2: error: Type of __all__ must be Sequence[unicode], not List[int] +main:2: error: Type of __all__ must be "Sequence[unicode]", not "List[int]" [case testAllUnicodeSequenceOK_python2] import typing @@ -648,7 +648,7 @@ def f(x: str) -> None: pass if object(): import m else: - m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type Module) + m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Module") [file m.py] [builtins fixtures/module.pyi] [out] @@ -673,7 +673,7 @@ def f(x: str) -> None: pass None + 1 [file m/a.py] [out] -tmp/m/__init__.py:1: error: Unsupported left operand type for + (None) +tmp/m/__init__.py:1: error: Unsupported left operand type for + ("None") [case testTypeCheckNamedModule2] # cmd: mypy -m m.a @@ -681,7 +681,7 @@ tmp/m/__init__.py:1: error: Unsupported left operand type for + (None) [file m/a.py] None + 1 [out] -tmp/m/a.py:1: error: Unsupported left operand type for + (None) +tmp/m/a.py:1: error: Unsupported left operand type for + ("None") [case testTypeCheckNamedModule3] # cmd: mypy -m m @@ -689,7 +689,7 @@ tmp/m/a.py:1: error: Unsupported left operand type for + (None) None + 1 [file m/a.py] [out] -tmp/m/__init__.py:1: error: Unsupported left operand type for + (None) +tmp/m/__init__.py:1: error: Unsupported left operand type for + ("None") [case testTypeCheckNamedModule4] # cmd: mypy -m m @@ -704,7 +704,7 @@ None + '' # Not analyzed. [file m.py] None + 1 [out] -tmp/m.py:1: error: Unsupported left operand type for + (None) +tmp/m.py:1: error: Unsupported left operand type for + ("None") [case testTypeCheckNamedModuleWithImportCycle] # cmd: mypy -m m.a @@ -752,7 +752,7 @@ value = 3.2 [case testSubmoduleImportFromDoesNotAddParents] from a import b reveal_type(b.value) # E: Revealed type is 'builtins.str' -b.c.value # E: Module has no attribute "c" +b.c.value # E: "Module" has no attribute "c" a.value # E: Name 'a' is not defined [file a/__init__.py] @@ -853,7 +853,7 @@ bar = parent.unrelated.ShouldNotLoad() [builtins fixtures/module.pyi] [out] tmp/parent/child.py:8: error: Revealed type is 'parent.common.SomeClass' -tmp/parent/child.py:9: error: Module has no attribute "unrelated" +tmp/parent/child.py:9: error: "Module" has no attribute "unrelated" [case testSubmoduleMixingImportFromAndImport2] import parent.child @@ -915,7 +915,7 @@ class z: pass [out] main:2: error: Incompatible import of "x" (imported name has type "str", local name has type "int") main:2: error: Incompatible import of "y" (imported name has type Callable[[], str], local name has type Callable[[], int]) -main:2: error: Incompatible import of "z" (imported name has type Type[b.z], local name has type Type[a.z]) +main:2: error: Incompatible import of "z" (imported name has type "Type[b.z]", local name has type "Type[a.z]") -- Misc diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 81aa3f6957e6..9f803bbcc558 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -221,7 +221,7 @@ a = (1,) # E: Incompatible types in assignment (expression has type "Tuple[int] [case testNamedTupleMissingClassAttribute] import collections MyNamedTuple = collections.namedtuple('MyNamedTuple', ['spam', 'eggs']) -MyNamedTuple.x # E: Type[MyNamedTuple] has no attribute "x" +MyNamedTuple.x # E: "Type[MyNamedTuple]" has no attribute "x" [case testNamedTupleEmptyItems] @@ -286,7 +286,7 @@ from typing import NamedTuple X = NamedTuple('X', [('x', int), ('y', str)]) reveal_type(X._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' -X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any] +X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected "Iterable[Any]" -- # FIX: not a proper class method -- x = None # type: X @@ -420,7 +420,7 @@ class C: A = NamedTuple('A', [('x', int)]) def g(self): A = NamedTuple('A', [('y', int)]) -C.A # E: Type[C] has no attribute "A" +C.A # E: "Type[C]" has no attribute "A" [case testNamedTupleInFunction] from typing import NamedTuple diff --git a/test-data/unit/check-newsyntax.test b/test-data/unit/check-newsyntax.test index 9f3f87853e63..f17b324cbca2 100644 --- a/test-data/unit/check-newsyntax.test +++ b/test-data/unit/check-newsyntax.test @@ -29,7 +29,7 @@ from typing import Dict, Any d: Dict[int, str] = {} d[42] = 'ab' d[42] = 42 # E: Incompatible types in assignment (expression has type "int", target has type "str") -d['ab'] = 'ab' # E: Invalid index type "str" for Dict[int, str]; expected type "int" +d['ab'] = 'ab' # E: Invalid index type "str" for "Dict[int, str]"; expected type "int" [builtins fixtures/dict.pyi] [out] @@ -61,29 +61,29 @@ TstInstance().a = 'ab' [case testNewSyntaxWithClassVars] # flags: --strict-optional --python-version 3.6 class CCC: - a: str = None # E: Incompatible types in assignment (expression has type None, variable has type "str") + a: str = None # E: Incompatible types in assignment (expression has type "None", variable has type "str") [out] [case testNewSyntaxWithStrictOptional] # flags: --strict-optional --python-version 3.6 strict: int -strict = None # E: Incompatible types in assignment (expression has type None, variable has type "int") -strict2: int = None # E: Incompatible types in assignment (expression has type None, variable has type "int") +strict = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") +strict2: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [out] [case testNewSyntaxWithStrictOptionalFunctions] # flags: --strict-optional --python-version 3.6 def f() -> None: x: int - x = None # E: Incompatible types in assignment (expression has type None, variable has type "int") + x = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [out] [case testNewSyntaxWithStrictOptionalClasses] # flags: --strict-optional --python-version 3.6 class C: def meth(self) -> None: - x: int = None # E: Incompatible types in assignment (expression has type None, variable has type "int") - self.x: int = None # E: Incompatible types in assignment (expression has type None, variable has type "int") + x: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") + self.x: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [out] [case testNewSyntaxSpecialAssign] diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index 6ae6df914376..ed9226116c00 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -2,11 +2,11 @@ [case testImplicitNoneType] x = None -x() # E: None not callable +x() # E: "None" not callable [case testExplicitNoneType] x = None # type: None -x() # E: None not callable +x() # E: "None" not callable [case testNoneMemberOfOptional] from typing import Optional @@ -19,12 +19,12 @@ x = 0 # type: Optional[int] [case testNoneNotMemberOfType] x = None # type: int [out] -main:1: error: Incompatible types in assignment (expression has type None, variable has type "int") +main:1: error: Incompatible types in assignment (expression has type "None", variable has type "int") [case testTypeNotMemberOfNone] x = 0 # type: None [out] -main:1: error: Incompatible types in assignment (expression has type "int", variable has type None) +main:1: error: Incompatible types in assignment (expression has type "int", variable has type "None") [case testOptionalNotMemberOfType] from typing import Optional @@ -182,13 +182,13 @@ reveal_type(x) # E: Revealed type is 'Union[builtins.int, builtins.None]' [case testInferOptionalListType] x = [None] -x.append(1) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected None +x.append(1) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "None" [builtins fixtures/list.pyi] [case testInferNonOptionalListType] x = [] x.append(1) -x() # E: List[int] not callable +x() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testInferOptionalDictKeyValueTypes] @@ -196,13 +196,13 @@ x = {None: None} x["bar"] = 1 [builtins fixtures/dict.pyi] [out] -main:2: error: Invalid index type "str" for Dict[None, None]; expected type None -main:2: error: Incompatible types in assignment (expression has type "int", target has type None) +main:2: error: Invalid index type "str" for "Dict[None, None]"; expected type "None" +main:2: error: Incompatible types in assignment (expression has type "int", target has type "None") [case testInferNonOptionalDictType] x = {} x["bar"] = 1 -x() # E: Dict[str, int] not callable +x() # E: "Dict[str, int]" not callable [builtins fixtures/dict.pyi] [case testNoneClassVariable] @@ -217,7 +217,7 @@ from typing import Optional class C: x = None # type: int def __init__(self) -> None: - self.x = None # E: Incompatible types in assignment (expression has type None, variable has type "int") + self.x = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [out] [case testMultipleAssignmentNoneClassVariableInInit] @@ -225,8 +225,8 @@ from typing import Optional class C: x, y = None, None # type: int, str def __init__(self) -> None: - self.x = None # E: Incompatible types in assignment (expression has type None, variable has type "int") - self.y = None # E: Incompatible types in assignment (expression has type None, variable has type "str") + self.x = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") + self.y = None # E: Incompatible types in assignment (expression has type "None", variable has type "str") [out] [case testOverloadWithNone] diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index 69289fae18c1..4f359a3efefb 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -447,7 +447,7 @@ from foo import * from typing import overload t, a = None, None # type: (type, A) -a = A # E: Incompatible types in assignment (expression has type Type[A], variable has type "A") +a = A # E: Incompatible types in assignment (expression has type "Type[A]", variable has type "A") t = A class A: @@ -610,7 +610,7 @@ n = 1 m = 1 n = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int") m = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int") -f(list_object) # E: Argument 1 to "f" has incompatible type List[object]; expected List[int] +f(list_object) # E: Argument 1 to "f" has incompatible type "List[object]"; expected "List[int]" [builtins fixtures/list.pyi] [case testOverlappingOverloadSignatures] @@ -901,7 +901,7 @@ def f(x: int, y: List[int] = None) -> int: pass def f(x: int, y: List[str] = None) -> int: pass f(y=[1], x=0)() # E: "int" not callable f(y=[''], x=0)() # E: "int" not callable -a = f(y=[['']], x=0) # E: List item 0 has incompatible type List[str] +a = f(y=[['']], x=0) # E: List item 0 has incompatible type "List[str]" a() # E: "int" not callable [builtins fixtures/list.pyi] @@ -1117,14 +1117,14 @@ def f(x: int, y: Tuple[str, ...]) -> None: pass @overload def f(x: int, y: str) -> None: pass f(1, ('2', '3')) -f(1, (2, '3')) # E: Argument 2 to "f" has incompatible type "Tuple[int, str]"; expected Tuple[str, ...] +f(1, (2, '3')) # E: Argument 2 to "f" has incompatible type "Tuple[int, str]"; expected "Tuple[str, ...]" f(1, ('2',)) f(1, '2') -f(1, (2, 3)) # E: Argument 2 to "f" has incompatible type "Tuple[int, int]"; expected Tuple[str, ...] +f(1, (2, 3)) # E: Argument 2 to "f" has incompatible type "Tuple[int, int]"; expected "Tuple[str, ...]" x = ('2', '3') # type: Tuple[str, ...] f(1, x) y = (2, 3) # type: Tuple[int, ...] -f(1, y) # E: Argument 2 to "f" has incompatible type Tuple[int, ...]; expected Tuple[str, ...] +f(1, y) # E: Argument 2 to "f" has incompatible type "Tuple[int, ...]"; expected "Tuple[str, ...]" [builtins fixtures/tuple.pyi] [case testCallableSpecificOverload] diff --git a/test-data/unit/check-python2.test b/test-data/unit/check-python2.test index b3b899b21560..24022f4b15d8 100644 --- a/test-data/unit/check-python2.test +++ b/test-data/unit/check-python2.test @@ -34,7 +34,7 @@ class A: print >>A(), '' print >>None, '' print >>1, '' # E: "int" has no attribute "write" -print >>(None + ''), None # E: Unsupported left operand type for + (None) +print >>(None + ''), None # E: Unsupported left operand type for + ("None") [case testDivision] class A: @@ -291,7 +291,7 @@ class A(object): __metaclass__ = M y = 0 reveal_type(A.y) # E: Revealed type is 'builtins.int' -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAnyAsBaseOfMetaclass] from typing import Any, Type diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test index 8c1f85b1d743..a8071d68b1e6 100644 --- a/test-data/unit/check-statements.test +++ b/test-data/unit/check-statements.test @@ -377,7 +377,7 @@ import typing assert None + None # Fail assert None [out] -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") -- Exception handling @@ -599,9 +599,9 @@ main:7: error: Incompatible redefinition (redefinition with type Callable[[], st [case testExceptWithoutType] import typing try: - -None # E: Unsupported operand type for unary - (None) + -None # E: Unsupported operand type for unary - ("None") except: - ~None # E: Unsupported operand type for ~ (None) + ~None # E: Unsupported operand type for ~ ("None") [builtins fixtures/exception.pyi] [case testRaiseWithoutArgument] @@ -1189,7 +1189,7 @@ def g() -> Iterator[List[int]]: yield [2, 3, 4] def f() -> Iterator[List[int]]: yield from g() - yield from [1, 2, 3] # E: Incompatible types in "yield from" (actual type "int", expected type List[int]) + yield from [1, 2, 3] # E: Incompatible types in "yield from" (actual type "int", expected type "List[int]") [builtins fixtures/for.pyi] [out] @@ -1429,7 +1429,7 @@ y = 1 from typing import List bs, cs = None, None # type: List[A], List[B] *bs, b = bs -*bs, c = cs # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) +*bs, c = cs # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") *ns, c = cs nc = cs diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test index 08345706f0d9..ded930ae6d7e 100644 --- a/test-data/unit/check-tuples.test +++ b/test-data/unit/check-tuples.test @@ -91,7 +91,7 @@ from typing import Tuple t1 = None # type: Tuple[A, A] t2 = None # type: tuple -t1 = t2 # E: Incompatible types in assignment (expression has type Tuple[Any, ...], variable has type "Tuple[A, A]") +t1 = t2 # E: Incompatible types in assignment (expression has type "Tuple[Any, ...]", variable has type "Tuple[A, A]") t2 = t1 class A: pass @@ -388,7 +388,7 @@ aa, bb, *cc = t # E: Need type annotation for variable from typing import List li, lo = None, None # type: List[int], List[object] a, b, *c = 1, 2 # type: int, int, List[int] -c = lo # E: Incompatible types in assignment (expression has type List[object], variable has type List[int]) +c = lo # E: Incompatible types in assignment (expression has type "List[object]", variable has type "List[int]") c = li [builtins fixtures/list.pyi] @@ -450,14 +450,14 @@ class A: pass [out] main:6: error: List item 0 has incompatible type "A" main:6: error: List item 1 has incompatible type "A" -main:9: error: Incompatible types in assignment (expression has type "A", variable has type List[A]) +main:9: error: Incompatible types in assignment (expression has type "A", variable has type "List[A]") [case testAssignmentToStarFromTupleInference] from typing import List li = None # type: List[int] la = None # type: List[A] a, *l = A(), A() -l = li # E: Incompatible types in assignment (expression has type List[int], variable has type List[A]) +l = li # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[A]") l = la class A: pass @@ -469,7 +469,7 @@ from typing import List li = None # type: List[int] la = None # type: List[A] a, *l = [A(), A()] -l = li # E: Incompatible types in assignment (expression has type List[int], variable has type List[A]) +l = li # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[A]") l = la class A: pass @@ -482,7 +482,7 @@ li = None # type: List[int] la = None # type: List[A] ta = None # type: Tuple[A, A, A] a, *l = ta -l = li # E: Incompatible types in assignment (expression has type List[int], variable has type List[A]) +l = li # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[A]") l = la class A: pass @@ -494,7 +494,7 @@ from typing import List li = None # type: List[int] la = None # type: List[A] a, *l = la -l = li # E: Incompatible types in assignment (expression has type List[int], variable has type List[A]) +l = li # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[A]") l = la class A: pass @@ -579,7 +579,7 @@ class LongTypeName: def __add__(self, x: 'LongTypeName') -> 'LongTypeName': pass [builtins fixtures/tuple.pyi] [out] -main:3: error: Unsupported operand types for + ("LongTypeName" and tuple(length 50)) +main:3: error: Unsupported operand types for + ("LongTypeName" and "tuple(length 50)") -- Tuple methods @@ -750,7 +750,7 @@ tb = () # type: Tuple[B, ...] fa(ta) fa(tb) fb(tb) -fb(ta) # E: Argument 1 to "fb" has incompatible type Tuple[A, ...]; expected Tuple[B, ...] +fb(ta) # E: Argument 1 to "fb" has incompatible type "Tuple[A, ...]"; expected "Tuple[B, ...]" [builtins fixtures/tuple.pyi] [case testSubtypingFixedAndVariableLengthTuples] @@ -766,8 +766,8 @@ fa(aa) fa(ab) fa(bb) fb(bb) -fb(ab) # E: Argument 1 to "fb" has incompatible type "Tuple[A, B]"; expected Tuple[B, ...] -fb(aa) # E: Argument 1 to "fb" has incompatible type "Tuple[A, A]"; expected Tuple[B, ...] +fb(ab) # E: Argument 1 to "fb" has incompatible type "Tuple[A, B]"; expected "Tuple[B, ...]" +fb(aa) # E: Argument 1 to "fb" has incompatible type "Tuple[A, A]"; expected "Tuple[B, ...]" [builtins fixtures/tuple.pyi] [case testSubtypingTupleIsContainer] @@ -913,7 +913,7 @@ def f(a: Tuple) -> None: pass f(()) f((1,)) f(('', '')) -f(0) # E: Argument 1 to "f" has incompatible type "int"; expected Tuple[Any, ...] +f(0) # E: Argument 1 to "f" has incompatible type "int"; expected "Tuple[Any, ...]" [builtins fixtures/tuple.pyi] [case testTupleSingleton] diff --git a/test-data/unit/check-type-checks.test b/test-data/unit/check-type-checks.test index c4905a75ef78..dc3265238794 100644 --- a/test-data/unit/check-type-checks.test +++ b/test-data/unit/check-type-checks.test @@ -107,7 +107,7 @@ def f(x: object) -> None: if isinstance(x, C): x.f(1) x.f('') - x.g() # E: C[Any] has no attribute "g" + x.g() # E: "C[Any]" has no attribute "g" x.g() # E: "object" has no attribute "g" [builtins fixtures/isinstance.pyi] [out] diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 4714ec77f3dc..16010e5b9d1a 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -283,7 +283,7 @@ from mypy_extensions import TypedDict from typing import Mapping Point = TypedDict('Point', {'x': int, 'y': int}) def as_mapping(p: Point) -> Mapping[str, str]: - return p # E: Incompatible return value type (got "Point", expected Mapping[str, str]) + return p # E: Incompatible return value type (got "Point", expected "Mapping[str, str]") [builtins fixtures/dict.pyi] [case testTypedDictAcceptsIntForFloatDuckTypes] @@ -344,9 +344,9 @@ from mypy_extensions import TypedDict from typing import Dict, MutableMapping Point = TypedDict('Point', {'x': int, 'y': int}) def as_dict(p: Point) -> Dict[str, int]: - return p # E: Incompatible return value type (got "Point", expected Dict[str, int]) + return p # E: Incompatible return value type (got "Point", expected "Dict[str, int]") def as_mutable_mapping(p: Point) -> MutableMapping[str, int]: - return p # E: Incompatible return value type (got "Point", expected MutableMapping[str, int]) + return p # E: Incompatible return value type (got "Point", expected "MutableMapping[str, int]") [builtins fixtures/dict.pyi] [case testCanConvertTypedDictToAny] @@ -639,7 +639,7 @@ class C: A = TypedDict('A', {'x': int}) def g(self): A = TypedDict('A', {'y': int}) -C.A # E: Type[C] has no attribute "A" +C.A # E: "Type[C]" has no attribute "A" [builtins fixtures/dict.pyi] [case testTypedDictInFunction] diff --git a/test-data/unit/check-typevar-values.test b/test-data/unit/check-typevar-values.test index 36df2235a209..8dc6d32a55c1 100644 --- a/test-data/unit/check-typevar-values.test +++ b/test-data/unit/check-typevar-values.test @@ -270,7 +270,7 @@ y = C(S()) x = y y = x c_int = C(1) # type: C[int] -y = c_int # E: Incompatible types in assignment (expression has type C[int], variable has type C[str]) +y = c_int # E: Incompatible types in assignment (expression has type "C[int]", variable has type "C[str]") [case testGenericTypeBodyWithTypevarValues] from typing import TypeVar, Generic diff --git a/test-data/unit/check-unreachable-code.test b/test-data/unit/check-unreachable-code.test index 75e6f88c0c35..bbd538bc07ec 100644 --- a/test-data/unit/check-unreachable-code.test +++ b/test-data/unit/check-unreachable-code.test @@ -84,7 +84,7 @@ main:6: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" import typing MYPY = 0 if MYPY: - None + 1 # E: Unsupported left operand type for + (None) + None + 1 # E: Unsupported left operand type for + ("None") else: None + '' [builtins fixtures/bool.pyi] diff --git a/test-data/unit/check-varargs.test b/test-data/unit/check-varargs.test index 566841888693..802c6c8c8b86 100644 --- a/test-data/unit/check-varargs.test +++ b/test-data/unit/check-varargs.test @@ -10,8 +10,8 @@ from typing import Tuple def f( *b: 'B') -> None: ab = None # type: Tuple[B, ...] ac = None # type: Tuple[C, ...] - b = ac # E: Incompatible types in assignment (expression has type Tuple[C, ...], variable has type Tuple[B, ...]) - ac = b # E: Incompatible types in assignment (expression has type Tuple[B, ...], variable has type Tuple[C, ...]) + b = ac # E: Incompatible types in assignment (expression has type "Tuple[C, ...]", variable has type "Tuple[B, ...]") + ac = b # E: Incompatible types in assignment (expression has type "Tuple[B, ...]", variable has type "Tuple[C, ...]") b = ab ab = b @@ -108,7 +108,7 @@ it1 = None # type: Iterable[int] it2 = None # type: Iterable[str] def f(*x: int) -> None: pass f(*it1) -f(*it2) # E: Argument 1 to "f" has incompatible type *Iterable[str]; expected "int" +f(*it2) # E: Argument 1 to "f" has incompatible type *"Iterable[str]"; expected "int" [builtins fixtures/for.pyi] [case testCallVarargsFunctionWithIterableAndPositional] @@ -208,7 +208,7 @@ class A: pass class B: pass [builtins fixtures/list.pyi] [out] -main:7: error: Argument 1 to "f" has incompatible type *List[A]; expected "B" +main:7: error: Argument 1 to "f" has incompatible type *"List[A]"; expected "B" [case testCallingWithTupleVarArgs] @@ -277,13 +277,13 @@ class A: pass class B: pass [builtins fixtures/list.pyi] [out] -main:3: error: Argument 1 to "f" has incompatible type *List[A]; expected "B" -main:4: error: Argument 2 to "f" has incompatible type *List[A]; expected "B" +main:3: error: Argument 1 to "f" has incompatible type *"List[A]"; expected "B" +main:4: error: Argument 2 to "f" has incompatible type *"List[A]"; expected "B" main:5: error: Argument 1 to "f" has incompatible type "B"; expected "A" main:6: error: Argument 2 to "f" has incompatible type "A"; expected "B" -main:7: error: Argument 3 to "f" has incompatible type *List[A]; expected "B" +main:7: error: Argument 3 to "f" has incompatible type *"List[A]"; expected "B" main:8: error: Argument 1 to "f" has incompatible type "B"; expected "A" -main:9: error: Argument 1 to "g" has incompatible type *List[B]; expected "A" +main:9: error: Argument 1 to "g" has incompatible type *"List[B]"; expected "A" [case testCallingVarArgsFunctionWithTupleVarArgs] @@ -340,7 +340,7 @@ from typing import List aa = None # type: List[A] ab = None # type: List[B] -g(*aa) # E: Argument 1 to "g" has incompatible type *List[A]; expected "B" +g(*aa) # E: Argument 1 to "g" has incompatible type *"List[A]"; expected "B" f(*aa) f(*ab) g(*ab) @@ -377,8 +377,8 @@ class B: pass [builtins fixtures/list.pyi] [out] main:3: error: Too few arguments for "f" -main:4: error: Argument 2 to "f" has incompatible type *List[A]; expected "B" -main:5: error: Argument 3 to "f" has incompatible type *List[A]; expected "B" +main:4: error: Argument 2 to "f" has incompatible type *"List[A]"; expected "B" +main:5: error: Argument 3 to "f" has incompatible type *"List[A]"; expected "B" main:6: error: Argument 1 to "f" has incompatible type *"Tuple[A, A, B]"; expected "B" [case testVarArgsAfterKeywordArgInCall1-skip] @@ -491,11 +491,11 @@ class A: pass class B: pass [builtins fixtures/list.pyi] [out] -main:6: error: Argument 1 to "f" has incompatible type *List[A]; expected "B" -main:7: error: Argument 1 to "f" has incompatible type *List[A]; expected "B" +main:6: error: Argument 1 to "f" has incompatible type *"List[A]"; expected "B" +main:7: error: Argument 1 to "f" has incompatible type *"List[A]"; expected "B" main:8: error: Argument 1 to "f" has incompatible type "B"; expected "A" -main:9: error: Argument 2 to "f" has incompatible type *List[A]; expected "B" -main:10: error: Argument 3 to "f" has incompatible type *List[A]; expected "B" +main:9: error: Argument 2 to "f" has incompatible type *"List[A]"; expected "B" +main:10: error: Argument 3 to "f" has incompatible type *"List[A]"; expected "B" main:11: error: List or tuple expected as variable arguments main:12: error: List or tuple expected as variable arguments @@ -533,8 +533,8 @@ a, aa = G().f(*[a]) # Fail aa, a = G().f(*[a]) # Fail ab, aa = G().f(*[a]) # Fail -ao, ao = G().f(*[a]) # E: Incompatible types in assignment (expression has type List[], variable has type List[object]) -aa, aa = G().f(*[a]) # E: Incompatible types in assignment (expression has type List[], variable has type List[A]) +ao, ao = G().f(*[a]) # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[object]") +aa, aa = G().f(*[a]) # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") class G(Generic[T]): def f(self, *a: S) -> Tuple[List[S], List[T]]: @@ -544,11 +544,11 @@ class A: pass class B: pass [builtins fixtures/list.pyi] [out] -main:9: error: Incompatible types in assignment (expression has type List[A], variable has type "A") -main:9: error: Incompatible types in assignment (expression has type List[], variable has type List[A]) -main:10: error: Incompatible types in assignment (expression has type List[], variable has type "A") -main:11: error: Incompatible types in assignment (expression has type List[], variable has type List[A]) -main:11: error: Argument 1 to "f" of "G" has incompatible type *List[A]; expected "B" +main:9: error: Incompatible types in assignment (expression has type "List[A]", variable has type "A") +main:9: error: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") +main:10: error: Incompatible types in assignment (expression has type "List[]", variable has type "A") +main:11: error: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") +main:11: error: Argument 1 to "f" of "G" has incompatible type *"List[A]"; expected "B" -- Comment signatures From 466a832ab0dc9cdbf01a5a6e9ab90cc1f30cac90 Mon Sep 17 00:00:00 2001 From: Brian Weber Date: Tue, 23 May 2017 15:57:10 -0700 Subject: [PATCH 02/27] No quotes around Module --- mypy/messages.py | 3 +++ test-data/unit/check-ignore.test | 4 ++-- test-data/unit/check-incremental.test | 6 +++--- test-data/unit/check-modules.test | 16 ++++++++-------- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index ad158d4edc9f..209b2ebf7726 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -241,6 +241,9 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: None -> None callable type -> "" (empty string) """ + ret = self._format_simple(typ, verbosity) + if ret == "Module": + return ret return '"{}"'.format(self._format_simple(typ, verbosity)) def _format_simple(self, typ: Type, verbosity: int = 0) -> str: diff --git a/test-data/unit/check-ignore.test b/test-data/unit/check-ignore.test index 5f2fd773a0c1..ad183ac1fe2b 100644 --- a/test-data/unit/check-ignore.test +++ b/test-data/unit/check-ignore.test @@ -46,7 +46,7 @@ import b # type: ignore reveal_type(a.foo) # E: Revealed type is 'Any' reveal_type(b.foo) # E: Revealed type is 'builtins.int' a.bar() -b.bar() # E: "Module" has no attribute "bar" +b.bar() # E: Module has no attribute "bar" [file b.py] foo = 3 @@ -76,7 +76,7 @@ class B(A): import m m.x = object # type: ignore m.f() # type: ignore -m.y # E: "Module" has no attribute "y" +m.y # E: Module has no attribute "y" [file m.py] [builtins fixtures/module.pyi] diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 78da587098ec..23fafc24edf5 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -325,7 +325,7 @@ const = 3 [stale mod3] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: "Module" has no attribute "mod4" +tmp/mod1.py:3: error: Module has no attribute "mod4" [case testIncrementalLongBrokenCascade] import mod1 @@ -360,7 +360,7 @@ const = 3 [stale mod6] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: "Module" has no attribute "mod7" +tmp/mod1.py:3: error: Module has no attribute "mod7" [case testIncrementalNestedBrokenCascade] import mod1 @@ -386,7 +386,7 @@ const = 3 [stale mod2.mod3] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: "Module" has no attribute "mod4" +tmp/mod1.py:3: error: Module has no attribute "mod4" [case testIncrementalNestedBrokenCascadeWithType1] import mod1, mod2.mod3.mod5 diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test index 10c6a22680d6..423994ad981b 100644 --- a/test-data/unit/check-modules.test +++ b/test-data/unit/check-modules.test @@ -155,16 +155,16 @@ import m import typing class A: pass -m() # E: "Module" not callable -a = m # type: A # E: Incompatible types in assignment (expression has type "Module", variable has type "A") -m + None # E: Unsupported left operand type for + ("Module") +m() # E: Module not callable +a = m # type: A # E: Incompatible types in assignment (expression has type Module, variable has type "A") +m + None # E: Unsupported left operand type for + (Module) [file m.py] [builtins fixtures/module.pyi] [case testNameDefinedInDifferentModule] import m, n import typing -m.x # E: "Module" has no attribute "x" +m.x # E: Module has no attribute "x" [file m.py] y = object() [file n.py] @@ -330,7 +330,7 @@ import nonexistent [out] tmp/x.py:1: error: Cannot find module named 'nonexistent' tmp/x.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:3: error: "Module" has no attribute "z" +main:3: error: Module has no attribute "z" [case testUnknownModuleImportedWithinFunction] def f(): @@ -648,7 +648,7 @@ def f(x: str) -> None: pass if object(): import m else: - m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Module") + m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type Module) [file m.py] [builtins fixtures/module.pyi] [out] @@ -752,7 +752,7 @@ value = 3.2 [case testSubmoduleImportFromDoesNotAddParents] from a import b reveal_type(b.value) # E: Revealed type is 'builtins.str' -b.c.value # E: "Module" has no attribute "c" +b.c.value # E: Module has no attribute "c" a.value # E: Name 'a' is not defined [file a/__init__.py] @@ -853,7 +853,7 @@ bar = parent.unrelated.ShouldNotLoad() [builtins fixtures/module.pyi] [out] tmp/parent/child.py:8: error: Revealed type is 'parent.common.SomeClass' -tmp/parent/child.py:9: error: "Module" has no attribute "unrelated" +tmp/parent/child.py:9: error: Module has no attribute "unrelated" [case testSubmoduleMixingImportFromAndImport2] import parent.child From dc7c243e05e0cb79efdcccec7517f7fc5c0043b8 Mon Sep 17 00:00:00 2001 From: Brian Weber Date: Tue, 23 May 2017 16:53:16 -0700 Subject: [PATCH 03/27] And even more tests that need to be updated --- test-data/unit/pythoneval-asyncio.test | 8 ++++---- test-data/unit/pythoneval.test | 28 +++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test-data/unit/pythoneval-asyncio.test b/test-data/unit/pythoneval-asyncio.test index 6d1690339ff7..114cd4b9cb66 100644 --- a/test-data/unit/pythoneval-asyncio.test +++ b/test-data/unit/pythoneval-asyncio.test @@ -339,7 +339,7 @@ loop.run_until_complete(future) print(future.result()) loop.close() [out] -_program.py:12: error: Argument 1 to "slow_operation" has incompatible type Future[str]; expected Future[int] +_program.py:12: error: Argument 1 to "slow_operation" has incompatible type "Future[str]"; expected "Future[int]" [case testErrorUsingDifferentFutureTypeAndSetFutureDifferentInternalType] from typing import Generator, Any @@ -359,7 +359,7 @@ print(future.result()) loop.close() [out] _program.py:8: error: Argument 1 to "set_result" of "Future" has incompatible type "str"; expected "int" -_program.py:12: error: Argument 1 to "slow_operation" has incompatible type Future[str]; expected Future[int] +_program.py:12: error: Argument 1 to "slow_operation" has incompatible type "Future[str]"; expected "Future[int]" [case testErrorSettingCallbackWithDifferentFutureType] import typing @@ -422,7 +422,7 @@ loop = asyncio.get_event_loop() loop.run_until_complete(h()) loop.close() [out] -_program.py:18: error: Incompatible return value type (got Future[Future[int]], expected Future[Future[Future[int]]]) +_program.py:18: error: Incompatible return value type (got "Future[Future[int]]", expected "Future[Future[Future[int]]]") [case testErrorOneLessFutureInReturnType] import typing @@ -456,7 +456,7 @@ loop = asyncio.get_event_loop() loop.run_until_complete(h()) loop.close() [out] -_program.py:18: error: Incompatible return value type (got Future[Future[int]], expected Future[int]) +_program.py:18: error: Incompatible return value type (got "Future[Future[int]]", expected "Future[int]") [case testErrorAssignmentDifferentType] import typing diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 92b9906f9b53..704ccffcf65d 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -391,7 +391,7 @@ txt(sys.stdout) bin(sys.stdout) [out] _program.py:5: error: Argument 1 to "write" of "IO" has incompatible type "bytes"; expected "str" -_program.py:10: error: Argument 1 to "bin" has incompatible type "TextIO"; expected IO[bytes] +_program.py:10: error: Argument 1 to "bin" has incompatible type "TextIO"; expected "IO[bytes]" [case testBuiltinOpen] f = open('x') @@ -399,7 +399,7 @@ f.write('x') f.write(b'x') f.foobar() [out] -_program.py:4: error: IO[Any] has no attribute "foobar" +_program.py:4: error: "IO[Any]" has no attribute "foobar" [case testGenericPatterns] from typing import Pattern @@ -577,7 +577,7 @@ print(tuple(a)) import typing [1] + iter([2, 3]) [out] -_program.py:2: error: Unsupported operand types for + (List[int] and Iterator[int]) +_program.py:2: error: Unsupported operand types for + ("List[int]" and "Iterator[int]") [case testInferHeterogeneousListOfIterables] from typing import Sequence @@ -766,7 +766,7 @@ x = range(3) a = list(map(str, x)) a + 1 [out] -_program.py:4: error: Unsupported operand types for + (List[str] and "int") +_program.py:4: error: Unsupported operand types for + ("List[str]" and "int") [case testNamedTuple] import typing @@ -968,7 +968,7 @@ def f(*x: int) -> None: x.append(1) f(1) [out] -_program.py:3: error: Tuple[int, ...] has no attribute "append" +_program.py:3: error: "Tuple[int, ...]" has no attribute "append" [case testExit] print('a') @@ -1049,14 +1049,14 @@ n = 4 t = ('',) * n t + 1 [out] -_program.py:3: error: Unsupported operand types for + (Tuple[str, ...] and "int") +_program.py:3: error: Unsupported operand types for + ("Tuple[str, ...]" and "int") [case testMultiplyTupleByIntegerReverse] n = 4 t = n * ('',) t + 1 [out] -_program.py:3: error: Unsupported operand types for + (Tuple[str, ...] and "int") +_program.py:3: error: Unsupported operand types for + ("Tuple[str, ...]" and "int") [case testDictWithKeywordArgs] from typing import Dict, Any, List @@ -1068,7 +1068,7 @@ d4 = dict(a=1, b='') # type: Dict[str, Any] result = dict(x=[], y=[]) # type: Dict[str, List[str]] [out] _program.py:3: error: Dict entry 1 has incompatible type "str": "str" -_program.py:5: error: Dict[str, int] has no attribute "xyz" +_program.py:5: error: "Dict[str, int]" has no attribute "xyz" [case testDefaultDict] import typing as t @@ -1096,11 +1096,11 @@ class MyDDict(t.DefaultDict[int,T], t.Generic[T]): MyDDict(dict)['0'] MyDDict(dict)[0] [out] -_program.py:6: error: Argument 1 to "defaultdict" has incompatible type Type[List[Any]]; expected Callable[[], str] -_program.py:9: error: Invalid index type "str" for defaultdict[int, str]; expected type "int" +_program.py:6: error: Argument 1 to "defaultdict" has incompatible type "Type[List[Any]]"; expected Callable[[], str] +_program.py:9: error: Invalid index type "str" for "defaultdict[int, str]"; expected type "int" _program.py:9: error: Incompatible types in assignment (expression has type "int", target has type "str") -_program.py:19: error: Dict entry 0 has incompatible type "str": List[] -_program.py:23: error: Invalid index type "str" for MyDDict[Dict[_KT, _VT]]; expected type "int" +_program.py:19: error: Dict entry 0 has incompatible type "str": "List[]" +_program.py:23: error: Invalid index type "str" for "MyDDict[Dict[_KT, _VT]]"; expected type "int" [case testNoSubcriptionOfStdlibCollections] import collections @@ -1122,7 +1122,7 @@ def f(d: collections.defaultdict[int, str]) -> None: _program.py:5: error: "defaultdict" is not subscriptable _program.py:6: error: "Counter" is not subscriptable _program.py:9: error: "defaultdict" is not subscriptable -_program.py:12: error: Invalid index type "int" for defaultdict[str, int]; expected type "str" +_program.py:12: error: Invalid index type "int" for "defaultdict[str, int]"; expected type "str" _program.py:14: error: "defaultdict" is not subscriptable, use "typing.DefaultDict" instead [case testCollectionsAliases] @@ -1150,7 +1150,7 @@ reveal_type(o6) [out] _testCollectionsAliases.py:5: error: Revealed type is 'collections.Counter[builtins.int]' -_testCollectionsAliases.py:6: error: Invalid index type "str" for Counter[int]; expected type "int" +_testCollectionsAliases.py:6: error: Invalid index type "str" for "Counter[int]"; expected type "int" _testCollectionsAliases.py:9: error: Revealed type is 'collections.ChainMap[builtins.int, builtins.str]' _testCollectionsAliases.py:12: error: Revealed type is 'collections.deque[builtins.int]' _testCollectionsAliases.py:15: error: Revealed type is 'collections.Counter[builtins.int*]' From df586333597daa985c84c14ee6ae3e0ef41df741 Mon Sep 17 00:00:00 2001 From: Brian Weber Date: Tue, 23 May 2017 21:40:53 -0700 Subject: [PATCH 04/27] incorrect indentation --- mypy/messages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/messages.py b/mypy/messages.py index 209b2ebf7726..423ff0a65f29 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -243,7 +243,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: """ ret = self._format_simple(typ, verbosity) if ret == "Module": - return ret + return ret return '"{}"'.format(self._format_simple(typ, verbosity)) def _format_simple(self, typ: Type, verbosity: int = 0) -> str: From 7940d76c85aabcb4bab8bb28a439438df7f586fe Mon Sep 17 00:00:00 2001 From: Carl Meyer Date: Wed, 24 May 2017 05:56:58 -0700 Subject: [PATCH 05/27] Add 'how to run this one test' note to test quick start. (#3436) This was something I was looking for in the quick start, and didn't find clearly stated anywhere in the README. --- test-data/unit/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/test-data/unit/README.md b/test-data/unit/README.md index 4e42a064ae3a..64737e8ca3b4 100644 --- a/test-data/unit/README.md +++ b/test-data/unit/README.md @@ -41,6 +41,7 @@ usually, "E: " is preferred because it makes it easier to associate the errors with the code generating them at a glance, and to change the code of the test without having to change line numbers in `[out]` - an empty `[out]` section has no effect +- to run just this test, use `pytest -k testNewSyntaxBasics -n0` Fixtures From ccd95e6adea3fcf8058a4bc1e99e0cea0623e9ee Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Wed, 24 May 2017 23:53:58 +0200 Subject: [PATCH 06/27] Fix crashes in synthetic types (#3322) Fixes #3308 This PR adds better processing of "synthetic" types (``NewType``, ``NamedTuple``, ``TypedDict``) to the third pass and moves some processing from the second to the third pass. --- mypy/nodes.py | 3 +- mypy/semanal.py | 23 ++++++-- mypy/typeanal.py | 3 ++ test-data/unit/check-classes.test | 87 +++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/mypy/nodes.py b/mypy/nodes.py index e662dd2dfb2f..a5cb96007750 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -731,6 +731,7 @@ class ClassDef(Statement): info = None # type: TypeInfo # Related TypeInfo metaclass = '' # type: Optional[str] decorators = None # type: List[Expression] + analyzed = None # type: Optional[Expression] has_incompatible_baseclass = False def __init__(self, @@ -753,7 +754,7 @@ def is_generic(self) -> bool: return self.info.is_generic() def serialize(self) -> JsonDict: - # Not serialized: defs, base_type_exprs, decorators + # Not serialized: defs, base_type_exprs, decorators, analyzed (for named tuples etc.) return {'.class': 'ClassDef', 'name': self.name, 'fullname': self.fullname, diff --git a/mypy/semanal.py b/mypy/semanal.py index b14e3dd9076e..d16be31e8e18 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -862,6 +862,7 @@ def analyze_namedtuple_classdef(self, defn: ClassDef) -> Optional[TypeInfo]: defn.name, items, types, default_items) node.node = info defn.info = info + defn.analyzed = NamedTupleExpr(info) return info return None @@ -1178,7 +1179,9 @@ def analyze_typeddict_classdef(self, defn: ClassDef) -> bool: defn.base_type_exprs[0].fullname == 'mypy_extensions.TypedDict'): # Building a new TypedDict fields, types = self.check_typeddict_classdef(defn) - node.node = self.build_typeddict_typeinfo(defn.name, fields, types) + info = self.build_typeddict_typeinfo(defn.name, fields, types) + node.node = info + defn.analyzed = TypedDictExpr(info) return True # Extending/merging existing TypedDicts if any(not isinstance(expr, RefExpr) or @@ -1205,7 +1208,9 @@ def analyze_typeddict_classdef(self, defn: ClassDef) -> bool: fields, types = self.check_typeddict_classdef(defn, newfields) newfields.extend(fields) newtypes.extend(types) - node.node = self.build_typeddict_typeinfo(defn.name, newfields, newtypes) + info = self.build_typeddict_typeinfo(defn.name, newfields, newtypes) + node.node = info + defn.analyzed = TypedDictExpr(info) return True return False @@ -3681,6 +3686,11 @@ def visit_class_def(self, tdef: ClassDef) -> None: if tdef.info.mro: tdef.info.mro = [] # Force recomputation calculate_class_mro(tdef, self.fail_blocker) + if tdef.analyzed is not None: + if isinstance(tdef.analyzed, TypedDictExpr): + self.analyze(tdef.analyzed.info.typeddict_type) + elif isinstance(tdef.analyzed, NamedTupleExpr): + self.analyze(tdef.analyzed.info.tuple_type) super().visit_class_def(tdef) def visit_decorator(self, dec: Decorator) -> None: @@ -3737,6 +3747,13 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None: self.analyze(s.type) if isinstance(s.rvalue, IndexExpr) and isinstance(s.rvalue.analyzed, TypeAliasExpr): self.analyze(s.rvalue.analyzed.type) + if isinstance(s.rvalue, CallExpr): + if isinstance(s.rvalue.analyzed, NewTypeExpr): + self.analyze(s.rvalue.analyzed.old_type) + if isinstance(s.rvalue.analyzed, TypedDictExpr): + self.analyze(s.rvalue.analyzed.info.typeddict_type) + if isinstance(s.rvalue.analyzed, NamedTupleExpr): + self.analyze(s.rvalue.analyzed.info.tuple_type) super().visit_assignment_stmt(s) def visit_cast_expr(self, e: CastExpr) -> None: @@ -3753,7 +3770,7 @@ def visit_type_application(self, e: TypeApplication) -> None: # Helpers - def analyze(self, type: Type) -> None: + def analyze(self, type: Optional[Type]) -> None: if type: analyzer = TypeAnalyserPass3(self.fail) type.accept(analyzer) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 2a506b7a5378..3b90464c3367 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -610,6 +610,9 @@ def visit_instance(self, t: Instance) -> None: arg, info.name(), tvar.upper_bound), t) for arg in t.args: arg.accept(self) + if info.is_newtype: + for base in info.bases: + base.accept(self) def check_type_var_values(self, type: TypeInfo, actuals: List[Type], valids: List[Type], arg_number: int, context: Context) -> None: diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index a257fa0375f0..0b6bb6873d62 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -3137,6 +3137,93 @@ class M(type): class A(metaclass=M): pass reveal_type(type(A).x) # E: Revealed type is 'builtins.int' +-- Synthetic types crashes +-- ----------------------- + +[case testCrashInvalidArgsSyntheticClassSyntax] +from typing import List, NamedTuple +from mypy_extensions import TypedDict +class TD(TypedDict): + x: List[int, str] # E: "list" expects 1 type argument, but 2 given +class NM(NamedTuple): + x: List[int, str] # E: "list" expects 1 type argument, but 2 given + +# These two should never crash, reveals are in the next test +TD({'x': []}) +NM(x=[]) +[builtins fixtures/dict.pyi] +[out] + +[case testCrashInvalidArgsSyntheticClassSyntaxReveals] +from typing import List, NamedTuple +from mypy_extensions import TypedDict +class TD(TypedDict): + x: List[int, str] # E: "list" expects 1 type argument, but 2 given +class NM(NamedTuple): + x: List[int, str] # E: "list" expects 1 type argument, but 2 given + +x: TD +x1 = TD({'x': []}) +y: NM +y1 = NM(x=[]) +reveal_type(x) # E: Revealed type is 'TypedDict(x=builtins.list[Any], _fallback=__main__.TD)' +reveal_type(x1) # E: Revealed type is 'TypedDict(x=builtins.list[Any], _fallback=typing.Mapping[builtins.str, builtins.list[Any]])' +reveal_type(y) # E: Revealed type is 'Tuple[builtins.list[Any], fallback=__main__.NM]' +reveal_type(y1) # E: Revealed type is 'Tuple[builtins.list[Any], fallback=__main__.NM]' +[builtins fixtures/dict.pyi] +[out] + +[case testCrashInvalidArgsSyntheticFunctionSyntax] +from typing import List, NewType, NamedTuple +from mypy_extensions import TypedDict +TD = TypedDict('TD', {'x': List[int, str]}) # E: "list" expects 1 type argument, but 2 given +NM = NamedTuple('NM', [('x', List[int, str])]) # E: "list" expects 1 type argument, but 2 given +NT = NewType('NT', List[int, str]) # E: "list" expects 1 type argument, but 2 given + +# These three should not crash +TD({'x': []}) +NM(x=[]) +NT([]) +[builtins fixtures/dict.pyi] +[out] + +-- The two tests below will not crash after +-- https://github.com/python/mypy/issues/3319 is fixed +[case testCrashForwardSyntheticClassSyntax-skip] +from typing import NamedTuple +from mypy_extensions import TypedDict +class A1(NamedTuple): + b: 'B' + x: int +class A2(TypedDict): + b: 'B' + x: int +class B: + pass +x: A1 +y: A2 +reveal_type(x.b) # E: Revealed type is '__main__.B' +reveal_type(y['b']) # E: Revealed type is '__main__.B' +[builtins fixtures/dict.pyi] +[out] + +[case testCrashForwardSyntheticFunctionSyntax-skip] +from typing import NamedTuple +from mypy_extensions import TypedDict +A1 = NamedTuple('A1', [('b', 'B'), ('x', int)]) +A2 = TypedDict('A2', {'b': 'B', 'x': int}) +class B: + pass +x: A1 +y: A2 +reveal_type(x.b) # E: Revealed type is '__main__.B' +reveal_type(y['b']) # E: Revealed type is '__main__.B' +[builtins fixtures/dict.pyi] +[out] + +-- Special support for six +-- ----------------------- + [case testSixWithMetaclass] import six class M(type): From 75c526aaacf058a7485b0766fe61692efcfa21d3 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 24 May 2017 15:01:11 -0700 Subject: [PATCH 07/27] Fix bug in cache log (#3443) --- mypy/waiter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/waiter.py b/mypy/waiter.py index 62a0555974c0..0f1759fefab8 100644 --- a/mypy/waiter.py +++ b/mypy/waiter.py @@ -339,7 +339,7 @@ def sort_function(cmd: LazySubprocess) -> Tuple[Any, int, float]: if self.new_log: # don't append empty log, it will corrupt the cache file # log only LOGSIZE most recent tests - test_log = (self.load_log_file() + [self.new_log])[:self.LOGSIZE] + test_log = (self.load_log_file() + [self.new_log])[-self.LOGSIZE:] try: with open(self.FULL_LOG_FILENAME, 'w') as fp: json.dump(test_log, fp, sort_keys=True, indent=4) From 847d884beea7e16506b91ffbad32d8441332c7fc Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 24 May 2017 20:28:31 -0700 Subject: [PATCH 08/27] Sync typeshed (#3449) --- typeshed | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typeshed b/typeshed index c2e6a6f670f5..c1b7fc70203c 160000 --- a/typeshed +++ b/typeshed @@ -1 +1 @@ -Subproject commit c2e6a6f670f5d75c07eb31cf2509db302825b76d +Subproject commit c1b7fc70203c4b92577f1f4765e0fdb654a8886c From a494197163db9f515f6efc278a17337ebc4528e5 Mon Sep 17 00:00:00 2001 From: Jesse Lord Date: Thu, 25 May 2017 00:04:09 -0700 Subject: [PATCH 09/27] Mismatch of inferred type and return type note (#3428) * Add note for diff inffered and return type * Fix conditions for note * Move tests to newline * Style improvements and more detailed message * Fix tests * Move message function to messages * More test cases * Test different sequence * Cleaner separate of test cases --- mypy/checker.py | 7 +++- mypy/messages.py | 31 +++++++++++++++- test-data/unit/check-functions.test | 56 +++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 870c561852b6..59746059a573 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -36,7 +36,7 @@ true_only, false_only, function_type, is_named_instance, union_items ) from mypy.sametypes import is_same_type, is_same_types -from mypy.messages import MessageBuilder +from mypy.messages import MessageBuilder, make_inferred_type_note import mypy.checkexpr from mypy.checkmember import map_type_from_supertype, bind_self, erase_to_bound from mypy import messages @@ -2313,15 +2313,20 @@ def check_subtype(self, subtype: Type, supertype: Type, context: Context, if self.should_suppress_optional_error([subtype]): return False extra_info = [] # type: List[str] + note_msg = '' if subtype_label is not None or supertype_label is not None: subtype_str, supertype_str = self.msg.format_distinctly(subtype, supertype) if subtype_label is not None: extra_info.append(subtype_label + ' ' + subtype_str) if supertype_label is not None: extra_info.append(supertype_label + ' ' + supertype_str) + note_msg = make_inferred_type_note(context, subtype, + supertype, supertype_str) if extra_info: msg += ' (' + ', '.join(extra_info) + ')' self.fail(msg, context) + if note_msg: + self.note(note_msg, context) return False def contains_none(self, t: Type) -> bool: diff --git a/mypy/messages.py b/mypy/messages.py index e8fb537f6fa5..8dbf1dbeff95 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -17,7 +17,8 @@ ) from mypy.nodes import ( TypeInfo, Context, MypyFile, op_methods, FuncDef, reverse_type_aliases, - ARG_POS, ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2 + ARG_POS, ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2, + ReturnStmt, NameExpr, Var ) @@ -989,3 +990,31 @@ def pretty_or(args: List[str]) -> str: if len(quoted) == 2: return "{} or {}".format(quoted[0], quoted[1]) return ", ".join(quoted[:-1]) + ", or " + quoted[-1] + + +def make_inferred_type_note(context: Context, subtype: Type, + supertype: Type, supertype_str: str) -> str: + """Explain that the user may have forgotten to type a variable. + + The user does not expect an error if the inferred container type is the same as the return + type of a function and the argument type(s) are a subtype of the argument type(s) of the + return type. This note suggests that they add a type annotation with the return type instead + of relying on the inferred type. + """ + from mypy.subtypes import is_subtype + if (isinstance(subtype, Instance) and + isinstance(supertype, Instance) and + subtype.type.fullname() == supertype.type.fullname() and + subtype.args and + supertype.args and + isinstance(context, ReturnStmt) and + isinstance(context.expr, NameExpr) and + isinstance(context.expr.node, Var) and + context.expr.node.is_inferred): + for subtype_arg, supertype_arg in zip(subtype.args, supertype.args): + if not is_subtype(subtype_arg, supertype_arg): + return '' + var_name = context.expr.name + return 'Perhaps you need a type annotation for "{}"? Suggestion: {}'.format( + var_name, supertype_str) + return '' diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index e4a155a748ed..343b4b79cf9f 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -2067,3 +2067,59 @@ def some_method(self: badtype): pass # E: Name 'badtype' is not defined def fn( a: badtype) -> None: # E: Name 'badtype' is not defined pass + +[case testInferredTypeSubTypeOfReturnType] +from typing import Union, Dict, List +def f() -> List[Union[str, int]]: + x = ['a'] + return x # E: Incompatible return value type (got List[str], expected List[Union[str, int]]) \ +# N: Perhaps you need a type annotation for "x"? Suggestion: List[Union[str, int]] + +def g() -> Dict[str, Union[str, int]]: + x = {'a': 'a'} + return x # E: Incompatible return value type (got Dict[str, str], expected Dict[str, Union[str, int]]) \ +# N: Perhaps you need a type annotation for "x"? Suggestion: Dict[str, Union[str, int]] + +def h() -> Dict[Union[str, int], str]: + x = {'a': 'a'} + return x # E: Incompatible return value type (got Dict[str, str], expected Dict[Union[str, int], str]) \ +# N: Perhaps you need a type annotation for "x"? Suggestion: Dict[Union[str, int], str] + +def i() -> List[Union[int, float]]: + x: List[int] = [1] + return x # E: Incompatible return value type (got List[int], expected List[Union[int, float]]) \ +# N: Perhaps you need a type annotation for "x"? Suggestion: List[Union[int, float]] + +[builtins fixtures/dict.pyi] + +[case testInferredTypeNotSubTypeOfReturnType] +from typing import Union, List +def f() -> List[Union[int, float]]: + x = ['a'] + return x # E: Incompatible return value type (got List[str], expected List[Union[int, float]]) + +def g() -> List[Union[str, int]]: + x = ('a', 2) + return x # E: Incompatible return value type (got "Tuple[str, int]", expected List[Union[str, int]]) + +[builtins fixtures/list.pyi] + +[case testInferredTypeIsObjectMismatch] +from typing import Union, Dict, List +def f() -> Dict[str, Union[str, int]]: + x = {'a': 'a', 'b': 2} + return x # E: Incompatible return value type (got Dict[str, object], expected Dict[str, Union[str, int]]) + +def g() -> Dict[str, Union[str, int]]: + x: Dict[str, Union[str, int]] = {'a': 'a', 'b': 2} + return x + +def h() -> List[Union[str, int]]: + x = ['a', 2] + return x # E: Incompatible return value type (got List[object], expected List[Union[str, int]]) + +def i() -> List[Union[str, int]]: + x: List[Union[str, int]] = ['a', 2] + return x + +[builtins fixtures/dict.pyi] From 53879ef0da6337b0ed75fb2114f81c08bc7ede2f Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 25 May 2017 00:14:58 -0700 Subject: [PATCH 10/27] Add type checking plugin support for functions (#3299) * Add type checking plugin support for functions The plugins allow implementing special-case logic for inferring the return type of certain functions with tricky signatures such as `open` in Python 3. Include plugins for `open` and `contextlib.contextmanager`. Some design considerations: - The plugins have direct access to mypy internals. The idea is that most plugins will be included with mypy so mypy maintainers can update the plugins as needed. - User-maintained plugins are currently not supported but could be added in the future. However, the intention is to not have a stable plugin API, at least initially. User-maintained plugins would have to track mypy internal API changes. Later on, we may decide to provide a more stable API if there seems to be a significant need. The preferred way would still be to keep plugins in the mypy repo. * Add test case for additional special cases * Fix handling of arguments other than simple positional ones Also add comments and some defensive checks. --- mypy/checker.py | 6 ++- mypy/checkexpr.py | 43 ++++++++++++++++-- mypy/funcplugins.py | 81 ++++++++++++++++++++++++++++++++++ test-data/unit/pythoneval.test | 52 +++++++++++++++++++++- 4 files changed, 176 insertions(+), 6 deletions(-) create mode 100644 mypy/funcplugins.py diff --git a/mypy/checker.py b/mypy/checker.py index 59746059a573..0a08aca51cb4 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -2223,8 +2223,12 @@ def visit_decorator(self, e: Decorator) -> None: continue dec = self.expr_checker.accept(d) temp = self.temp_node(sig) + fullname = None + if isinstance(d, RefExpr): + fullname = d.fullname sig, t2 = self.expr_checker.check_call(dec, [temp], - [nodes.ARG_POS], e) + [nodes.ARG_POS], e, + callable_name=fullname) sig = cast(FunctionLike, sig) sig = set_callable_name(sig, e.func) e.var.type = sig diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index b19a0a1bcfd2..016668b46105 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -44,6 +44,7 @@ from mypy.util import split_module_names from mypy.typevars import fill_typevars from mypy.visitor import ExpressionVisitor +from mypy.funcplugins import get_function_plugin_callbacks, PluginCallback from mypy import experiments @@ -103,6 +104,7 @@ class ExpressionChecker(ExpressionVisitor[Type]): type_context = None # type: List[Optional[Type]] strfrm_checker = None # type: StringFormatterChecker + function_plugins = None # type: Dict[str, PluginCallback] def __init__(self, chk: 'mypy.checker.TypeChecker', @@ -112,6 +114,7 @@ def __init__(self, self.msg = msg self.type_context = [None] self.strfrm_checker = StringFormatterChecker(self, self.chk, self.msg) + self.function_plugins = get_function_plugin_callbacks(self.chk.options.python_version) def visit_name_expr(self, e: NameExpr) -> Type: """Type check a name expression. @@ -198,7 +201,11 @@ def visit_call_expr(self, e: CallExpr, allow_none_return: bool = False) -> Type: isinstance(callee_type, CallableType) and callee_type.implicit): return self.msg.untyped_function_call(callee_type, e) - ret_type = self.check_call_expr_with_callee_type(callee_type, e) + if not isinstance(e.callee, RefExpr): + fullname = None + else: + fullname = e.callee.fullname + ret_type = self.check_call_expr_with_callee_type(callee_type, e, fullname) if isinstance(ret_type, UninhabitedType): self.chk.binder.unreachable() if not allow_none_return and isinstance(ret_type, NoneTyp): @@ -330,21 +337,44 @@ def try_infer_partial_type(self, e: CallExpr) -> None: list(full_item_types)) del partial_types[var] + def apply_function_plugin(self, + arg_types: List[Type], + inferred_ret_type: Type, + arg_kinds: List[int], + formal_to_actual: List[List[int]], + args: List[Expression], + num_formals: int, + fullname: Optional[str]) -> Type: + """Use special case logic to infer the return type for of a particular named function. + + Return the inferred return type. + """ + formal_arg_types = [[] for _ in range(num_formals)] # type: List[List[Type]] + formal_arg_exprs = [[] for _ in range(num_formals)] # type: List[List[Expression]] + for formal, actuals in enumerate(formal_to_actual): + for actual in actuals: + formal_arg_types[formal].append(arg_types[actual]) + formal_arg_exprs[formal].append(args[actual]) + return self.function_plugins[fullname]( + formal_arg_types, formal_arg_exprs, inferred_ret_type, self.chk.named_generic_type) + def check_call_expr_with_callee_type(self, callee_type: Type, - e: CallExpr) -> Type: + e: CallExpr, callable_name: Optional[str]) -> Type: """Type check call expression. The given callee type overrides the type of the callee expression. """ return self.check_call(callee_type, e.args, e.arg_kinds, e, - e.arg_names, callable_node=e.callee)[0] + e.arg_names, callable_node=e.callee, + callable_name=callable_name)[0] def check_call(self, callee: Type, args: List[Expression], arg_kinds: List[int], context: Context, arg_names: List[str] = None, callable_node: Expression = None, - arg_messages: MessageBuilder = None) -> Tuple[Type, Type]: + arg_messages: MessageBuilder = None, + callable_name: Optional[str] = None) -> Tuple[Type, Type]: """Type check a call. Also infer type arguments if the callee is a generic function. @@ -406,6 +436,11 @@ def check_call(self, callee: Type, args: List[Expression], if callable_node: # Store the inferred callable type. self.chk.store_type(callable_node, callee) + if callable_name in self.function_plugins: + ret_type = self.apply_function_plugin( + arg_types, callee.ret_type, arg_kinds, formal_to_actual, + args, len(callee.arg_types), callable_name) + callee = callee.copy_modified(ret_type=ret_type) return callee.ret_type, callee elif isinstance(callee, Overloaded): # Type check arguments in empty context. They will be checked again diff --git a/mypy/funcplugins.py b/mypy/funcplugins.py new file mode 100644 index 000000000000..7d5c25248e0a --- /dev/null +++ b/mypy/funcplugins.py @@ -0,0 +1,81 @@ +"""Plugins that implement special type checking rules for individual functions. + +The plugins infer better types for tricky functions such as "open". +""" + +from typing import Tuple, Dict, Callable, List + +from mypy.nodes import Expression, StrExpr +from mypy.types import Type, Instance, CallableType + + +# A callback that infers the return type of a function with a special signature. +# +# A no-op callback would just return the inferred return type, but a useful callback +# at least sometimes can infer a more precise type. +PluginCallback = Callable[ + [ + List[List[Type]], # List of types caller provides for each formal argument + List[List[Expression]], # Actual argument expressions for each formal argument + Type, # Return type for call inferred using the regular signature + Callable[[str, List[Type]], Type] # Callable for constructing a named instance type + ], + Type # Return type inferred by the callback +] + + +def get_function_plugin_callbacks(python_version: Tuple[int, int]) -> Dict[str, PluginCallback]: + """Return all available function plugins for a given Python version.""" + if python_version[0] == 3: + return { + 'builtins.open': open_callback, + 'contextlib.contextmanager': contextmanager_callback, + } + else: + return { + 'contextlib.contextmanager': contextmanager_callback, + } + + +def open_callback( + arg_types: List[List[Type]], + args: List[List[Expression]], + inferred_return_type: Type, + named_generic_type: Callable[[str, List[Type]], Type]) -> Type: + """Infer a better return type for 'open'. + + Infer IO[str] or IO[bytes] as the return value if the mode argument is not + given or is a literal. + """ + mode = None + if not arg_types or len(arg_types[1]) != 1: + mode = 'r' + elif isinstance(args[1][0], StrExpr): + mode = args[1][0].value + if mode is not None: + assert isinstance(inferred_return_type, Instance) + if 'b' in mode: + arg = named_generic_type('builtins.bytes', []) + else: + arg = named_generic_type('builtins.str', []) + return Instance(inferred_return_type.type, [arg]) + return inferred_return_type + + +def contextmanager_callback( + arg_types: List[List[Type]], + args: List[List[Expression]], + inferred_return_type: Type, + named_generic_type: Callable[[str, List[Type]], Type]) -> Type: + """Infer a better return type for 'contextlib.contextmanager'.""" + # Be defensive, just in case. + if arg_types and len(arg_types[0]) == 1: + arg_type = arg_types[0][0] + if isinstance(arg_type, CallableType) and isinstance(inferred_return_type, CallableType): + # The stub signature doesn't preserve information about arguments so + # add them back here. + return inferred_return_type.copy_modified( + arg_types=arg_type.arg_types, + arg_kinds=arg_type.arg_kinds, + arg_names=arg_type.arg_names) + return inferred_return_type diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 92b9906f9b53..be05dafe20c8 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -399,7 +399,33 @@ f.write('x') f.write(b'x') f.foobar() [out] -_program.py:4: error: IO[Any] has no attribute "foobar" +_program.py:3: error: Argument 1 to "write" of "IO" has incompatible type "bytes"; expected "str" +_program.py:4: error: IO[str] has no attribute "foobar" + +[case testOpenReturnTypeInference] +reveal_type(open('x')) +reveal_type(open('x', 'r')) +reveal_type(open('x', 'rb')) +mode = 'rb' +reveal_type(open('x', mode)) +[out] +_program.py:1: error: Revealed type is 'typing.IO[builtins.str]' +_program.py:2: error: Revealed type is 'typing.IO[builtins.str]' +_program.py:3: error: Revealed type is 'typing.IO[builtins.bytes]' +_program.py:5: error: Revealed type is 'typing.IO[Any]' + +[case testOpenReturnTypeInferenceSpecialCases] +reveal_type(open()) +reveal_type(open(mode='rb', file='x')) +reveal_type(open(file='x', mode='rb')) +mode = 'rb' +reveal_type(open(mode=mode, file='r')) +[out] +_testOpenReturnTypeInferenceSpecialCases.py:1: error: Revealed type is 'typing.IO[builtins.str]' +_testOpenReturnTypeInferenceSpecialCases.py:1: error: Too few arguments for "open" +_testOpenReturnTypeInferenceSpecialCases.py:2: error: Revealed type is 'typing.IO[builtins.bytes]' +_testOpenReturnTypeInferenceSpecialCases.py:3: error: Revealed type is 'typing.IO[builtins.bytes]' +_testOpenReturnTypeInferenceSpecialCases.py:5: error: Revealed type is 'typing.IO[Any]' [case testGenericPatterns] from typing import Pattern @@ -1286,3 +1312,27 @@ a[1] = 2, 'y' a[:] = [('z', 3)] [out] _program.py:4: error: Incompatible types in assignment (expression has type "Tuple[int, str]", target has type "Tuple[str, int]") + +[case testContextManager] +import contextlib +from contextlib import contextmanager +from typing import Iterator + +@contextmanager +def f(x: int) -> Iterator[str]: + yield 'foo' + +@contextlib.contextmanager +def g(*x: str) -> Iterator[int]: + yield 1 + +reveal_type(f) +reveal_type(g) + +with f('') as s: + reveal_type(s) +[out] +_program.py:13: error: Revealed type is 'def (x: builtins.int) -> contextlib.GeneratorContextManager[builtins.str*]' +_program.py:14: error: Revealed type is 'def (*x: builtins.str) -> contextlib.GeneratorContextManager[builtins.int*]' +_program.py:16: error: Argument 1 to "f" has incompatible type "str"; expected "int" +_program.py:17: error: Revealed type is 'builtins.str*' From 443c479f2a46967c50d63776a7203c120a26d8d0 Mon Sep 17 00:00:00 2001 From: David Fisher Date: Fri, 26 May 2017 07:47:26 -0700 Subject: [PATCH 11/27] Add flag to avoid interpreting arguments with a default of None as Optional (#3248) See python/typing#275. --- docs/source/config_file.rst | 2 ++ mypy/fastparse.py | 54 +++++++++++++----------------- mypy/fastparse2.py | 37 +++++++------------- mypy/main.py | 2 ++ mypy/options.py | 4 +++ mypy/parse.py | 6 ++-- test-data/unit/check-optional.test | 18 +++++----- 7 files changed, 53 insertions(+), 70 deletions(-) diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index 7e04286d6cd3..6fe139b1bb8c 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -178,6 +178,8 @@ overridden by the pattern sections matching the module name. - ``strict_boolean`` (Boolean, default False) makes using non-boolean expressions in conditions an error. +- ``no_implicit_optional`` (Boolean, default false) changes the treatment of + arguments with a default value of None by not implicitly making their type Optional Example ******* diff --git a/mypy/fastparse.py b/mypy/fastparse.py index bbf20c14be16..1d6dec891dd9 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -30,6 +30,7 @@ from mypy import experiments from mypy import messages from mypy.errors import Errors +from mypy.options import Options try: from typed_ast import ast3 @@ -60,14 +61,12 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None, - pyversion: Tuple[int, int] = defaults.PYTHON3_VERSION, - custom_typing_module: str = None) -> MypyFile: + options: Options = Options()) -> MypyFile: + """Parse a source file, without doing any semantic analysis. Return the parse tree. If errors is not provided, raise ParseError on failure. Otherwise, use the errors object to report parse errors. - - The pyversion (major, minor) argument determines the Python syntax variant. """ raise_on_error = False if errors is None: @@ -76,14 +75,16 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None, errors.set_file('' if fnam is None else fnam, None) is_stub_file = bool(fnam) and fnam.endswith('.pyi') try: - assert pyversion[0] >= 3 or is_stub_file - feature_version = pyversion[1] if not is_stub_file else defaults.PYTHON3_VERSION[1] + if is_stub_file: + feature_version = defaults.PYTHON3_VERSION[1] + else: + assert options.python_version[0] >= 3 + feature_version = options.python_version[1] ast = ast3.parse(source, fnam, 'exec', feature_version=feature_version) - tree = ASTConverter(pyversion=pyversion, + tree = ASTConverter(options=options, is_stub=is_stub_file, errors=errors, - custom_typing_module=custom_typing_module, ).visit(ast) tree.path = fnam tree.is_stub = is_stub_file @@ -138,17 +139,15 @@ def is_no_type_check_decorator(expr: ast3.expr) -> bool: class ASTConverter(ast3.NodeTransformer): # type: ignore # typeshed PR #931 def __init__(self, - pyversion: Tuple[int, int], + options: Options, is_stub: bool, - errors: Errors, - custom_typing_module: str = None) -> None: + errors: Errors) -> None: self.class_nesting = 0 self.imports = [] # type: List[ImportBase] - self.pyversion = pyversion + self.options = options self.is_stub = is_stub self.errors = errors - self.custom_typing_module = custom_typing_module def fail(self, msg: str, line: int, column: int) -> None: self.errors.report(line, column, msg) @@ -262,9 +261,9 @@ def translate_module_id(self, id: str) -> str: For example, translate '__builtin__' in Python 2 to 'builtins'. """ - if id == self.custom_typing_module: + if id == self.options.custom_typing_module: return 'typing' - elif id == '__builtin__' and self.pyversion[0] == 2: + elif id == '__builtin__' and self.options.python_version[0] == 2: # HACK: __builtin__ in Python 2 is aliases to builtins. However, the implementation # is named __builtin__.py (there is another layer of translation elsewhere). return 'builtins' @@ -391,7 +390,7 @@ def do_func_def(self, n: Union[ast3.FunctionDef, ast3.AsyncFunctionDef], return func_def def set_type_optional(self, type: Type, initializer: Expression) -> None: - if not experiments.STRICT_OPTIONAL: + if self.options.no_implicit_optional or not experiments.STRICT_OPTIONAL: return # Indicate that type should be wrapped in an Optional if arg is initialized to None. optional = isinstance(initializer, NameExpr) and initializer.name == 'None' @@ -846,16 +845,13 @@ def visit_Num(self, n: ast3.Num) -> Union[IntExpr, FloatExpr, ComplexExpr]: # Str(string s) @with_line def visit_Str(self, n: ast3.Str) -> Union[UnicodeExpr, StrExpr]: - if self.pyversion[0] >= 3 or self.is_stub: - # Hack: assume all string literals in Python 2 stubs are normal - # strs (i.e. not unicode). All stubs are parsed with the Python 3 - # parser, which causes unprefixed string literals to be interpreted - # as unicode instead of bytes. This hack is generally okay, - # because mypy considers str literals to be compatible with - # unicode. - return StrExpr(n.s) - else: - return UnicodeExpr(n.s) + # Hack: assume all string literals in Python 2 stubs are normal + # strs (i.e. not unicode). All stubs are parsed with the Python 3 + # parser, which causes unprefixed string literals to be interpreted + # as unicode instead of bytes. This hack is generally okay, + # because mypy considers str literals to be compatible with + # unicode. + return StrExpr(n.s) # Only available with typed_ast >= 0.6.2 if hasattr(ast3, 'JoinedStr'): @@ -885,11 +881,7 @@ def visit_Bytes(self, n: ast3.Bytes) -> Union[BytesExpr, StrExpr]: # The following line is a bit hacky, but is the best way to maintain # compatibility with how mypy currently parses the contents of bytes literals. contents = str(n.s)[2:-1] - - if self.pyversion[0] >= 3: - return BytesExpr(contents) - else: - return StrExpr(contents) + return BytesExpr(contents) # NameConstant(singleton value) def visit_NameConstant(self, n: ast3.NameConstant) -> NameExpr: diff --git a/mypy/fastparse2.py b/mypy/fastparse2.py index b7d5e9d400db..109dfe407cf2 100644 --- a/mypy/fastparse2.py +++ b/mypy/fastparse2.py @@ -38,11 +38,11 @@ from mypy.types import ( Type, CallableType, AnyType, UnboundType, EllipsisType ) -from mypy import defaults from mypy import experiments from mypy import messages from mypy.errors import Errors from mypy.fastparse import TypeConverter, parse_type_comment +from mypy.options import Options try: from typed_ast import ast27 @@ -74,14 +74,11 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None, - pyversion: Tuple[int, int] = defaults.PYTHON3_VERSION, - custom_typing_module: str = None) -> MypyFile: + options: Options = Options()) -> MypyFile: """Parse a source file, without doing any semantic analysis. Return the parse tree. If errors is not provided, raise ParseError on failure. Otherwise, use the errors object to report parse errors. - - The pyversion (major, minor) argument determines the Python syntax variant. """ raise_on_error = False if errors is None: @@ -90,12 +87,11 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None, errors.set_file('' if fnam is None else fnam, None) is_stub_file = bool(fnam) and fnam.endswith('.pyi') try: - assert pyversion[0] < 3 and not is_stub_file + assert options.python_version[0] < 3 and not is_stub_file ast = ast27.parse(source, fnam, 'exec') - tree = ASTConverter(pyversion=pyversion, + tree = ASTConverter(options=options, is_stub=is_stub_file, errors=errors, - custom_typing_module=custom_typing_module, ).visit(ast) assert isinstance(tree, MypyFile) tree.path = fnam @@ -137,17 +133,15 @@ def is_no_type_check_decorator(expr: ast27.expr) -> bool: class ASTConverter(ast27.NodeTransformer): def __init__(self, - pyversion: Tuple[int, int], + options: Options, is_stub: bool, - errors: Errors, - custom_typing_module: str = None) -> None: + errors: Errors) -> None: self.class_nesting = 0 self.imports = [] # type: List[ImportBase] - self.pyversion = pyversion + self.options = options self.is_stub = is_stub self.errors = errors - self.custom_typing_module = custom_typing_module def fail(self, msg: str, line: int, column: int) -> None: self.errors.report(line, column, msg) @@ -262,9 +256,9 @@ def translate_module_id(self, id: str) -> str: For example, translate '__builtin__' in Python 2 to 'builtins'. """ - if id == self.custom_typing_module: + if id == self.options.custom_typing_module: return 'typing' - elif id == '__builtin__' and self.pyversion[0] == 2: + elif id == '__builtin__': # HACK: __builtin__ in Python 2 is aliases to builtins. However, the implementation # is named __builtin__.py (there is another layer of translation elsewhere). return 'builtins' @@ -370,7 +364,7 @@ def visit_FunctionDef(self, n: ast27.FunctionDef) -> Statement: return func_def def set_type_optional(self, type: Type, initializer: Expression) -> None: - if not experiments.STRICT_OPTIONAL: + if self.options.no_implicit_optional or not experiments.STRICT_OPTIONAL: return # Indicate that type should be wrapped in an Optional if arg is initialized to None. optional = isinstance(initializer, NameExpr) and initializer.name == 'None' @@ -870,16 +864,9 @@ def visit_Str(self, s: ast27.Str) -> Expression: # The following line is a bit hacky, but is the best way to maintain # compatibility with how mypy currently parses the contents of bytes literals. contents = str(n)[2:-1] - - if self.pyversion[0] >= 3: - return BytesExpr(contents) - else: - return StrExpr(contents) + return StrExpr(contents) else: - if self.pyversion[0] >= 3 or self.is_stub: - return StrExpr(s.s) - else: - return UnicodeExpr(s.s) + return UnicodeExpr(s.s) # Ellipsis def visit_Ellipsis(self, n: ast27.Ellipsis) -> EllipsisExpr: diff --git a/mypy/main.py b/mypy/main.py index a5511671c966..d11dd64a6b14 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -247,6 +247,8 @@ def add_invertible_flag(flag: str, add_invertible_flag('--show-error-context', default=False, dest='show_error_context', help='Precede errors with "note:" messages explaining context') + add_invertible_flag('--no-implicit-optional', default=False, strict_flag=True, + help="don't assume arguments with default values of None are Optional") parser.add_argument('-i', '--incremental', action='store_true', help="enable module cache") parser.add_argument('--quick-and-dirty', action='store_true', diff --git a/mypy/options.py b/mypy/options.py index 8c8764200800..5e841bee0c6e 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -29,6 +29,7 @@ class Options: "warn_return_any", "ignore_errors", "strict_boolean", + "no_implicit_optional", } OPTIONS_AFFECTING_CACHE = PER_MODULE_OPTIONS | {"strict_optional", "quick_and_dirty"} @@ -92,6 +93,9 @@ def __init__(self) -> None: # Alternate way to show/hide strict-None-checking related errors self.show_none_errors = True + # Don't assume arguments with default values of None are Optional + self.no_implicit_optional = False + # Use script name instead of __main__ self.scripts_are_modules = False diff --git a/mypy/parse.py b/mypy/parse.py index 13fd58be3f60..2e02269f5e46 100644 --- a/mypy/parse.py +++ b/mypy/parse.py @@ -22,12 +22,10 @@ def parse(source: Union[str, bytes], return mypy.fastparse.parse(source, fnam=fnam, errors=errors, - pyversion=options.python_version, - custom_typing_module=options.custom_typing_module) + options=options) else: import mypy.fastparse2 return mypy.fastparse2.parse(source, fnam=fnam, errors=errors, - pyversion=options.python_version, - custom_typing_module=options.custom_typing_module) + options=options) diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index 6ae6df914376..3cde2f99a1fb 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -125,11 +125,10 @@ def f(x: int = None) -> None: f(None) [out] -[case testInferOptionalFromDefaultNoneWithFastParser] - -def f(x: int = None) -> None: - x + 1 # E: Unsupported left operand type for + (some union) -f(None) +[case testNoInferOptionalFromDefaultNone] +# flags: --no-implicit-optional +def f(x: int = None) -> None: # E: Incompatible types in assignment (expression has type None, variable has type "int") + pass [out] [case testInferOptionalFromDefaultNoneComment] @@ -139,12 +138,11 @@ def f(x=None): f(None) [out] -[case testInferOptionalFromDefaultNoneCommentWithFastParser] - -def f(x=None): +[case testNoInferOptionalFromDefaultNoneComment] +# flags: --no-implicit-optional +def f(x=None): # E: Incompatible types in assignment (expression has type None, variable has type "int") # type: (int) -> None - x + 1 # E: Unsupported left operand type for + (some union) -f(None) + pass [out] [case testInferOptionalType] From 577dd99ce47df963f9c0fd8deadcdef32194fe15 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Fri, 26 May 2017 18:09:18 +0100 Subject: [PATCH 12/27] Add mypy roadmap (#3460) --- ROADMAP.md | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 ROADMAP.md diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 000000000000..e40cea8d83b7 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,94 @@ +# Mypy Roadmap + +The goal of the roadmap is to document areas the mypy core team is +planning to work on in the future or is currently working on. PRs +targeting these areas are very welcome, but please check first with a +core team member that nobody else is working on the same thing. + +**Note:** This doesn’t include everything that the core team will work +on, and everything is subject to change. Near-term plans are likely +more accurate. + +## April-June 2017 + +- Add more comprehensive testing for `--incremental` and `--quick` + modes to improve reliability. At least write more unit tests with + focus on areas that have previously had bugs. + ([issue](https://github.com/python/mypy/issues/3455)) + +- Speed up `--quick` mode to better support million+ line codebases + through some of these: + + - Make it possible to use remote caching for incremental cache + files. This would speed up a cold run with no local cache data. + We need to update incremental cache to use hashes to determine + whether files have changes to allow + [sharing cache data](https://github.com/python/mypy/issues/3403). + + - See if we can speed up deserialization of incremental cache + files. Initial experiments aren’t very promising though so there + might not be any easy wins left. + ([issue](https://github.com/python/mypy/issues/3456)) + +- Improve support for complex signatures such as `open(fn, 'rb')` and + specific complex decorators such as `contextlib.contextmanager` + through type checker plugins/hooks. + ([issue](https://github.com/python/mypy/issues/1240)) + +- Document basic properties of all type operations used within mypy, + including compatibility, proper subtyping, joins and meets. + ([issue](https://github.com/python/mypy/issues/3454)) + +- Make TypedDict an officially supported mypy feature. This makes it + possible to give precise types for dictionaries that represent JSON + objects, such as `{"path": "/dir/fnam.ext", "size": 1234}`. + ([issue](https://github.com/python/mypy/issues/3453)) + +- Make error messages more useful and informative. + ([issue](https://github.com/python/mypy/labels/topic-usability)) + +- Resolve [#2008](https://github.com/python/mypy/issues/2008) (we are + converging on approach 4). + +## July-December 2017 + +- Invest some effort into systematically filling in missing + annotations and stubs in typeshed, with focus on features heavily + used at Dropbox. Better support for ORMs will be a separate + project. + +- Improve opt-in warnings about `Any` types to make it easier to keep + code free from unwanted `Any` types. For example, warn about using + `list` (instead of `List[x]`) and calling `open` if we can’t infer a + precise return type, or using types imported from ignored modules + (they are implicitly `Any`). + +- Add support for protocols and structural subtyping (PEP 544). + +- Switch completely to pytest and remove the custom testing framework. + ([issue](https://github.com/python/mypy/issues/1673)) + +- Make it possible to run mypy as a daemon to avoid reprocessing the + entire program on each run. This will improve performance + significantly. Even when using the incremental mode, processing a + large number of files is not cheap. + +- Refactor and simplify specific tricky parts of mypy internals, such + as the [conditional type binder](https://github.com/python/mypy/issues/3457), + [symbol tables](https://github.com/python/mypy/issues/3458) or + the various [semantic analysis passes](https://github.com/python/mypy/issues/3459). + +- Implement a general type system plugin architecture. It should be + able to support some typical ORM features at least, such as + metaclasses that add methods with automatically inferred signatures + and complex descriptors such as those used by Django models. + ([issue](https://github.com/python/mypy/issues/1240)) + +- Add support for statically typed + [protobufs](https://developers.google.com/protocol-buffers/). + +- Provide much faster, reliable interactive feedback through + fine-grained incremental type checking, built on top the daemon + mode. + +- Start work on editor plugins and support for selected IDE features. From 3ba42e86dc099c334b3e9b475a9d13d0b324ea23 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 26 May 2017 11:29:40 -0700 Subject: [PATCH 13/27] Print pytest output as it happens (#3463) Fix #3393 This results in pytest output being shown as a passthrough at the beginning of runtests.py. --- mypy/waiter.py | 10 ++++++++-- runtests.py | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/mypy/waiter.py b/mypy/waiter.py index 0f1759fefab8..f0c7de6002a6 100644 --- a/mypy/waiter.py +++ b/mypy/waiter.py @@ -25,16 +25,20 @@ class LazySubprocess: """Wrapper around a subprocess that runs a test task.""" def __init__(self, name: str, args: List[str], *, cwd: str = None, - env: Dict[str, str] = None) -> None: + env: Dict[str, str] = None, passthrough: bool = False) -> None: self.name = name self.args = args self.cwd = cwd self.env = env self.start_time = None # type: float self.end_time = None # type: float + self.passthrough = passthrough def start(self) -> None: - self.outfile = tempfile.TemporaryFile() + if self.passthrough: + self.outfile = None + else: + self.outfile = tempfile.TemporaryFile() self.start_time = time.perf_counter() self.process = Popen(self.args, cwd=self.cwd, env=self.env, stdout=self.outfile, stderr=STDOUT) @@ -47,6 +51,8 @@ def status(self) -> Optional[int]: return self.process.returncode def read_output(self) -> str: + if self.passthrough: + return '' file = self.outfile file.seek(0) # Assume it's ascii to avoid unicode headaches (and portability issues). diff --git a/runtests.py b/runtests.py index 83a6ffa0d3da..3371f9ae8b91 100755 --- a/runtests.py +++ b/runtests.py @@ -111,7 +111,8 @@ def add_pytest(self, name: str, pytest_args: List[str], coverage: bool = False) else: args = [sys.executable, '-m', 'pytest'] + pytest_args - self.waiter.add(LazySubprocess(full_name, args, env=self.env), sequential=True) + self.waiter.add(LazySubprocess(full_name, args, env=self.env, passthrough=True), + sequential=True) def add_python(self, name: str, *args: str, cwd: Optional[str] = None) -> None: name = 'run %s' % name From 278a10a3229ed5d33968291f65465c136220447d Mon Sep 17 00:00:00 2001 From: Svyatoslav Ilinskiy Date: Fri, 26 May 2017 12:07:08 -0700 Subject: [PATCH 14/27] Fix last character cut in html-report if file does not end with newline (#3466) --- mypy/report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/report.py b/mypy/report.py index 74b44ac1f995..157aa1caab6f 100644 --- a/mypy/report.py +++ b/mypy/report.py @@ -334,7 +334,7 @@ def on_file(self, etree.SubElement(root, 'line', number=str(lineno), precision=stats.precision_names[status], - content=line_text[:-1]) + content=line_text.rstrip('\n')) # Assumes a layout similar to what XmlReporter uses. xslt_path = os.path.relpath('mypy-html.xslt', path) transform_pi = etree.ProcessingInstruction('xml-stylesheet', From 4d61418ac6ee753a88815322f27dd7515f6ea574 Mon Sep 17 00:00:00 2001 From: chernrick Date: Fri, 26 May 2017 13:35:21 -0700 Subject: [PATCH 15/27] Better error message for invalid package names passed to mypy (#3447) Fixes #2775 --- mypy/main.py | 18 ++++++++++++++++-- test-data/unit/cmdline.test | 8 ++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/mypy/main.py b/mypy/main.py index d11dd64a6b14..f73cbeb99972 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -24,6 +24,10 @@ PY_EXTENSIONS = tuple(PYTHON_EXTENSIONS) +class InvalidPackageName(Exception): + """Exception indicating that a package name was invalid.""" + + def main(script_path: str, args: List[str] = None) -> None: """Main entry point to the type checker. @@ -459,9 +463,15 @@ def add_invertible_flag(flag: str, targets = [] for f in special_opts.files: if f.endswith(PY_EXTENSIONS): - targets.append(BuildSource(f, crawl_up(f)[1], None)) + try: + targets.append(BuildSource(f, crawl_up(f)[1], None)) + except InvalidPackageName as e: + fail(str(e)) elif os.path.isdir(f): - sub_targets = expand_dir(f) + try: + sub_targets = expand_dir(f) + except InvalidPackageName as e: + fail(str(e)) if not sub_targets: fail("There are no .py[i] files in directory '{}'" .format(f)) @@ -528,10 +538,14 @@ def crawl_up(arg: str) -> Tuple[str, str]: dir, base = os.path.split(dir) if not base: break + # Ensure that base is a valid python module name + if not base.isidentifier(): + raise InvalidPackageName('{} is not a valid Python package name'.format(base)) if mod == '__init__' or not mod: mod = base else: mod = base + '.' + mod + return dir, mod diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test index d0648844daaa..a9ba3c28950b 100644 --- a/test-data/unit/cmdline.test +++ b/test-data/unit/cmdline.test @@ -75,6 +75,14 @@ undef dir/subpkg/a.py:1: error: Name 'undef' is not defined dir/a.py:1: error: Name 'undef' is not defined +[case testCmdlineInvalidPackageName] +# cmd: mypy dir/sub.pkg/a.py +[file dir/sub.pkg/__init__.py] +[file dir/sub.pkg/a.py] +undef +[out] +sub.pkg is not a valid Python package name + [case testBadFileEncoding] # cmd: mypy a.py [file a.py] From c0f7bba54f3b39ce01e2cc708772c1cb4309bce3 Mon Sep 17 00:00:00 2001 From: Jesse Lord Date: Fri, 26 May 2017 15:37:04 -0700 Subject: [PATCH 16/27] Change label for variance section to just 'variance' (#3429) This will allow the links in #3411 to be shorter. --- docs/source/common_issues.rst | 2 +- docs/source/revision_history.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index 2501acd28fc0..d26b049daf51 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -180,7 +180,7 @@ not support ``sort()``) as a list and sort it in-place: # Type of x is List[int] here. x.sort() # Okay! -.. _invariance-vs-covariance: +.. _variance Invariance vs covariance ------------------------ diff --git a/docs/source/revision_history.rst b/docs/source/revision_history.rst index dd74dadd244e..98f6495dd188 100644 --- a/docs/source/revision_history.rst +++ b/docs/source/revision_history.rst @@ -31,7 +31,7 @@ List of major changes: * Add :ref:`variance-of-generics`. - * Add :ref:`invariance-vs-covariance`. + * Add :ref:`variance`. * Updates to :ref:`python-36`. From 99f372ef1c56d7d852693bc19ac3adcfe6ee88e2 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 26 May 2017 20:11:21 -0700 Subject: [PATCH 17/27] Fix 'variance' label. --- docs/source/common_issues.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index d26b049daf51..0c8b500d8f06 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -180,7 +180,7 @@ not support ``sort()``) as a list and sort it in-place: # Type of x is List[int] here. x.sort() # Okay! -.. _variance +.. _variance: Invariance vs covariance ------------------------ From 166d54daffb6288958f50146bfc8b35af19a6fbb Mon Sep 17 00:00:00 2001 From: Ethan Smith Date: Sat, 27 May 2017 16:38:36 -0700 Subject: [PATCH 18/27] Add console scripts (#3074) Use entry_points instead of custom scripts (but custom scripts remain in case they are still useful). --- mypy/__main__.py | 8 +++++++- scripts/stubgen | 0 setup.py | 6 ++---- 3 files changed, 9 insertions(+), 5 deletions(-) mode change 100755 => 100644 scripts/stubgen diff --git a/mypy/__main__.py b/mypy/__main__.py index 0a6f79261a53..625242d100be 100644 --- a/mypy/__main__.py +++ b/mypy/__main__.py @@ -2,4 +2,10 @@ from mypy.main import main -main(None) + +def console_entry() -> None: + main(None) + + +if __name__ == '__main__': + main(None) diff --git a/scripts/stubgen b/scripts/stubgen old mode 100755 new mode 100644 diff --git a/setup.py b/setup.py index 78c6a639ad0a..efc23f4a6fe4 100644 --- a/setup.py +++ b/setup.py @@ -94,9 +94,6 @@ def run(self): package_dir = {'mypy': 'mypy'} -scripts = ['scripts/mypy', 'scripts/stubgen'] -if os.name == 'nt': - scripts.append('scripts/mypy.bat') # These requirements are used when installing by other means than bdist_wheel. # E.g. "pip3 install ." or @@ -119,7 +116,8 @@ def run(self): package_dir=package_dir, py_modules=[], packages=['mypy'], - scripts=scripts, + entry_points={'console_scripts': ['mypy=mypy.__main__:console_entry', + 'stubgen=mypy.stubgen:main']}, data_files=data_files, classifiers=classifiers, cmdclass={'build_py': CustomPythonBuild}, From 8c989bf9eb1acf5a5c8f71521b15ad4d3c198cc7 Mon Sep 17 00:00:00 2001 From: Carl Meyer Date: Sun, 28 May 2017 11:55:35 -0700 Subject: [PATCH 19/27] Allow NewType subclassing NewType. (#3465) Use case: type hierarchy of IDs, all of which are integers at runtime, but we want to type-check distinctions between e.g. "id of User" and "id of Media", while still allowing some functions to take "any ID" (which is still a more specific type than "any integer"). --- mypy/semanal.py | 4 ---- test-data/unit/check-newtype.test | 32 ++++++++++++++++++++++--------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index d16be31e8e18..e930c3706191 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1822,10 +1822,6 @@ def check_newtype_args(self, name: str, call: CallExpr, context: Context) -> Opt return None old_type = self.anal_type(unanalyzed_type) - if isinstance(old_type, Instance) and old_type.type.is_newtype: - self.fail("Argument 2 to NewType(...) cannot be another NewType", context) - has_failed = True - return None if has_failed else old_type def build_newtype_typeinfo(self, name: str, old_type: Type, base_type: Instance) -> TypeInfo: diff --git a/test-data/unit/check-newtype.test b/test-data/unit/check-newtype.test index 144c8fba04c3..32b25558c84f 100644 --- a/test-data/unit/check-newtype.test +++ b/test-data/unit/check-newtype.test @@ -155,6 +155,29 @@ y = Bar2(42) y = func3(x) [out] +[case testNewTypeWithNewType] +from typing import NewType +A = NewType('A', int) +B = NewType('B', A) +C = A +D = C +E = NewType('E', D) + +a = A(1) +b = B(a) +e = E(a) + +def funca(a: A) -> None: ... +def funcb(b: B) -> None: ... + +funca(a) +funca(b) +funca(e) +funcb(a) # E: Argument 1 to "funcb" has incompatible type "A"; expected "B" +funcb(b) +funcb(e) # E: Argument 1 to "funcb" has incompatible type "E"; expected "B" + +[out] -- Make sure NewType works as expected in a variety of different scopes/across files @@ -279,15 +302,6 @@ main:3: error: Argument 2 to NewType(...) must be subclassable (got T?) main:3: error: Invalid type "__main__.T" main:4: error: Invalid type "__main__.T" -[case testNewTypeWithNewTypeFails] -from typing import NewType -A = NewType('A', int) -B = NewType('B', A) # E: Argument 2 to NewType(...) cannot be another NewType -C = A -D = C -E = NewType('E', D) # E: Argument 2 to NewType(...) cannot be another NewType -[out] - [case testNewTypeRedefiningVariablesFails] from typing import NewType From 9ec8a951c6c271a07aad102ab8a5af3b0b3fec06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Miedzi=C5=84ski?= Date: Mon, 29 May 2017 04:59:54 +0200 Subject: [PATCH 20/27] Fix None slice bounds with strict-optional (#3445) Fixes #3442. --- mypy/checkexpr.py | 4 +++- test-data/unit/check-expressions.test | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 016668b46105..4829b99231cd 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -45,6 +45,7 @@ from mypy.typevars import fill_typevars from mypy.visitor import ExpressionVisitor from mypy.funcplugins import get_function_plugin_callbacks, PluginCallback +from mypy.typeanal import make_optional_type from mypy import experiments @@ -1928,10 +1929,11 @@ def analyze_super(self, e: SuperExpr, is_lvalue: bool) -> Type: return AnyType() def visit_slice_expr(self, e: SliceExpr) -> Type: + expected = make_optional_type(self.named_type('builtins.int')) for index in [e.begin_index, e.end_index, e.stride]: if index: t = self.accept(index) - self.chk.check_subtype(t, self.named_type('builtins.int'), + self.chk.check_subtype(t, expected, index, messages.INVALID_SLICE_INDEX) return self.named_type('builtins.slice') diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index 1d840269da42..ae1498acdadd 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -1006,6 +1006,16 @@ a[None:] a[:None] [builtins fixtures/slice.pyi] +[case testNoneSliceBoundsWithStrictOptional] +# flags: --strict-optional +from typing import Any +a = None # type: Any +a[None:1] +a[1:None] +a[None:] +a[:None] +[builtins fixtures/slice.pyi] + -- String interpolation -- -------------------- From e1fcab8143bfd4bc6e28f47d590493cfc766d63c Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sun, 28 May 2017 20:17:26 -0700 Subject: [PATCH 21/27] Move version of extensions to post-release (#3348) --- extensions/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/setup.py b/extensions/setup.py index 32741a0b67b6..59d634debc3f 100644 --- a/extensions/setup.py +++ b/extensions/setup.py @@ -4,7 +4,7 @@ from distutils.core import setup -version = '0.2.0' +version = '0.3.0-dev' description = 'Experimental type system extensions for programs checked with the mypy typechecker.' long_description = ''' Mypy Extensions From d238ab504d1d6bd6ec6c53aeaebb4d03673fcf60 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 28 May 2017 20:20:10 -0700 Subject: [PATCH 22/27] Remove bundled lib-typing (#3337) This gets rid of code duplication and makes sure mypy works with the released version of `typing`. This doesn't fix any immediate issue, but I saw some comments in the bug tracker saying that we should be able to get rid of `lib-typing` eventually. There is a minor downside: To run mypy tests locally, you will now have to have a Python 2.7 installed that has `typing` available. --- .travis.yml | 1 + LICENSE | 3 +- lib-typing/2.7/mod_generics_cache.py | 14 - lib-typing/2.7/setup.py | 46 - lib-typing/2.7/test_typing.py | 1828 ------------------- lib-typing/2.7/typing.py | 2140 ----------------------- lib-typing/3.2/mod_generics_cache.py | 14 - lib-typing/3.2/test_typing.py | 2422 -------------------------- lib-typing/3.2/typing.py | 2335 ------------------------- mypy/test/testpythoneval.py | 10 +- runtests.py | 39 +- setup.cfg | 2 - test-data/unit/README.md | 14 +- 13 files changed, 28 insertions(+), 8840 deletions(-) delete mode 100644 lib-typing/2.7/mod_generics_cache.py delete mode 100644 lib-typing/2.7/setup.py delete mode 100644 lib-typing/2.7/test_typing.py delete mode 100644 lib-typing/2.7/typing.py delete mode 100644 lib-typing/3.2/mod_generics_cache.py delete mode 100644 lib-typing/3.2/test_typing.py delete mode 100644 lib-typing/3.2/typing.py diff --git a/.travis.yml b/.travis.yml index 56804c71bf50..2dffdb283666 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ python: install: - pip install -r test-requirements.txt + - python2 -m pip install --user typing - python setup.py install script: diff --git a/LICENSE b/LICENSE index 8145cc386a7b..afddd48c889e 100644 --- a/LICENSE +++ b/LICENSE @@ -27,8 +27,7 @@ DEALINGS IN THE SOFTWARE. = = = = = Portions of mypy are licensed under different licenses. The files -under stdlib-samples and lib-typing are licensed under the PSF 2 -License, reproduced below. +under stdlib-samples are licensed under the PSF 2 License, reproduced below. = = = = = diff --git a/lib-typing/2.7/mod_generics_cache.py b/lib-typing/2.7/mod_generics_cache.py deleted file mode 100644 index d9a60b4b28c3..000000000000 --- a/lib-typing/2.7/mod_generics_cache.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Module for testing the behavior of generics across different modules.""" - -from typing import TypeVar, Generic - -T = TypeVar('T') - - -class A(Generic[T]): - pass - - -class B(Generic[T]): - class A(Generic[T]): - pass diff --git a/lib-typing/2.7/setup.py b/lib-typing/2.7/setup.py deleted file mode 100644 index 18c34d84be64..000000000000 --- a/lib-typing/2.7/setup.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python - -"""setup.py for Python 2.x typing module""" - -import glob -import os -import os.path -import sys - -from distutils.core import setup - -if sys.version_info >= (3, 0, 0): - sys.stderr.write("ERROR: You need Python 2.x to install this module.\n") - exit(1) - -version = '0.0.1.dev1' -description = 'typing (Python 2.x)' -long_description = ''' -typing (Python 2.x) -=================== - -This module is part of mypy, a static type checker for Python. -'''.lstrip() - -classifiers = [ - 'Development Status :: 2 - Pre-Alpha', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Operating System :: POSIX', - 'Programming Language :: Python :: 2.7', - 'Topic :: Software Development', -] - -setup(name='typing', - version=version, - description=description, - long_description=long_description, - author='Jukka Lehtosalo', - author_email='jukka.lehtosalo@iki.fi', - url='http://www.mypy-lang.org/', - license='MIT License', - platforms=['POSIX'], - py_modules=['typing'], - classifiers=classifiers, - ) diff --git a/lib-typing/2.7/test_typing.py b/lib-typing/2.7/test_typing.py deleted file mode 100644 index 2ea954fe30f4..000000000000 --- a/lib-typing/2.7/test_typing.py +++ /dev/null @@ -1,1828 +0,0 @@ -from __future__ import absolute_import, unicode_literals - -import collections -import pickle -import re -import sys -from unittest import TestCase, main, SkipTest -from copy import copy, deepcopy - -from typing import Any -from typing import TypeVar, AnyStr -from typing import T, KT, VT # Not in __all__. -from typing import Union, Optional -from typing import Tuple, List, MutableMapping -from typing import Callable -from typing import Generic, ClassVar, GenericMeta -from typing import cast -from typing import Type -from typing import NewType -from typing import NamedTuple -from typing import Pattern, Match -import typing -import weakref -try: - import collections.abc as collections_abc -except ImportError: - import collections as collections_abc # Fallback for PY3.2. - - -class BaseTestCase(TestCase): - - def assertIsSubclass(self, cls, class_or_tuple, msg=None): - if not issubclass(cls, class_or_tuple): - message = '%r is not a subclass of %r' % (cls, class_or_tuple) - if msg is not None: - message += ' : %s' % msg - raise self.failureException(message) - - def assertNotIsSubclass(self, cls, class_or_tuple, msg=None): - if issubclass(cls, class_or_tuple): - message = '%r is a subclass of %r' % (cls, class_or_tuple) - if msg is not None: - message += ' : %s' % msg - raise self.failureException(message) - - def clear_caches(self): - for f in typing._cleanups: - f() - - -class Employee(object): - pass - - -class Manager(Employee): - pass - - -class Founder(Employee): - pass - - -class ManagingFounder(Manager, Founder): - pass - - -class AnyTests(BaseTestCase): - - def test_any_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance(42, Any) - - def test_any_subclass_type_error(self): - with self.assertRaises(TypeError): - issubclass(Employee, Any) - with self.assertRaises(TypeError): - issubclass(Any, Employee) - - def test_repr(self): - self.assertEqual(repr(Any), 'typing.Any') - - def test_errors(self): - with self.assertRaises(TypeError): - issubclass(42, Any) - with self.assertRaises(TypeError): - Any[int] # Any is not a generic type. - - def test_cannot_subclass(self): - with self.assertRaises(TypeError): - class A(Any): - pass - with self.assertRaises(TypeError): - class A(type(Any)): - pass - - def test_cannot_instantiate(self): - with self.assertRaises(TypeError): - Any() - with self.assertRaises(TypeError): - type(Any)() - - def test_any_is_subclass(self): - # These expressions must simply not fail. - typing.Match[Any] - typing.Pattern[Any] - typing.IO[Any] - - -class TypeVarTests(BaseTestCase): - - def test_basic_plain(self): - T = TypeVar('T') - # T equals itself. - self.assertEqual(T, T) - # T is an instance of TypeVar - self.assertIsInstance(T, TypeVar) - - def test_typevar_instance_type_error(self): - T = TypeVar('T') - with self.assertRaises(TypeError): - isinstance(42, T) - - def test_typevar_subclass_type_error(self): - T = TypeVar('T') - with self.assertRaises(TypeError): - issubclass(int, T) - with self.assertRaises(TypeError): - issubclass(T, int) - - def test_constrained_error(self): - with self.assertRaises(TypeError): - X = TypeVar('X', int) - X - - def test_union_unique(self): - X = TypeVar('X') - Y = TypeVar('Y') - self.assertNotEqual(X, Y) - self.assertEqual(Union[X], X) - self.assertNotEqual(Union[X], Union[X, Y]) - self.assertEqual(Union[X, X], X) - self.assertNotEqual(Union[X, int], Union[X]) - self.assertNotEqual(Union[X, int], Union[int]) - self.assertEqual(Union[X, int].__args__, (X, int)) - self.assertEqual(Union[X, int].__parameters__, (X,)) - self.assertIs(Union[X, int].__origin__, Union) - - def test_union_constrained(self): - A = TypeVar('A', str, bytes) - self.assertNotEqual(Union[A, str], Union[A]) - - def test_repr(self): - self.assertEqual(repr(T), '~T') - self.assertEqual(repr(KT), '~KT') - self.assertEqual(repr(VT), '~VT') - self.assertEqual(repr(AnyStr), '~AnyStr') - T_co = TypeVar('T_co', covariant=True) - self.assertEqual(repr(T_co), '+T_co') - T_contra = TypeVar('T_contra', contravariant=True) - self.assertEqual(repr(T_contra), '-T_contra') - - def test_no_redefinition(self): - self.assertNotEqual(TypeVar('T'), TypeVar('T')) - self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str)) - - def test_cannot_subclass_vars(self): - with self.assertRaises(TypeError): - class V(TypeVar('T')): - pass - - def test_cannot_subclass_var_itself(self): - with self.assertRaises(TypeError): - class V(TypeVar): - pass - - def test_cannot_instantiate_vars(self): - with self.assertRaises(TypeError): - TypeVar('A')() - - def test_bound_errors(self): - with self.assertRaises(TypeError): - TypeVar('X', bound=42) - with self.assertRaises(TypeError): - TypeVar('X', str, float, bound=Employee) - - def test_no_bivariant(self): - with self.assertRaises(ValueError): - TypeVar('T', covariant=True, contravariant=True) - - -class UnionTests(BaseTestCase): - - def test_basics(self): - u = Union[int, float] - self.assertNotEqual(u, Union) - - def test_subclass_error(self): - with self.assertRaises(TypeError): - issubclass(int, Union) - with self.assertRaises(TypeError): - issubclass(Union, int) - with self.assertRaises(TypeError): - issubclass(int, Union[int, str]) - with self.assertRaises(TypeError): - issubclass(Union[int, str], int) - - def test_union_any(self): - u = Union[Any] - self.assertEqual(u, Any) - u1 = Union[int, Any] - u2 = Union[Any, int] - u3 = Union[Any, object] - self.assertEqual(u1, u2) - self.assertNotEqual(u1, Any) - self.assertNotEqual(u2, Any) - self.assertNotEqual(u3, Any) - - def test_union_object(self): - u = Union[object] - self.assertEqual(u, object) - u = Union[int, object] - self.assertEqual(u, object) - u = Union[object, int] - self.assertEqual(u, object) - - def test_unordered(self): - u1 = Union[int, float] - u2 = Union[float, int] - self.assertEqual(u1, u2) - - def test_single_class_disappears(self): - t = Union[Employee] - self.assertIs(t, Employee) - - def test_base_class_disappears(self): - u = Union[Employee, Manager, int] - self.assertEqual(u, Union[int, Employee]) - u = Union[Manager, int, Employee] - self.assertEqual(u, Union[int, Employee]) - u = Union[Employee, Manager] - self.assertIs(u, Employee) - - def test_union_union(self): - u = Union[int, float] - v = Union[u, Employee] - self.assertEqual(v, Union[int, float, Employee]) - - def test_repr(self): - self.assertEqual(repr(Union), 'typing.Union') - u = Union[Employee, int] - self.assertEqual(repr(u), 'typing.Union[%s.Employee, int]' % __name__) - u = Union[int, Employee] - self.assertEqual(repr(u), 'typing.Union[int, %s.Employee]' % __name__) - T = TypeVar('T') - u = Union[T, int][int] - self.assertEqual(repr(u), repr(int)) - u = Union[List[int], int] - self.assertEqual(repr(u), 'typing.Union[typing.List[int], int]') - - def test_cannot_subclass(self): - with self.assertRaises(TypeError): - class C(Union): - pass - with self.assertRaises(TypeError): - class C(type(Union)): - pass - with self.assertRaises(TypeError): - class C(Union[int, str]): - pass - - def test_cannot_instantiate(self): - with self.assertRaises(TypeError): - Union() - u = Union[int, float] - with self.assertRaises(TypeError): - u() - with self.assertRaises(TypeError): - type(u)() - - def test_union_generalization(self): - self.assertFalse(Union[str, typing.Iterable[int]] == str) - self.assertFalse(Union[str, typing.Iterable[int]] == typing.Iterable[int]) - self.assertTrue(Union[str, typing.Iterable] == typing.Iterable) - - def test_union_compare_other(self): - self.assertNotEqual(Union, object) - self.assertNotEqual(Union, Any) - self.assertNotEqual(ClassVar, Union) - self.assertNotEqual(Optional, Union) - self.assertNotEqual([None], Optional) - self.assertNotEqual(Optional, typing.Mapping) - self.assertNotEqual(Optional[typing.MutableMapping], Union) - - def test_optional(self): - o = Optional[int] - u = Union[int, None] - self.assertEqual(o, u) - - def test_empty(self): - with self.assertRaises(TypeError): - Union[()] - - def test_union_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance(42, Union[int, str]) - - def test_no_eval_union(self): - u = Union[int, str] - self.assertIs(u._eval_type({}, {}), u) - - def test_function_repr_union(self): - def fun(): pass - self.assertEqual(repr(Union[fun, int]), 'typing.Union[fun, int]') - - def test_union_str_pattern(self): - # Shouldn't crash; see http://bugs.python.org/issue25390 - A = Union[str, Pattern] - A - - def test_etree(self): - # See https://github.com/python/typing/issues/229 - # (Only relevant for Python 2.) - try: - from xml.etree.cElementTree import Element - except ImportError: - raise SkipTest("cElementTree not found") - Union[Element, str] # Shouldn't crash - - def Elem(*args): - return Element(*args) - - Union[Elem, str] # Nor should this - - -class TupleTests(BaseTestCase): - - def test_basics(self): - with self.assertRaises(TypeError): - issubclass(Tuple, Tuple[int, str]) - with self.assertRaises(TypeError): - issubclass(tuple, Tuple[int, str]) - - class TP(tuple): pass - self.assertTrue(issubclass(tuple, Tuple)) - self.assertTrue(issubclass(TP, Tuple)) - - def test_equality(self): - self.assertEqual(Tuple[int], Tuple[int]) - self.assertEqual(Tuple[int, ...], Tuple[int, ...]) - self.assertNotEqual(Tuple[int], Tuple[int, int]) - self.assertNotEqual(Tuple[int], Tuple[int, ...]) - - def test_tuple_subclass(self): - class MyTuple(tuple): - pass - self.assertTrue(issubclass(MyTuple, Tuple)) - - def test_tuple_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance((0, 0), Tuple[int, int]) - isinstance((0, 0), Tuple) - - def test_repr(self): - self.assertEqual(repr(Tuple), 'typing.Tuple') - self.assertEqual(repr(Tuple[()]), 'typing.Tuple[()]') - self.assertEqual(repr(Tuple[int, float]), 'typing.Tuple[int, float]') - self.assertEqual(repr(Tuple[int, ...]), 'typing.Tuple[int, ...]') - - def test_errors(self): - with self.assertRaises(TypeError): - issubclass(42, Tuple) - with self.assertRaises(TypeError): - issubclass(42, Tuple[int]) - - -class CallableTests(BaseTestCase): - - def test_self_subclass(self): - with self.assertRaises(TypeError): - self.assertTrue(issubclass(type(lambda x: x), Callable[[int], int])) - self.assertTrue(issubclass(type(lambda x: x), Callable)) - - def test_eq_hash(self): - self.assertEqual(Callable[[int], int], Callable[[int], int]) - self.assertEqual(len({Callable[[int], int], Callable[[int], int]}), 1) - self.assertNotEqual(Callable[[int], int], Callable[[int], str]) - self.assertNotEqual(Callable[[int], int], Callable[[str], int]) - self.assertNotEqual(Callable[[int], int], Callable[[int, int], int]) - self.assertNotEqual(Callable[[int], int], Callable[[], int]) - self.assertNotEqual(Callable[[int], int], Callable) - - def test_cannot_instantiate(self): - with self.assertRaises(TypeError): - Callable() - with self.assertRaises(TypeError): - type(Callable)() - c = Callable[[int], str] - with self.assertRaises(TypeError): - c() - with self.assertRaises(TypeError): - type(c)() - - def test_callable_wrong_forms(self): - with self.assertRaises(TypeError): - Callable[(), int] - with self.assertRaises(TypeError): - Callable[[()], int] - with self.assertRaises(TypeError): - Callable[[int, 1], 2] - with self.assertRaises(TypeError): - Callable[int] - - def test_callable_instance_works(self): - def f(): - pass - self.assertIsInstance(f, Callable) - self.assertNotIsInstance(None, Callable) - - def test_callable_instance_type_error(self): - def f(): - pass - with self.assertRaises(TypeError): - self.assertIsInstance(f, Callable[[], None]) - with self.assertRaises(TypeError): - self.assertIsInstance(f, Callable[[], Any]) - with self.assertRaises(TypeError): - self.assertNotIsInstance(None, Callable[[], None]) - with self.assertRaises(TypeError): - self.assertNotIsInstance(None, Callable[[], Any]) - - def test_repr(self): - ct0 = Callable[[], bool] - self.assertEqual(repr(ct0), 'typing.Callable[[], bool]') - ct2 = Callable[[str, float], int] - self.assertEqual(repr(ct2), 'typing.Callable[[str, float], int]') - ctv = Callable[..., str] - self.assertEqual(repr(ctv), 'typing.Callable[..., str]') - - def test_ellipsis_in_generic(self): - # Shouldn't crash; see https://github.com/python/typing/issues/259 - typing.List[Callable[..., str]] - - -XK = TypeVar('XK', unicode, bytes) -XV = TypeVar('XV') - - -class SimpleMapping(Generic[XK, XV]): - - def __getitem__(self, key): - pass - - def __setitem__(self, key, value): - pass - - def get(self, key, default=None): - pass - - -class MySimpleMapping(SimpleMapping[XK, XV]): - - def __init__(self): - self.store = {} - - def __getitem__(self, key): - return self.store[key] - - def __setitem__(self, key, value): - self.store[key] = value - - def get(self, key, default=None): - try: - return self.store[key] - except KeyError: - return default - - -class ProtocolTests(BaseTestCase): - - def test_supports_int(self): - self.assertIsSubclass(int, typing.SupportsInt) - self.assertNotIsSubclass(str, typing.SupportsInt) - - def test_supports_float(self): - self.assertIsSubclass(float, typing.SupportsFloat) - self.assertNotIsSubclass(str, typing.SupportsFloat) - - def test_supports_complex(self): - - # Note: complex itself doesn't have __complex__. - class C(object): - def __complex__(self): - return 0j - - self.assertIsSubclass(C, typing.SupportsComplex) - self.assertNotIsSubclass(str, typing.SupportsComplex) - - def test_supports_abs(self): - self.assertIsSubclass(float, typing.SupportsAbs) - self.assertIsSubclass(int, typing.SupportsAbs) - self.assertNotIsSubclass(str, typing.SupportsAbs) - - def test_reversible(self): - self.assertIsSubclass(list, typing.Reversible) - self.assertNotIsSubclass(int, typing.Reversible) - - def test_protocol_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance(0, typing.SupportsAbs) - class C1(typing.SupportsInt): - def __int__(self): - return 42 - class C2(C1): - pass - c = C2() - self.assertIsInstance(c, C1) - - -class GenericTests(BaseTestCase): - - def test_basics(self): - X = SimpleMapping[str, Any] - self.assertEqual(X.__parameters__, ()) - with self.assertRaises(TypeError): - X[unicode] - with self.assertRaises(TypeError): - X[unicode, unicode] - Y = SimpleMapping[XK, unicode] - self.assertEqual(Y.__parameters__, (XK,)) - Y[unicode] - with self.assertRaises(TypeError): - Y[unicode, unicode] - self.assertIsSubclass(SimpleMapping[str, int], SimpleMapping) - - def test_generic_errors(self): - T = TypeVar('T') - S = TypeVar('S') - with self.assertRaises(TypeError): - Generic[T]() - with self.assertRaises(TypeError): - Generic[T][T] - with self.assertRaises(TypeError): - Generic[T][S] - with self.assertRaises(TypeError): - isinstance([], List[int]) - with self.assertRaises(TypeError): - issubclass(list, List[int]) - with self.assertRaises(TypeError): - class NewGeneric(Generic): pass - with self.assertRaises(TypeError): - class MyGeneric(Generic[T], Generic[S]): pass - with self.assertRaises(TypeError): - class MyGeneric(List[T], Generic[S]): pass - - def test_init(self): - T = TypeVar('T') - S = TypeVar('S') - with self.assertRaises(TypeError): - Generic[T, T] - with self.assertRaises(TypeError): - Generic[T, S, T] - - def test_repr(self): - self.assertEqual(repr(SimpleMapping), - __name__ + '.' + 'SimpleMapping') - self.assertEqual(repr(MySimpleMapping), - __name__ + '.' + 'MySimpleMapping') - - def test_chain_repr(self): - T = TypeVar('T') - S = TypeVar('S') - - class C(Generic[T]): - pass - - X = C[Tuple[S, T]] - self.assertEqual(X, C[Tuple[S, T]]) - self.assertNotEqual(X, C[Tuple[T, S]]) - - Y = X[T, int] - self.assertEqual(Y, X[T, int]) - self.assertNotEqual(Y, X[S, int]) - self.assertNotEqual(Y, X[T, str]) - - Z = Y[str] - self.assertEqual(Z, Y[str]) - self.assertNotEqual(Z, Y[int]) - self.assertNotEqual(Z, Y[T]) - - self.assertTrue(str(Z).endswith( - '.C[typing.Tuple[str, int]]')) - - def test_new_repr(self): - T = TypeVar('T') - U = TypeVar('U', covariant=True) - S = TypeVar('S') - - self.assertEqual(repr(List), 'typing.List') - self.assertEqual(repr(List[T]), 'typing.List[~T]') - self.assertEqual(repr(List[U]), 'typing.List[+U]') - self.assertEqual(repr(List[S][T][int]), 'typing.List[int]') - self.assertEqual(repr(List[int]), 'typing.List[int]') - - def test_new_repr_complex(self): - T = TypeVar('T') - TS = TypeVar('TS') - - self.assertEqual(repr(typing.Mapping[T, TS][TS, T]), 'typing.Mapping[~TS, ~T]') - self.assertEqual(repr(List[Tuple[T, TS]][int, T]), - 'typing.List[typing.Tuple[int, ~T]]') - self.assertEqual( - repr(List[Tuple[T, T]][List[int]]), - 'typing.List[typing.Tuple[typing.List[int], typing.List[int]]]' - ) - - def test_new_repr_bare(self): - T = TypeVar('T') - self.assertEqual(repr(Generic[T]), 'typing.Generic[~T]') - self.assertEqual(repr(typing._Protocol[T]), 'typing.Protocol[~T]') - class C(typing.Dict[Any, Any]): pass - # this line should just work - repr(C.__mro__) - - def test_dict(self): - T = TypeVar('T') - - class B(Generic[T]): - pass - - b = B() - b.foo = 42 - self.assertEqual(b.__dict__, {'foo': 42}) - - class C(B[int]): - pass - - c = C() - c.bar = 'abc' - self.assertEqual(c.__dict__, {'bar': 'abc'}) - - def test_subscripted_generics_as_proxies(self): - T = TypeVar('T') - class C(Generic[T]): - x = 'def' - self.assertEqual(C[int].x, 'def') - self.assertEqual(C[C[int]].x, 'def') - C[C[int]].x = 'changed' - self.assertEqual(C.x, 'changed') - self.assertEqual(C[str].x, 'changed') - C[List[str]].z = 'new' - self.assertEqual(C.z, 'new') - self.assertEqual(C[Tuple[int]].z, 'new') - - self.assertEqual(C().x, 'changed') - self.assertEqual(C[Tuple[str]]().z, 'new') - - class D(C[T]): - pass - self.assertEqual(D[int].x, 'changed') - self.assertEqual(D.z, 'new') - D.z = 'from derived z' - D[int].x = 'from derived x' - self.assertEqual(C.x, 'changed') - self.assertEqual(C[int].z, 'new') - self.assertEqual(D.x, 'from derived x') - self.assertEqual(D[str].z, 'from derived z') - - def test_abc_registry_kept(self): - T = TypeVar('T') - class C(Generic[T]): pass - C.register(int) - self.assertIsInstance(1, C) - C[int] - self.assertIsInstance(1, C) - - def test_false_subclasses(self): - class MyMapping(MutableMapping[str, str]): pass - self.assertNotIsInstance({}, MyMapping) - self.assertNotIsSubclass(dict, MyMapping) - - def test_abc_bases(self): - class MM(MutableMapping[str, str]): - def __getitem__(self, k): - return None - def __setitem__(self, k, v): - pass - def __delitem__(self, k): - pass - def __iter__(self): - return iter(()) - def __len__(self): - return 0 - # this should just work - MM().update() - self.assertIsInstance(MM(), collections_abc.MutableMapping) - self.assertIsInstance(MM(), MutableMapping) - self.assertNotIsInstance(MM(), List) - self.assertNotIsInstance({}, MM) - - def test_multiple_bases(self): - class MM1(MutableMapping[str, str], collections_abc.MutableMapping): - pass - with self.assertRaises(TypeError): - # consistent MRO not possible - class MM2(collections_abc.MutableMapping, MutableMapping[str, str]): - pass - - def test_orig_bases(self): - T = TypeVar('T') - class C(typing.Dict[str, T]): pass - self.assertEqual(C.__orig_bases__, (typing.Dict[str, T],)) - - def test_naive_runtime_checks(self): - def naive_dict_check(obj, tp): - # Check if a dictionary conforms to Dict type - if len(tp.__parameters__) > 0: - raise NotImplementedError - if tp.__args__: - KT, VT = tp.__args__ - return all( - isinstance(k, KT) and isinstance(v, VT) - for k, v in obj.items() - ) - self.assertTrue(naive_dict_check({'x': 1}, typing.Dict[typing.Text, int])) - self.assertFalse(naive_dict_check({1: 'x'}, typing.Dict[typing.Text, int])) - with self.assertRaises(NotImplementedError): - naive_dict_check({1: 'x'}, typing.Dict[typing.Text, T]) - - def naive_generic_check(obj, tp): - # Check if an instance conforms to the generic class - if not hasattr(obj, '__orig_class__'): - raise NotImplementedError - return obj.__orig_class__ == tp - class Node(Generic[T]): pass - self.assertTrue(naive_generic_check(Node[int](), Node[int])) - self.assertFalse(naive_generic_check(Node[str](), Node[int])) - self.assertFalse(naive_generic_check(Node[str](), List)) - with self.assertRaises(NotImplementedError): - naive_generic_check([1, 2, 3], Node[int]) - - def naive_list_base_check(obj, tp): - # Check if list conforms to a List subclass - return all(isinstance(x, tp.__orig_bases__[0].__args__[0]) - for x in obj) - class C(List[int]): pass - self.assertTrue(naive_list_base_check([1, 2, 3], C)) - self.assertFalse(naive_list_base_check(['a', 'b'], C)) - - def test_multi_subscr_base(self): - T = TypeVar('T') - U = TypeVar('U') - V = TypeVar('V') - class C(List[T][U][V]): pass - class D(C, List[T][U][V]): pass - self.assertEqual(C.__parameters__, (V,)) - self.assertEqual(D.__parameters__, (V,)) - self.assertEqual(C[int].__parameters__, ()) - self.assertEqual(D[int].__parameters__, ()) - self.assertEqual(C[int].__args__, (int,)) - self.assertEqual(D[int].__args__, (int,)) - self.assertEqual(C.__bases__, (List,)) - self.assertEqual(D.__bases__, (C, List)) - self.assertEqual(C.__orig_bases__, (List[T][U][V],)) - self.assertEqual(D.__orig_bases__, (C, List[T][U][V])) - - def test_subscript_meta(self): - T = TypeVar('T') - self.assertEqual(Type[GenericMeta], Type[GenericMeta]) - self.assertEqual(Union[T, int][GenericMeta], Union[GenericMeta, int]) - self.assertEqual(Callable[..., GenericMeta].__args__, (Ellipsis, GenericMeta)) - - def test_generic_hashes(self): - import mod_generics_cache - class A(Generic[T]): - __module__ = 'test_typing' - - class B(Generic[T]): - class A(Generic[T]): - pass - - self.assertEqual(A, A) - self.assertEqual(mod_generics_cache.A[str], mod_generics_cache.A[str]) - self.assertEqual(B.A, B.A) - self.assertEqual(mod_generics_cache.B.A[B.A[str]], - mod_generics_cache.B.A[B.A[str]]) - - self.assertNotEqual(A, B.A) - self.assertNotEqual(A, mod_generics_cache.A) - self.assertNotEqual(A, mod_generics_cache.B.A) - self.assertNotEqual(B.A, mod_generics_cache.A) - self.assertNotEqual(B.A, mod_generics_cache.B.A) - - self.assertNotEqual(A[str], B.A[str]) - self.assertNotEqual(A[List[Any]], B.A[List[Any]]) - self.assertNotEqual(A[str], mod_generics_cache.A[str]) - self.assertNotEqual(A[str], mod_generics_cache.B.A[str]) - self.assertNotEqual(B.A[int], mod_generics_cache.A[int]) - self.assertNotEqual(B.A[List[Any]], mod_generics_cache.B.A[List[Any]]) - - self.assertNotEqual(Tuple[A[str]], Tuple[B.A[str]]) - self.assertNotEqual(Tuple[A[List[Any]]], Tuple[B.A[List[Any]]]) - self.assertNotEqual(Union[str, A[str]], Union[str, mod_generics_cache.A[str]]) - self.assertNotEqual(Union[A[str], A[str]], - Union[A[str], mod_generics_cache.A[str]]) - self.assertNotEqual(typing.FrozenSet[A[str]], - typing.FrozenSet[mod_generics_cache.B.A[str]]) - - self.assertTrue(repr(Tuple[A[str]]).endswith('test_typing.A[str]]')) - self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) - .endswith('mod_generics_cache.A[str]]')) - - def test_extended_generic_rules_eq(self): - T = TypeVar('T') - U = TypeVar('U') - self.assertEqual(Tuple[T, T][int], Tuple[int, int]) - self.assertEqual(typing.Iterable[Tuple[T, T]][T], typing.Iterable[Tuple[T, T]]) - with self.assertRaises(TypeError): - Tuple[T, int][()] - with self.assertRaises(TypeError): - Tuple[T, U][T, ...] - - self.assertEqual(Union[T, int][int], int) - self.assertEqual(Union[T, U][int, Union[int, str]], Union[int, str]) - class Base(object): pass - class Derived(Base): pass - self.assertEqual(Union[T, Base][Derived], Base) - with self.assertRaises(TypeError): - Union[T, int][1] - - self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT]) - self.assertEqual(Callable[..., List[T]][int], Callable[..., List[int]]) - with self.assertRaises(TypeError): - Callable[[T], U][..., int] - with self.assertRaises(TypeError): - Callable[[T], U][[], int] - - def test_extended_generic_rules_repr(self): - T = TypeVar('T') - self.assertEqual(repr(Union[Tuple, Callable]).replace('typing.', ''), - 'Union[Tuple, Callable]') - self.assertEqual(repr(Union[Tuple, Tuple[int]]).replace('typing.', ''), - 'Tuple') - self.assertEqual(repr(Callable[..., Optional[T]][int]).replace('typing.', ''), - 'Callable[..., Union[int, NoneType]]') - self.assertEqual(repr(Callable[[], List[T]][int]).replace('typing.', ''), - 'Callable[[], List[int]]') - - def test_generic_forvard_ref(self): - LLT = List[List['CC']] - class CC: pass - self.assertEqual(typing._eval_type(LLT, globals(), locals()), List[List[CC]]) - T = TypeVar('T') - AT = Tuple[T, ...] - self.assertIs(typing._eval_type(AT, globals(), locals()), AT) - CT = Callable[..., List[T]] - self.assertIs(typing._eval_type(CT, globals(), locals()), CT) - - def test_extended_generic_rules_subclassing(self): - class T1(Tuple[T, KT]): pass - class T2(Tuple[T, ...]): pass - class C1(Callable[[T], T]): pass - class C2(Callable[..., int]): - def __call__(self): - return None - - self.assertEqual(T1.__parameters__, (T, KT)) - self.assertEqual(T1[int, str].__args__, (int, str)) - self.assertEqual(T1[int, T].__origin__, T1) - - self.assertEqual(T2.__parameters__, (T,)) - with self.assertRaises(TypeError): - T1[int] - with self.assertRaises(TypeError): - T2[int, str] - - self.assertEqual(repr(C1[int]).split('.')[-1], 'C1[int]') - self.assertEqual(C2.__parameters__, ()) - self.assertIsInstance(C2(), collections_abc.Callable) - self.assertIsSubclass(C2, collections_abc.Callable) - self.assertIsSubclass(C1, collections_abc.Callable) - self.assertIsInstance(T1(), tuple) - self.assertIsSubclass(T2, tuple) - self.assertIsSubclass(Tuple[int, ...], typing.Sequence) - self.assertIsSubclass(Tuple[int, ...], typing.Iterable) - - def test_fail_with_bare_union(self): - with self.assertRaises(TypeError): - List[Union] - with self.assertRaises(TypeError): - Tuple[Optional] - with self.assertRaises(TypeError): - ClassVar[ClassVar] - with self.assertRaises(TypeError): - List[ClassVar[int]] - - def test_fail_with_bare_generic(self): - T = TypeVar('T') - with self.assertRaises(TypeError): - List[Generic] - with self.assertRaises(TypeError): - Tuple[Generic[T]] - with self.assertRaises(TypeError): - List[typing._Protocol] - with self.assertRaises(TypeError): - isinstance(1, Generic) - - def test_type_erasure_special(self): - T = TypeVar('T') - # this is the only test that checks type caching - self.clear_caches() - class MyTup(Tuple[T, T]): pass - self.assertIs(MyTup[int]().__class__, MyTup) - self.assertIs(MyTup[int]().__orig_class__, MyTup[int]) - class MyCall(Callable[..., T]): - def __call__(self): return None - self.assertIs(MyCall[T]().__class__, MyCall) - self.assertIs(MyCall[T]().__orig_class__, MyCall[T]) - class MyDict(typing.Dict[T, T]): pass - self.assertIs(MyDict[int]().__class__, MyDict) - self.assertIs(MyDict[int]().__orig_class__, MyDict[int]) - class MyDef(typing.DefaultDict[str, T]): pass - self.assertIs(MyDef[int]().__class__, MyDef) - self.assertIs(MyDef[int]().__orig_class__, MyDef[int]) - - def test_all_repr_eq_any(self): - objs = (getattr(typing, el) for el in typing.__all__) - for obj in objs: - self.assertNotEqual(repr(obj), '') - self.assertEqual(obj, obj) - if getattr(obj, '__parameters__', None) and len(obj.__parameters__) == 1: - self.assertEqual(obj[Any].__args__, (Any,)) - if isinstance(obj, type): - for base in obj.__mro__: - self.assertNotEqual(repr(base), '') - self.assertEqual(base, base) - - def test_pickle(self): - global C # pickle wants to reference the class by name - T = TypeVar('T') - - class B(Generic[T]): - pass - - class C(B[int]): - pass - - c = C() - c.foo = 42 - c.bar = 'abc' - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - z = pickle.dumps(c, proto) - x = pickle.loads(z) - self.assertEqual(x.foo, 42) - self.assertEqual(x.bar, 'abc') - self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) - simples = [Any, Union, Tuple, Callable, ClassVar, List, typing.Iterable] - for s in simples: - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - z = pickle.dumps(s, proto) - x = pickle.loads(z) - self.assertEqual(s, x) - - def test_copy_and_deepcopy(self): - T = TypeVar('T') - class Node(Generic[T]): pass - things = [ - Any, - Callable[..., T], - Callable[[int], int], - ClassVar[List[T]], - ClassVar[int], - List['T'], - Node[Any], - Node[T], - Node[int], - Tuple['T', 'T'], - Tuple[Any, Any], - Tuple[T, int], - Union['T', int], - Union[T, int], - typing.Dict[T, Any], - typing.Dict[int, str], - typing.Iterable[Any], - typing.Iterable[T], - typing.Iterable[int], - typing.Mapping['T', int] - ] - for t in things: - self.assertEqual(t, deepcopy(t)) - self.assertEqual(t, copy(t)) - - def test_weakref_all(self): - T = TypeVar('T') - things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any], - Optional[List[int]], typing.Mapping[int, str], - typing.re.Match[bytes], typing.Iterable['whatever']] - for t in things: - self.assertEqual(weakref.ref(t)(), t) - - def test_parameterized_slots(self): - T = TypeVar('T') - class C(Generic[T]): - __slots__ = ('potato',) - - c = C() - c_int = C[int]() - self.assertEqual(C.__slots__, C[str].__slots__) - - c.potato = 0 - c_int.potato = 0 - with self.assertRaises(AttributeError): - c.tomato = 0 - with self.assertRaises(AttributeError): - c_int.tomato = 0 - - self.assertEqual(typing._eval_type(C['C'], globals(), locals()), C[C]) - self.assertEqual(typing._eval_type(C['C'], globals(), locals()).__slots__, - C.__slots__) - self.assertEqual(copy(C[int]), deepcopy(C[int])) - - def test_parameterized_slots_dict(self): - T = TypeVar('T') - class D(Generic[T]): - __slots__ = {'banana': 42} - - d = D() - d_int = D[int]() - self.assertEqual(D.__slots__, D[str].__slots__) - - d.banana = 'yes' - d_int.banana = 'yes' - with self.assertRaises(AttributeError): - d.foobar = 'no' - with self.assertRaises(AttributeError): - d_int.foobar = 'no' - - def test_errors(self): - with self.assertRaises(TypeError): - B = SimpleMapping[XK, Any] - - class C(Generic[B]): - pass - - def test_repr_2(self): - PY32 = sys.version_info[:2] < (3, 3) - - class C(Generic[T]): - pass - - self.assertEqual(C.__module__, __name__) - if not PY32: - self.assertEqual(C.__qualname__, - 'GenericTests.test_repr_2..C') - self.assertEqual(repr(C).split('.')[-1], 'C') - X = C[int] - self.assertEqual(X.__module__, __name__) - if not PY32: - self.assertTrue(X.__qualname__.endswith('..C')) - self.assertEqual(repr(X).split('.')[-1], 'C[int]') - - class Y(C[int]): - pass - - self.assertEqual(Y.__module__, __name__) - if not PY32: - self.assertEqual(Y.__qualname__, - 'GenericTests.test_repr_2..Y') - self.assertEqual(repr(Y).split('.')[-1], 'Y') - - def test_eq_1(self): - self.assertEqual(Generic, Generic) - self.assertEqual(Generic[T], Generic[T]) - self.assertNotEqual(Generic[KT], Generic[VT]) - - def test_eq_2(self): - - class A(Generic[T]): - pass - - class B(Generic[T]): - pass - - self.assertEqual(A, A) - self.assertNotEqual(A, B) - self.assertEqual(A[T], A[T]) - self.assertNotEqual(A[T], B[T]) - - def test_multiple_inheritance(self): - - class A(Generic[T, VT]): - pass - - class B(Generic[KT, T]): - pass - - class C(A[T, VT], Generic[VT, T, KT], B[KT, T]): - pass - - self.assertEqual(C.__parameters__, (VT, T, KT)) - - def test_nested(self): - - G = Generic - - class Visitor(G[T]): - - a = None - - def set(self, a): - self.a = a - - def get(self): - return self.a - - def visit(self): - return self.a - - V = Visitor[typing.List[int]] - - class IntListVisitor(V): - - def append(self, x): - self.a.append(x) - - a = IntListVisitor() - a.set([]) - a.append(1) - a.append(42) - self.assertEqual(a.get(), [1, 42]) - - def test_type_erasure(self): - T = TypeVar('T') - - class Node(Generic[T]): - def __init__(self, label, - left=None, - right=None): - self.label = label # type: T - self.left = left # type: Optional[Node[T]] - self.right = right # type: Optional[Node[T]] - - def foo(x): - a = Node(x) - b = Node[T](x) - c = Node[Any](x) - self.assertIs(type(a), Node) - self.assertIs(type(b), Node) - self.assertIs(type(c), Node) - self.assertEqual(a.label, x) - self.assertEqual(b.label, x) - self.assertEqual(c.label, x) - - foo(42) - - def test_implicit_any(self): - T = TypeVar('T') - - class C(Generic[T]): - pass - - class D(C): - pass - - self.assertEqual(D.__parameters__, ()) - - with self.assertRaises(Exception): - D[int] - with self.assertRaises(Exception): - D[Any] - with self.assertRaises(Exception): - D[T] - - -class ClassVarTests(BaseTestCase): - - def test_basics(self): - with self.assertRaises(TypeError): - ClassVar[1] - with self.assertRaises(TypeError): - ClassVar[int, str] - with self.assertRaises(TypeError): - ClassVar[int][str] - - def test_repr(self): - self.assertEqual(repr(ClassVar), 'typing.ClassVar') - cv = ClassVar[int] - self.assertEqual(repr(cv), 'typing.ClassVar[int]') - cv = ClassVar[Employee] - self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__) - - def test_cannot_subclass(self): - with self.assertRaises(TypeError): - class C(type(ClassVar)): - pass - with self.assertRaises(TypeError): - class C(type(ClassVar[int])): - pass - - def test_cannot_init(self): - with self.assertRaises(TypeError): - ClassVar() - with self.assertRaises(TypeError): - type(ClassVar)() - with self.assertRaises(TypeError): - type(ClassVar[Optional[int]])() - - def test_no_isinstance(self): - with self.assertRaises(TypeError): - isinstance(1, ClassVar[int]) - with self.assertRaises(TypeError): - issubclass(int, ClassVar) - - -class CastTests(BaseTestCase): - - def test_basics(self): - self.assertEqual(cast(int, 42), 42) - self.assertEqual(cast(float, 42), 42) - self.assertIs(type(cast(float, 42)), int) - self.assertEqual(cast(Any, 42), 42) - self.assertEqual(cast(list, 42), 42) - self.assertEqual(cast(Union[str, float], 42), 42) - self.assertEqual(cast(AnyStr, 42), 42) - self.assertEqual(cast(None, 42), 42) - - def test_errors(self): - # Bogus calls are not expected to fail. - cast(42, 42) - cast('hello', 42) - - -class ForwardRefTests(BaseTestCase): - - def test_forwardref_instance_type_error(self): - fr = typing._ForwardRef('int') - with self.assertRaises(TypeError): - isinstance(42, fr) - - def test_syntax_error(self): - - with self.assertRaises(SyntaxError): - Generic['/T'] - - def test_forwardref_subclass_type_error(self): - fr = typing._ForwardRef('int') - with self.assertRaises(TypeError): - issubclass(int, fr) - - def test_forward_equality(self): - fr = typing._ForwardRef('int') - self.assertEqual(fr, typing._ForwardRef('int')) - self.assertNotEqual(List['int'], List[int]) - - def test_forward_repr(self): - self.assertEqual(repr(List['int']), "typing.List[_ForwardRef(%r)]" % 'int') - - -class OverloadTests(BaseTestCase): - - def test_overload_fails(self): - from typing import overload - - with self.assertRaises(RuntimeError): - - @overload - def blah(): - pass - - blah() - - def test_overload_succeeds(self): - from typing import overload - - @overload - def blah(): - pass - - def blah(): - pass - - blah() - - -class CollectionsAbcTests(BaseTestCase): - - def test_hashable(self): - self.assertIsInstance(42, typing.Hashable) - self.assertNotIsInstance([], typing.Hashable) - - def test_iterable(self): - self.assertIsInstance([], typing.Iterable) - # Due to ABC caching, the second time takes a separate code - # path and could fail. So call this a few times. - self.assertIsInstance([], typing.Iterable) - self.assertIsInstance([], typing.Iterable) - self.assertNotIsInstance(42, typing.Iterable) - # Just in case, also test issubclass() a few times. - self.assertIsSubclass(list, typing.Iterable) - self.assertIsSubclass(list, typing.Iterable) - - def test_iterator(self): - it = iter([]) - self.assertIsInstance(it, typing.Iterator) - self.assertNotIsInstance(42, typing.Iterator) - - def test_sized(self): - self.assertIsInstance([], typing.Sized) - self.assertNotIsInstance(42, typing.Sized) - - def test_container(self): - self.assertIsInstance([], typing.Container) - self.assertNotIsInstance(42, typing.Container) - - def test_abstractset(self): - self.assertIsInstance(set(), typing.AbstractSet) - self.assertNotIsInstance(42, typing.AbstractSet) - - def test_mutableset(self): - self.assertIsInstance(set(), typing.MutableSet) - self.assertNotIsInstance(frozenset(), typing.MutableSet) - - def test_mapping(self): - self.assertIsInstance({}, typing.Mapping) - self.assertNotIsInstance(42, typing.Mapping) - - def test_mutablemapping(self): - self.assertIsInstance({}, typing.MutableMapping) - self.assertNotIsInstance(42, typing.MutableMapping) - - def test_sequence(self): - self.assertIsInstance([], typing.Sequence) - self.assertNotIsInstance(42, typing.Sequence) - - def test_mutablesequence(self): - self.assertIsInstance([], typing.MutableSequence) - self.assertNotIsInstance((), typing.MutableSequence) - - def test_bytestring(self): - self.assertIsInstance(b'', typing.ByteString) - self.assertIsInstance(bytearray(b''), typing.ByteString) - - def test_list(self): - self.assertIsSubclass(list, typing.List) - - def test_deque(self): - self.assertIsSubclass(collections.deque, typing.Deque) - class MyDeque(typing.Deque[int]): pass - self.assertIsInstance(MyDeque(), collections.deque) - - def test_counter(self): - self.assertIsSubclass(collections.Counter, typing.Counter) - - def test_set(self): - self.assertIsSubclass(set, typing.Set) - self.assertNotIsSubclass(frozenset, typing.Set) - - def test_frozenset(self): - self.assertIsSubclass(frozenset, typing.FrozenSet) - self.assertNotIsSubclass(set, typing.FrozenSet) - - def test_dict(self): - self.assertIsSubclass(dict, typing.Dict) - - def test_no_list_instantiation(self): - with self.assertRaises(TypeError): - typing.List() - with self.assertRaises(TypeError): - typing.List[T]() - with self.assertRaises(TypeError): - typing.List[int]() - - def test_list_subclass(self): - - class MyList(typing.List[int]): - pass - - a = MyList() - self.assertIsInstance(a, MyList) - self.assertIsInstance(a, typing.Sequence) - - self.assertIsSubclass(MyList, list) - self.assertNotIsSubclass(list, MyList) - - def test_no_dict_instantiation(self): - with self.assertRaises(TypeError): - typing.Dict() - with self.assertRaises(TypeError): - typing.Dict[KT, VT]() - with self.assertRaises(TypeError): - typing.Dict[str, int]() - - def test_dict_subclass(self): - - class MyDict(typing.Dict[str, int]): - pass - - d = MyDict() - self.assertIsInstance(d, MyDict) - self.assertIsInstance(d, typing.MutableMapping) - - self.assertIsSubclass(MyDict, dict) - self.assertNotIsSubclass(dict, MyDict) - - def test_defaultdict_instantiation(self): - self.assertIs(type(typing.DefaultDict()), collections.defaultdict) - self.assertIs(type(typing.DefaultDict[KT, VT]()), collections.defaultdict) - self.assertIs(type(typing.DefaultDict[str, int]()), collections.defaultdict) - - def test_defaultdict_subclass(self): - - class MyDefDict(typing.DefaultDict[str, int]): - pass - - dd = MyDefDict() - self.assertIsInstance(dd, MyDefDict) - - self.assertIsSubclass(MyDefDict, collections.defaultdict) - self.assertNotIsSubclass(collections.defaultdict, MyDefDict) - - def test_deque_instantiation(self): - self.assertIs(type(typing.Deque()), collections.deque) - self.assertIs(type(typing.Deque[T]()), collections.deque) - self.assertIs(type(typing.Deque[int]()), collections.deque) - class D(typing.Deque[T]): pass - self.assertIs(type(D[int]()), D) - - def test_counter_instantiation(self): - self.assertIs(type(typing.Counter()), collections.Counter) - self.assertIs(type(typing.Counter[T]()), collections.Counter) - self.assertIs(type(typing.Counter[int]()), collections.Counter) - class C(typing.Counter[T]): pass - self.assertIs(type(C[int]()), C) - - def test_counter_subclass_instantiation(self): - - class MyCounter(typing.Counter[int]): - pass - - d = MyCounter() - self.assertIsInstance(d, MyCounter) - self.assertIsInstance(d, typing.Counter) - self.assertIsInstance(d, collections.Counter) - - def test_no_set_instantiation(self): - with self.assertRaises(TypeError): - typing.Set() - with self.assertRaises(TypeError): - typing.Set[T]() - with self.assertRaises(TypeError): - typing.Set[int]() - - def test_set_subclass_instantiation(self): - - class MySet(typing.Set[int]): - pass - - d = MySet() - self.assertIsInstance(d, MySet) - - def test_no_frozenset_instantiation(self): - with self.assertRaises(TypeError): - typing.FrozenSet() - with self.assertRaises(TypeError): - typing.FrozenSet[T]() - with self.assertRaises(TypeError): - typing.FrozenSet[int]() - - def test_frozenset_subclass_instantiation(self): - - class MyFrozenSet(typing.FrozenSet[int]): - pass - - d = MyFrozenSet() - self.assertIsInstance(d, MyFrozenSet) - - def test_no_tuple_instantiation(self): - with self.assertRaises(TypeError): - Tuple() - with self.assertRaises(TypeError): - Tuple[T]() - with self.assertRaises(TypeError): - Tuple[int]() - - def test_generator(self): - def foo(): - yield 42 - g = foo() - self.assertIsSubclass(type(g), typing.Generator) - - def test_no_generator_instantiation(self): - with self.assertRaises(TypeError): - typing.Generator() - with self.assertRaises(TypeError): - typing.Generator[T, T, T]() - with self.assertRaises(TypeError): - typing.Generator[int, int, int]() - - def test_subclassing(self): - - class MMA(typing.MutableMapping): - pass - - with self.assertRaises(TypeError): # It's abstract - MMA() - - class MMC(MMA): - def __getitem__(self, k): - return None - def __setitem__(self, k, v): - pass - def __delitem__(self, k): - pass - def __iter__(self): - return iter(()) - def __len__(self): - return 0 - - self.assertEqual(len(MMC()), 0) - assert callable(MMC.update) - self.assertIsInstance(MMC(), typing.Mapping) - - class MMB(typing.MutableMapping[KT, VT]): - def __getitem__(self, k): - return None - def __setitem__(self, k, v): - pass - def __delitem__(self, k): - pass - def __iter__(self): - return iter(()) - def __len__(self): - return 0 - - self.assertEqual(len(MMB()), 0) - self.assertEqual(len(MMB[str, str]()), 0) - self.assertEqual(len(MMB[KT, VT]()), 0) - - self.assertNotIsSubclass(dict, MMA) - self.assertNotIsSubclass(dict, MMB) - - self.assertIsSubclass(MMA, typing.Mapping) - self.assertIsSubclass(MMB, typing.Mapping) - self.assertIsSubclass(MMC, typing.Mapping) - - self.assertIsInstance(MMB[KT, VT](), typing.Mapping) - self.assertIsInstance(MMB[KT, VT](), collections.Mapping) - - self.assertIsSubclass(MMA, collections.Mapping) - self.assertIsSubclass(MMB, collections.Mapping) - self.assertIsSubclass(MMC, collections.Mapping) - - self.assertIsSubclass(MMB[str, str], typing.Mapping) - self.assertIsSubclass(MMC, MMA) - - class I(typing.Iterable): pass - self.assertNotIsSubclass(list, I) - - class G(typing.Generator[int, int, int]): pass - def g(): yield 0 - self.assertIsSubclass(G, typing.Generator) - self.assertIsSubclass(G, typing.Iterable) - if hasattr(collections, 'Generator'): - self.assertIsSubclass(G, collections.Generator) - self.assertIsSubclass(G, collections.Iterable) - self.assertNotIsSubclass(type(g), G) - - def test_subclassing_subclasshook(self): - - class Base(typing.Iterable): - @classmethod - def __subclasshook__(cls, other): - if other.__name__ == 'Foo': - return True - else: - return False - - class C(Base): pass - class Foo: pass - class Bar: pass - self.assertIsSubclass(Foo, Base) - self.assertIsSubclass(Foo, C) - self.assertNotIsSubclass(Bar, C) - - def test_subclassing_register(self): - - class A(typing.Container): pass - class B(A): pass - - class C: pass - A.register(C) - self.assertIsSubclass(C, A) - self.assertNotIsSubclass(C, B) - - class D: pass - B.register(D) - self.assertIsSubclass(D, A) - self.assertIsSubclass(D, B) - - class M(): pass - collections.MutableMapping.register(M) - self.assertIsSubclass(M, typing.Mapping) - - def test_collections_as_base(self): - - class M(collections.Mapping): pass - self.assertIsSubclass(M, typing.Mapping) - self.assertIsSubclass(M, typing.Iterable) - - class S(collections.MutableSequence): pass - self.assertIsSubclass(S, typing.MutableSequence) - self.assertIsSubclass(S, typing.Iterable) - - class I(collections.Iterable): pass - self.assertIsSubclass(I, typing.Iterable) - - class A(collections.Mapping): pass - class B: pass - A.register(B) - self.assertIsSubclass(B, typing.Mapping) - - -class TypeTests(BaseTestCase): - - def test_type_basic(self): - - class User(object): pass - class BasicUser(User): pass - class ProUser(User): pass - - def new_user(user_class): - # type: (Type[User]) -> User - return user_class() - - new_user(BasicUser) - - def test_type_typevar(self): - - class User(object): pass - class BasicUser(User): pass - class ProUser(User): pass - - global U - U = TypeVar('U', bound=User) - - def new_user(user_class): - # type: (Type[U]) -> U - return user_class() - - new_user(BasicUser) - - def test_type_optional(self): - A = Optional[Type[BaseException]] # noqa - - def foo(a): - # type: (A) -> Optional[BaseException] - if a is None: - return None - else: - return a() - - assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt) - assert foo(None) is None - - -class NewTypeTests(BaseTestCase): - - def test_basic(self): - UserId = NewType('UserId', int) - UserName = NewType('UserName', str) - self.assertIsInstance(UserId(5), int) - self.assertIsInstance(UserName('Joe'), type('Joe')) - self.assertEqual(UserId(5) + 1, 6) - - def test_errors(self): - UserId = NewType('UserId', int) - UserName = NewType('UserName', str) - with self.assertRaises(TypeError): - issubclass(UserId, int) - with self.assertRaises(TypeError): - class D(UserName): - pass - - -class NamedTupleTests(BaseTestCase): - - def test_basics(self): - Emp = NamedTuple('Emp', [('name', str), ('id', int)]) - self.assertIsSubclass(Emp, tuple) - joe = Emp('Joe', 42) - jim = Emp(name='Jim', id=1) - self.assertIsInstance(joe, Emp) - self.assertIsInstance(joe, tuple) - self.assertEqual(joe.name, 'Joe') - self.assertEqual(joe.id, 42) - self.assertEqual(jim.name, 'Jim') - self.assertEqual(jim.id, 1) - self.assertEqual(Emp.__name__, 'Emp') - self.assertEqual(Emp._fields, ('name', 'id')) - self.assertEqual(Emp._field_types, dict(name=str, id=int)) - - def test_pickle(self): - global Emp # pickle wants to reference the class by name - Emp = NamedTuple('Emp', [('name', str), ('id', int)]) - jane = Emp('jane', 37) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - z = pickle.dumps(jane, proto) - jane2 = pickle.loads(z) - self.assertEqual(jane2, jane) - - -class IOTests(BaseTestCase): - - def test_io_submodule(self): - from typing.io import IO, TextIO, BinaryIO, __all__, __name__ - self.assertIs(IO, typing.IO) - self.assertIs(TextIO, typing.TextIO) - self.assertIs(BinaryIO, typing.BinaryIO) - self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO'])) - self.assertEqual(__name__, 'typing.io') - - -class RETests(BaseTestCase): - # Much of this is really testing _TypeAlias. - - def test_basics(self): - pat = re.compile('[a-z]+', re.I) - self.assertIsSubclass(pat.__class__, Pattern) - self.assertIsSubclass(type(pat), Pattern) - self.assertIsInstance(pat, Pattern) - - mat = pat.search('12345abcde.....') - self.assertIsSubclass(mat.__class__, Match) - self.assertIsSubclass(type(mat), Match) - self.assertIsInstance(mat, Match) - - # these should just work - Pattern[Union[str, bytes]] - Match[Union[bytes, str]] - - def test_alias_equality(self): - self.assertEqual(Pattern[str], Pattern[str]) - self.assertNotEqual(Pattern[str], Pattern[bytes]) - self.assertNotEqual(Pattern[str], Match[str]) - self.assertNotEqual(Pattern[str], str) - - def test_errors(self): - with self.assertRaises(TypeError): - # Doesn't fit AnyStr. - Pattern[int] - with self.assertRaises(TypeError): - # Can't change type vars? - Match[T] - m = Match[Union[str, bytes]] - with self.assertRaises(TypeError): - # Too complicated? - m[str] - with self.assertRaises(TypeError): - # We don't support isinstance(). - isinstance(42, Pattern[str]) - with self.assertRaises(TypeError): - # We don't support issubclass(). - issubclass(Pattern[bytes], Pattern[str]) - - def test_repr(self): - self.assertEqual(repr(Pattern), 'Pattern[~AnyStr]') - self.assertEqual(repr(Pattern[unicode]), 'Pattern[unicode]') - self.assertEqual(repr(Pattern[str]), 'Pattern[str]') - self.assertEqual(repr(Match), 'Match[~AnyStr]') - self.assertEqual(repr(Match[unicode]), 'Match[unicode]') - self.assertEqual(repr(Match[str]), 'Match[str]') - - def test_re_submodule(self): - from typing.re import Match, Pattern, __all__, __name__ - self.assertIs(Match, typing.Match) - self.assertIs(Pattern, typing.Pattern) - self.assertEqual(set(__all__), set(['Match', 'Pattern'])) - self.assertEqual(__name__, 'typing.re') - - def test_cannot_subclass(self): - with self.assertRaises(TypeError) as ex: - - class A(typing.Match): - pass - - self.assertEqual(str(ex.exception), - "Cannot subclass typing._TypeAlias") - - -class AllTests(BaseTestCase): - """Tests for __all__.""" - - def test_all(self): - from typing import __all__ as a - # Just spot-check the first and last of every category. - self.assertIn('AbstractSet', a) - self.assertIn('ValuesView', a) - self.assertIn('cast', a) - self.assertIn('overload', a) - # Check that io and re are not exported. - self.assertNotIn('io', a) - self.assertNotIn('re', a) - # Spot-check that stdlib modules aren't exported. - self.assertNotIn('os', a) - self.assertNotIn('sys', a) - # Check that Text is defined. - self.assertIn('Text', a) - - def test_respect_no_type_check(self): - @typing.no_type_check - class NoTpCheck(object): - class Inn(object): - def __init__(self, x): - # type: (this is not actually a type) -> None - pass - self.assertTrue(NoTpCheck.__no_type_check__) - self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__) - - def test_get_type_hints_dummy(self): - - def foo(x): - # type: (int) -> int - return x + 1 - - self.assertIsNone(typing.get_type_hints(foo)) - - -if __name__ == '__main__': - main() diff --git a/lib-typing/2.7/typing.py b/lib-typing/2.7/typing.py deleted file mode 100644 index 0d67e4c3e150..000000000000 --- a/lib-typing/2.7/typing.py +++ /dev/null @@ -1,2140 +0,0 @@ -from __future__ import absolute_import, unicode_literals - -import abc -from abc import abstractmethod, abstractproperty -import collections -import functools -import re as stdlib_re # Avoid confusion with the re we export. -import sys -import types -try: - import collections.abc as collections_abc -except ImportError: - import collections as collections_abc # Fallback for PY3.2. - - -# Please keep __all__ alphabetized within each category. -__all__ = [ - # Super-special typing primitives. - 'Any', - 'Callable', - 'ClassVar', - 'Generic', - 'Optional', - 'Tuple', - 'Type', - 'TypeVar', - 'Union', - - # ABCs (from collections.abc). - 'AbstractSet', # collections.abc.Set. - 'GenericMeta', # subclass of abc.ABCMeta and a metaclass - # for 'Generic' and ABCs below. - 'ByteString', - 'Container', - 'Hashable', - 'ItemsView', - 'Iterable', - 'Iterator', - 'KeysView', - 'Mapping', - 'MappingView', - 'MutableMapping', - 'MutableSequence', - 'MutableSet', - 'Sequence', - 'Sized', - 'ValuesView', - - # Structural checks, a.k.a. protocols. - 'Reversible', - 'SupportsAbs', - 'SupportsFloat', - 'SupportsInt', - - # Concrete collection types. - 'Counter', - 'Deque', - 'Dict', - 'DefaultDict', - 'List', - 'Set', - 'FrozenSet', - 'NamedTuple', # Not really a type. - 'Generator', - - # One-off things. - 'AnyStr', - 'cast', - 'get_type_hints', - 'NewType', - 'no_type_check', - 'no_type_check_decorator', - 'overload', - 'Text', - 'TYPE_CHECKING', -] - -# The pseudo-submodules 're' and 'io' are part of the public -# namespace, but excluded from __all__ because they might stomp on -# legitimate imports of those modules. - - -def _qualname(x): - if sys.version_info[:2] >= (3, 3): - return x.__qualname__ - else: - # Fall back to just name. - return x.__name__ - - -def _trim_name(nm): - whitelist = ('_TypeAlias', '_ForwardRef', '_TypingBase', '_FinalTypingBase') - if nm.startswith('_') and nm not in whitelist: - nm = nm[1:] - return nm - - -class TypingMeta(type): - """Metaclass for most types defined in typing module - (not a part of public API). - - This also defines a dummy constructor (all the work for most typing - constructs is done in __new__) and a nicer repr(). - """ - - _is_protocol = False - - def __new__(cls, name, bases, namespace): - return super(TypingMeta, cls).__new__(cls, str(name), bases, namespace) - - @classmethod - def assert_no_subclassing(cls, bases): - for base in bases: - if isinstance(base, cls): - raise TypeError("Cannot subclass %s" % - (', '.join(map(_type_repr, bases)) or '()')) - - def __init__(self, *args, **kwds): - pass - - def _eval_type(self, globalns, localns): - """Override this in subclasses to interpret forward references. - - For example, List['C'] is internally stored as - List[_ForwardRef('C')], which should evaluate to List[C], - where C is an object found in globalns or localns (searching - localns first, of course). - """ - return self - - def _get_type_vars(self, tvars): - pass - - def __repr__(self): - qname = _trim_name(_qualname(self)) - return '%s.%s' % (self.__module__, qname) - - -class _TypingBase(object): - """Internal indicator of special typing constructs.""" - __metaclass__ = TypingMeta - __slots__ = ('__weakref__',) - - def __init__(self, *args, **kwds): - pass - - def __new__(cls, *args, **kwds): - """Constructor. - - This only exists to give a better error message in case - someone tries to subclass a special typing object (not a good idea). - """ - if (len(args) == 3 and - isinstance(args[0], str) and - isinstance(args[1], tuple)): - # Close enough. - raise TypeError("Cannot subclass %r" % cls) - return super(_TypingBase, cls).__new__(cls) - - # Things that are not classes also need these. - def _eval_type(self, globalns, localns): - return self - - def _get_type_vars(self, tvars): - pass - - def __repr__(self): - cls = type(self) - qname = _trim_name(_qualname(cls)) - return '%s.%s' % (cls.__module__, qname) - - def __call__(self, *args, **kwds): - raise TypeError("Cannot instantiate %r" % type(self)) - - -class _FinalTypingBase(_TypingBase): - """Internal mix-in class to prevent instantiation. - - Prevents instantiation unless _root=True is given in class call. - It is used to create pseudo-singleton instances Any, Union, Optional, etc. - """ - - __slots__ = () - - def __new__(cls, *args, **kwds): - self = super(_FinalTypingBase, cls).__new__(cls, *args, **kwds) - if '_root' in kwds and kwds['_root'] is True: - return self - raise TypeError("Cannot instantiate %r" % cls) - - def __reduce__(self): - return _trim_name(type(self).__name__) - - -class _ForwardRef(_TypingBase): - """Internal wrapper to hold a forward reference.""" - - __slots__ = ('__forward_arg__', '__forward_code__', - '__forward_evaluated__', '__forward_value__') - - def __init__(self, arg): - super(_ForwardRef, self).__init__(arg) - if not isinstance(arg, basestring): - raise TypeError('Forward reference must be a string -- got %r' % (arg,)) - try: - code = compile(arg, '', 'eval') - except SyntaxError: - raise SyntaxError('Forward reference must be an expression -- got %r' % - (arg,)) - self.__forward_arg__ = arg - self.__forward_code__ = code - self.__forward_evaluated__ = False - self.__forward_value__ = None - - def _eval_type(self, globalns, localns): - if not self.__forward_evaluated__ or localns is not globalns: - if globalns is None and localns is None: - globalns = localns = {} - elif globalns is None: - globalns = localns - elif localns is None: - localns = globalns - self.__forward_value__ = _type_check( - eval(self.__forward_code__, globalns, localns), - "Forward references must evaluate to types.") - self.__forward_evaluated__ = True - return self.__forward_value__ - - def __eq__(self, other): - if not isinstance(other, _ForwardRef): - return NotImplemented - return (self.__forward_arg__ == other.__forward_arg__ and - self.__forward_value__ == other.__forward_value__) - - def __hash__(self): - return hash((self.__forward_arg__, self.__forward_value__)) - - def __instancecheck__(self, obj): - raise TypeError("Forward references cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - raise TypeError("Forward references cannot be used with issubclass().") - - def __repr__(self): - return '_ForwardRef(%r)' % (self.__forward_arg__,) - - -class _TypeAlias(_TypingBase): - """Internal helper class for defining generic variants of concrete types. - - Note that this is not a type; let's call it a pseudo-type. It cannot - be used in instance and subclass checks in parameterized form, i.e. - ``isinstance(42, Match[str])`` raises ``TypeError`` instead of returning - ``False``. - """ - - __slots__ = ('name', 'type_var', 'impl_type', 'type_checker') - - def __init__(self, name, type_var, impl_type, type_checker): - """Initializer. - - Args: - name: The name, e.g. 'Pattern'. - type_var: The type parameter, e.g. AnyStr, or the - specific type, e.g. str. - impl_type: The implementation type. - type_checker: Function that takes an impl_type instance. - and returns a value that should be a type_var instance. - """ - assert isinstance(name, basestring), repr(name) - assert isinstance(impl_type, type), repr(impl_type) - assert not isinstance(impl_type, TypingMeta), repr(impl_type) - assert isinstance(type_var, (type, _TypingBase)), repr(type_var) - self.name = name - self.type_var = type_var - self.impl_type = impl_type - self.type_checker = type_checker - - def __repr__(self): - return "%s[%s]" % (self.name, _type_repr(self.type_var)) - - def __getitem__(self, parameter): - if not isinstance(self.type_var, TypeVar): - raise TypeError("%s cannot be further parameterized." % self) - if self.type_var.__constraints__ and isinstance(parameter, type): - if not issubclass(parameter, self.type_var.__constraints__): - raise TypeError("%s is not a valid substitution for %s." % - (parameter, self.type_var)) - if isinstance(parameter, TypeVar) and parameter is not self.type_var: - raise TypeError("%s cannot be re-parameterized." % self) - return self.__class__(self.name, parameter, - self.impl_type, self.type_checker) - - def __eq__(self, other): - if not isinstance(other, _TypeAlias): - return NotImplemented - return self.name == other.name and self.type_var == other.type_var - - def __hash__(self): - return hash((self.name, self.type_var)) - - def __instancecheck__(self, obj): - if not isinstance(self.type_var, TypeVar): - raise TypeError("Parameterized type aliases cannot be used " - "with isinstance().") - return isinstance(obj, self.impl_type) - - def __subclasscheck__(self, cls): - if not isinstance(self.type_var, TypeVar): - raise TypeError("Parameterized type aliases cannot be used " - "with issubclass().") - return issubclass(cls, self.impl_type) - - -def _get_type_vars(types, tvars): - for t in types: - if isinstance(t, TypingMeta) or isinstance(t, _TypingBase): - t._get_type_vars(tvars) - - -def _type_vars(types): - tvars = [] - _get_type_vars(types, tvars) - return tuple(tvars) - - -def _eval_type(t, globalns, localns): - if isinstance(t, TypingMeta) or isinstance(t, _TypingBase): - return t._eval_type(globalns, localns) - return t - - -def _type_check(arg, msg): - """Check that the argument is a type, and return it (internal helper). - - As a special case, accept None and return type(None) instead. - Also, _TypeAlias instances (e.g. Match, Pattern) are acceptable. - - The msg argument is a human-readable error message, e.g. - - "Union[arg, ...]: arg should be a type." - - We append the repr() of the actual value (truncated to 100 chars). - """ - if arg is None: - return type(None) - if isinstance(arg, basestring): - arg = _ForwardRef(arg) - if ( - isinstance(arg, _TypingBase) and type(arg).__name__ == '_ClassVar' or - not isinstance(arg, (type, _TypingBase)) and not callable(arg) - ): - raise TypeError(msg + " Got %.100r." % (arg,)) - # Bare Union etc. are not valid as type arguments - if ( - type(arg).__name__ in ('_Union', '_Optional') and - not getattr(arg, '__origin__', None) or - isinstance(arg, TypingMeta) and _gorg(arg) in (Generic, _Protocol) - ): - raise TypeError("Plain %s is not valid as type argument" % arg) - return arg - - -def _type_repr(obj): - """Return the repr() of an object, special-casing types (internal helper). - - If obj is a type, we return a shorter version than the default - type.__repr__, based on the module and qualified name, which is - typically enough to uniquely identify a type. For everything - else, we fall back on repr(obj). - """ - if isinstance(obj, type) and not isinstance(obj, TypingMeta): - if obj.__module__ == '__builtin__': - return _qualname(obj) - return '%s.%s' % (obj.__module__, _qualname(obj)) - if obj is Ellipsis: - return('...') - if isinstance(obj, types.FunctionType): - return obj.__name__ - return repr(obj) - - -class ClassVarMeta(TypingMeta): - """Metaclass for _ClassVar""" - - def __new__(cls, name, bases, namespace): - cls.assert_no_subclassing(bases) - self = super(ClassVarMeta, cls).__new__(cls, name, bases, namespace) - return self - - -class _ClassVar(_FinalTypingBase): - """Special type construct to mark class variables. - - An annotation wrapped in ClassVar indicates that a given - attribute is intended to be used as a class variable and - should not be set on instances of that class. Usage:: - - class Starship: - stats = {} # type: ClassVar[Dict[str, int]] # class variable - damage = 10 # type: int # instance variable - - ClassVar accepts only types and cannot be further subscribed. - - Note that ClassVar is not a class itself, and should not - be used with isinstance() or issubclass(). - """ - - __metaclass__ = ClassVarMeta - __slots__ = ('__type__',) - - def __init__(self, tp=None, _root=False): - self.__type__ = tp - - def __getitem__(self, item): - cls = type(self) - if self.__type__ is None: - return cls(_type_check(item, - '{} accepts only types.'.format(cls.__name__[1:])), - _root=True) - raise TypeError('{} cannot be further subscripted' - .format(cls.__name__[1:])) - - def _eval_type(self, globalns, localns): - return type(self)(_eval_type(self.__type__, globalns, localns), - _root=True) - - def __repr__(self): - r = super(_ClassVar, self).__repr__() - if self.__type__ is not None: - r += '[{}]'.format(_type_repr(self.__type__)) - return r - - def __hash__(self): - return hash((type(self).__name__, self.__type__)) - - def __eq__(self, other): - if not isinstance(other, _ClassVar): - return NotImplemented - if self.__type__ is not None: - return self.__type__ == other.__type__ - return self is other - - -ClassVar = _ClassVar(_root=True) - - -class AnyMeta(TypingMeta): - """Metaclass for Any.""" - - def __new__(cls, name, bases, namespace): - cls.assert_no_subclassing(bases) - self = super(AnyMeta, cls).__new__(cls, name, bases, namespace) - return self - - -class _Any(_FinalTypingBase): - """Special type indicating an unconstrained type. - - - Any is compatible with every type. - - Any assumed to have all methods. - - All values assumed to be instances of Any. - - Note that all the above statements are true from the point of view of - static type checkers. At runtime, Any should not be used with instance - or class checks. - """ - __metaclass__ = AnyMeta - __slots__ = () - - def __instancecheck__(self, obj): - raise TypeError("Any cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - raise TypeError("Any cannot be used with issubclass().") - - -Any = _Any(_root=True) - - -class TypeVarMeta(TypingMeta): - def __new__(cls, name, bases, namespace): - cls.assert_no_subclassing(bases) - return super(TypeVarMeta, cls).__new__(cls, name, bases, namespace) - - -class TypeVar(_TypingBase): - """Type variable. - - Usage:: - - T = TypeVar('T') # Can be anything - A = TypeVar('A', str, bytes) # Must be str or bytes - - Type variables exist primarily for the benefit of static type - checkers. They serve as the parameters for generic types as well - as for generic function definitions. See class Generic for more - information on generic types. Generic functions work as follows: - - def repeat(x: T, n: int) -> List[T]: - '''Return a list containing n references to x.''' - return [x]*n - - def longest(x: A, y: A) -> A: - '''Return the longest of two strings.''' - return x if len(x) >= len(y) else y - - The latter example's signature is essentially the overloading - of (str, str) -> str and (bytes, bytes) -> bytes. Also note - that if the arguments are instances of some subclass of str, - the return type is still plain str. - - At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError. - - Type variables defined with covariant=True or contravariant=True - can be used do declare covariant or contravariant generic types. - See PEP 484 for more details. By default generic types are invariant - in all type variables. - - Type variables can be introspected. e.g.: - - T.__name__ == 'T' - T.__constraints__ == () - T.__covariant__ == False - T.__contravariant__ = False - A.__constraints__ == (str, bytes) - """ - - __metaclass__ = TypeVarMeta - __slots__ = ('__name__', '__bound__', '__constraints__', - '__covariant__', '__contravariant__') - - def __init__(self, name, *constraints, **kwargs): - super(TypeVar, self).__init__(name, *constraints, **kwargs) - bound = kwargs.get('bound', None) - covariant = kwargs.get('covariant', False) - contravariant = kwargs.get('contravariant', False) - self.__name__ = name - if covariant and contravariant: - raise ValueError("Bivariant types are not supported.") - self.__covariant__ = bool(covariant) - self.__contravariant__ = bool(contravariant) - if constraints and bound is not None: - raise TypeError("Constraints cannot be combined with bound=...") - if constraints and len(constraints) == 1: - raise TypeError("A single constraint is not allowed") - msg = "TypeVar(name, constraint, ...): constraints must be types." - self.__constraints__ = tuple(_type_check(t, msg) for t in constraints) - if bound: - self.__bound__ = _type_check(bound, "Bound must be a type.") - else: - self.__bound__ = None - - def _get_type_vars(self, tvars): - if self not in tvars: - tvars.append(self) - - def __repr__(self): - if self.__covariant__: - prefix = '+' - elif self.__contravariant__: - prefix = '-' - else: - prefix = '~' - return prefix + self.__name__ - - def __instancecheck__(self, instance): - raise TypeError("Type variables cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - raise TypeError("Type variables cannot be used with issubclass().") - - -# Some unconstrained type variables. These are used by the container types. -# (These are not for export.) -T = TypeVar('T') # Any type. -KT = TypeVar('KT') # Key type. -VT = TypeVar('VT') # Value type. -T_co = TypeVar('T_co', covariant=True) # Any type covariant containers. -V_co = TypeVar('V_co', covariant=True) # Any type covariant containers. -VT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers. -T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant. - -# A useful type variable with constraints. This represents string types. -# (This one *is* for export!) -AnyStr = TypeVar('AnyStr', bytes, unicode) - - -def _replace_arg(arg, tvars, args): - """An internal helper function: replace arg if it is a type variable - found in tvars with corresponding substitution from args or - with corresponding substitution sub-tree if arg is a generic type. - """ - - if tvars is None: - tvars = [] - if hasattr(arg, '_subs_tree') and isinstance(arg, (GenericMeta, _TypingBase)): - return arg._subs_tree(tvars, args) - if isinstance(arg, TypeVar): - for i, tvar in enumerate(tvars): - if arg == tvar: - return args[i] - return arg - - -# Special typing constructs Union, Optional, Generic, Callable and Tuple -# use three special attributes for internal bookkeeping of generic types: -# * __parameters__ is a tuple of unique free type parameters of a generic -# type, for example, Dict[T, T].__parameters__ == (T,); -# * __origin__ keeps a reference to a type that was subscripted, -# e.g., Union[T, int].__origin__ == Union; -# * __args__ is a tuple of all arguments used in subscripting, -# e.g., Dict[T, int].__args__ == (T, int). - - -def _subs_tree(cls, tvars=None, args=None): - """An internal helper function: calculate substitution tree - for generic cls after replacing its type parameters with - substitutions in tvars -> args (if any). - Repeat the same following __origin__'s. - - Return a list of arguments with all possible substitutions - performed. Arguments that are generic classes themselves are represented - as tuples (so that no new classes are created by this function). - For example: _subs_tree(List[Tuple[int, T]][str]) == [(Tuple, int, str)] - """ - - if cls.__origin__ is None: - return cls - # Make of chain of origins (i.e. cls -> cls.__origin__) - current = cls.__origin__ - orig_chain = [] - while current.__origin__ is not None: - orig_chain.append(current) - current = current.__origin__ - # Replace type variables in __args__ if asked ... - tree_args = [] - for arg in cls.__args__: - tree_args.append(_replace_arg(arg, tvars, args)) - # ... then continue replacing down the origin chain. - for ocls in orig_chain: - new_tree_args = [] - for arg in ocls.__args__: - new_tree_args.append(_replace_arg(arg, ocls.__parameters__, tree_args)) - tree_args = new_tree_args - return tree_args - - -def _remove_dups_flatten(parameters): - """An internal helper for Union creation and substitution: flatten Union's - among parameters, then remove duplicates and strict subclasses. - """ - - # Flatten out Union[Union[...], ...]. - params = [] - for p in parameters: - if isinstance(p, _Union) and p.__origin__ is Union: - params.extend(p.__args__) - elif isinstance(p, tuple) and len(p) > 0 and p[0] is Union: - params.extend(p[1:]) - else: - params.append(p) - # Weed out strict duplicates, preserving the first of each occurrence. - all_params = set(params) - if len(all_params) < len(params): - new_params = [] - for t in params: - if t in all_params: - new_params.append(t) - all_params.remove(t) - params = new_params - assert not all_params, all_params - # Weed out subclasses. - # E.g. Union[int, Employee, Manager] == Union[int, Employee]. - # If object is present it will be sole survivor among proper classes. - # Never discard type variables. - # (In particular, Union[str, AnyStr] != AnyStr.) - all_params = set(params) - for t1 in params: - if not isinstance(t1, type): - continue - if any(isinstance(t2, type) and issubclass(t1, t2) - for t2 in all_params - {t1} - if not (isinstance(t2, GenericMeta) and - t2.__origin__ is not None)): - all_params.remove(t1) - return tuple(t for t in params if t in all_params) - - -def _check_generic(cls, parameters): - # Check correct count for parameters of a generic cls (internal helper). - if not cls.__parameters__: - raise TypeError("%s is not a generic class" % repr(cls)) - alen = len(parameters) - elen = len(cls.__parameters__) - if alen != elen: - raise TypeError("Too %s parameters for %s; actual %s, expected %s" % - ("many" if alen > elen else "few", repr(cls), alen, elen)) - - -_cleanups = [] - - -def _tp_cache(func): - maxsize = 128 - cache = {} - _cleanups.append(cache.clear) - - @functools.wraps(func) - def inner(*args): - key = args - try: - return cache[key] - except TypeError: - # Assume it's an unhashable argument. - return func(*args) - except KeyError: - value = func(*args) - if len(cache) >= maxsize: - # If the cache grows too much, just start over. - cache.clear() - cache[key] = value - return value - - return inner - - -class UnionMeta(TypingMeta): - """Metaclass for Union.""" - - def __new__(cls, name, bases, namespace): - cls.assert_no_subclassing(bases) - return super(UnionMeta, cls).__new__(cls, name, bases, namespace) - - -class _Union(_FinalTypingBase): - """Union type; Union[X, Y] means either X or Y. - - To define a union, use e.g. Union[int, str]. Details: - - - The arguments must be types and there must be at least one. - - - None as an argument is a special case and is replaced by - type(None). - - - Unions of unions are flattened, e.g.:: - - Union[Union[int, str], float] == Union[int, str, float] - - - Unions of a single argument vanish, e.g.:: - - Union[int] == int # The constructor actually returns int - - - Redundant arguments are skipped, e.g.:: - - Union[int, str, int] == Union[int, str] - - - When comparing unions, the argument order is ignored, e.g.:: - - Union[int, str] == Union[str, int] - - - When two arguments have a subclass relationship, the least - derived argument is kept, e.g.:: - - class Employee: pass - class Manager(Employee): pass - Union[int, Employee, Manager] == Union[int, Employee] - Union[Manager, int, Employee] == Union[int, Employee] - Union[Employee, Manager] == Employee - - - Similar for object:: - - Union[int, object] == object - - - You cannot subclass or instantiate a union. - - - You can use Optional[X] as a shorthand for Union[X, None]. - """ - - __metaclass__ = UnionMeta - __slots__ = ('__parameters__', '__args__', '__origin__', '__tree_hash__') - - def __new__(cls, parameters=None, origin=None, *args, **kwds): - self = super(_Union, cls).__new__(cls, parameters, origin, *args, **kwds) - if origin is None: - self.__parameters__ = None - self.__args__ = None - self.__origin__ = None - self.__tree_hash__ = hash(frozenset(('Union',))) - return self - if not isinstance(parameters, tuple): - raise TypeError("Expected parameters=") - if origin is Union: - parameters = _remove_dups_flatten(parameters) - # It's not a union if there's only one type left. - if len(parameters) == 1: - return parameters[0] - self.__parameters__ = _type_vars(parameters) - self.__args__ = parameters - self.__origin__ = origin - # Pre-calculate the __hash__ on instantiation. - # This improves speed for complex substitutions. - subs_tree = self._subs_tree() - if isinstance(subs_tree, tuple): - self.__tree_hash__ = hash(frozenset(subs_tree)) - else: - self.__tree_hash__ = hash(subs_tree) - return self - - def _eval_type(self, globalns, localns): - if self.__args__ is None: - return self - ev_args = tuple(_eval_type(t, globalns, localns) for t in self.__args__) - ev_origin = _eval_type(self.__origin__, globalns, localns) - if ev_args == self.__args__ and ev_origin == self.__origin__: - # Everything is already evaluated. - return self - return self.__class__(ev_args, ev_origin, _root=True) - - def _get_type_vars(self, tvars): - if self.__origin__ and self.__parameters__: - _get_type_vars(self.__parameters__, tvars) - - def __repr__(self): - if self.__origin__ is None: - return super(_Union, self).__repr__() - tree = self._subs_tree() - if not isinstance(tree, tuple): - return repr(tree) - return tree[0]._tree_repr(tree) - - def _tree_repr(self, tree): - arg_list = [] - for arg in tree[1:]: - if not isinstance(arg, tuple): - arg_list.append(_type_repr(arg)) - else: - arg_list.append(arg[0]._tree_repr(arg)) - return super(_Union, self).__repr__() + '[%s]' % ', '.join(arg_list) - - @_tp_cache - def __getitem__(self, parameters): - if parameters == (): - raise TypeError("Cannot take a Union of no types.") - if not isinstance(parameters, tuple): - parameters = (parameters,) - if self.__origin__ is None: - msg = "Union[arg, ...]: each arg must be a type." - else: - msg = "Parameters to generic types must be types." - parameters = tuple(_type_check(p, msg) for p in parameters) - if self is not Union: - _check_generic(self, parameters) - return self.__class__(parameters, origin=self, _root=True) - - def _subs_tree(self, tvars=None, args=None): - if self is Union: - return Union # Nothing to substitute - tree_args = _subs_tree(self, tvars, args) - tree_args = _remove_dups_flatten(tree_args) - if len(tree_args) == 1: - return tree_args[0] # Union of a single type is that type - return (Union,) + tree_args - - def __eq__(self, other): - if isinstance(other, _Union): - return self.__tree_hash__ == other.__tree_hash__ - elif self is not Union: - return self._subs_tree() == other - else: - return self is other - - def __hash__(self): - return self.__tree_hash__ - - def __instancecheck__(self, obj): - raise TypeError("Unions cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - raise TypeError("Unions cannot be used with issubclass().") - - -Union = _Union(_root=True) - - -class OptionalMeta(TypingMeta): - """Metaclass for Optional.""" - - def __new__(cls, name, bases, namespace): - cls.assert_no_subclassing(bases) - return super(OptionalMeta, cls).__new__(cls, name, bases, namespace) - - -class _Optional(_FinalTypingBase): - """Optional type. - - Optional[X] is equivalent to Union[X, None]. - """ - - __metaclass__ = OptionalMeta - __slots__ = () - - @_tp_cache - def __getitem__(self, arg): - arg = _type_check(arg, "Optional[t] requires a single type.") - return Union[arg, type(None)] - - -Optional = _Optional(_root=True) - - -def _gorg(a): - """Return the farthest origin of a generic class (internal helper).""" - assert isinstance(a, GenericMeta) - while a.__origin__ is not None: - a = a.__origin__ - return a - - -def _geqv(a, b): - """Return whether two generic classes are equivalent (internal helper). - - The intention is to consider generic class X and any of its - parameterized forms (X[T], X[int], etc.) as equivalent. - - However, X is not equivalent to a subclass of X. - - The relation is reflexive, symmetric and transitive. - """ - assert isinstance(a, GenericMeta) and isinstance(b, GenericMeta) - # Reduce each to its origin. - return _gorg(a) is _gorg(b) - - -def _next_in_mro(cls): - """Helper for Generic.__new__. - - Returns the class after the last occurrence of Generic or - Generic[...] in cls.__mro__. - """ - next_in_mro = object - # Look for the last occurrence of Generic or Generic[...]. - for i, c in enumerate(cls.__mro__[:-1]): - if isinstance(c, GenericMeta) and _gorg(c) is Generic: - next_in_mro = cls.__mro__[i + 1] - return next_in_mro - - -def _make_subclasshook(cls): - """Construct a __subclasshook__ callable that incorporates - the associated __extra__ class in subclass checks performed - against cls. - """ - if isinstance(cls.__extra__, abc.ABCMeta): - # The logic mirrors that of ABCMeta.__subclasscheck__. - # Registered classes need not be checked here because - # cls and its extra share the same _abc_registry. - def __extrahook__(cls, subclass): - res = cls.__extra__.__subclasshook__(subclass) - if res is not NotImplemented: - return res - if cls.__extra__ in getattr(subclass, '__mro__', ()): - return True - for scls in cls.__extra__.__subclasses__(): - if isinstance(scls, GenericMeta): - continue - if issubclass(subclass, scls): - return True - return NotImplemented - else: - # For non-ABC extras we'll just call issubclass(). - def __extrahook__(cls, subclass): - if cls.__extra__ and issubclass(subclass, cls.__extra__): - return True - return NotImplemented - return classmethod(__extrahook__) - - -class GenericMeta(TypingMeta, abc.ABCMeta): - """Metaclass for generic types. - - This is a metaclass for typing.Generic and generic ABCs defined in - typing module. User defined subclasses of GenericMeta can override - __new__ and invoke super().__new__. Note that GenericMeta.__new__ - has strict rules on what is allowed in its bases argument: - * plain Generic is disallowed in bases; - * Generic[...] should appear in bases at most once; - * if Generic[...] is present, then it should list all type variables - that appear in other bases. - In addition, type of all generic bases is erased, e.g., C[int] is - stripped to plain C. - """ - - def __new__(cls, name, bases, namespace, - tvars=None, args=None, origin=None, extra=None, orig_bases=None): - """Create a new generic class. GenericMeta.__new__ accepts - keyword arguments that are used for internal bookkeeping, therefore - an override should pass unused keyword arguments to super(). - """ - if tvars is not None: - # Called from __getitem__() below. - assert origin is not None - assert all(isinstance(t, TypeVar) for t in tvars), tvars - else: - # Called from class statement. - assert tvars is None, tvars - assert args is None, args - assert origin is None, origin - - # Get the full set of tvars from the bases. - tvars = _type_vars(bases) - # Look for Generic[T1, ..., Tn]. - # If found, tvars must be a subset of it. - # If not found, tvars is it. - # Also check for and reject plain Generic, - # and reject multiple Generic[...]. - gvars = None - for base in bases: - if base is Generic: - raise TypeError("Cannot inherit from plain Generic") - if (isinstance(base, GenericMeta) and - base.__origin__ is Generic): - if gvars is not None: - raise TypeError( - "Cannot inherit from Generic[...] multiple types.") - gvars = base.__parameters__ - if gvars is None: - gvars = tvars - else: - tvarset = set(tvars) - gvarset = set(gvars) - if not tvarset <= gvarset: - raise TypeError( - "Some type variables (%s) " - "are not listed in Generic[%s]" % - (", ".join(str(t) for t in tvars if t not in gvarset), - ", ".join(str(g) for g in gvars))) - tvars = gvars - - initial_bases = bases - if extra is None: - extra = namespace.get('__extra__') - if extra is not None and type(extra) is abc.ABCMeta and extra not in bases: - bases = (extra,) + bases - bases = tuple(_gorg(b) if isinstance(b, GenericMeta) else b for b in bases) - - # remove bare Generic from bases if there are other generic bases - if any(isinstance(b, GenericMeta) and b is not Generic for b in bases): - bases = tuple(b for b in bases if b is not Generic) - namespace.update({'__origin__': origin, '__extra__': extra}) - self = super(GenericMeta, cls).__new__(cls, name, bases, namespace) - - self.__parameters__ = tvars - # Be prepared that GenericMeta will be subclassed by TupleMeta - # and CallableMeta, those two allow ..., (), or [] in __args___. - self.__args__ = tuple(Ellipsis if a is _TypingEllipsis else - () if a is _TypingEmpty else - a for a in args) if args else None - # Speed hack (https://github.com/python/typing/issues/196). - self.__next_in_mro__ = _next_in_mro(self) - # Preserve base classes on subclassing (__bases__ are type erased now). - if orig_bases is None: - self.__orig_bases__ = initial_bases - - # This allows unparameterized generic collections to be used - # with issubclass() and isinstance() in the same way as their - # collections.abc counterparts (e.g., isinstance([], Iterable)). - if ( - '__subclasshook__' not in namespace and extra or - # allow overriding - getattr(self.__subclasshook__, '__name__', '') == '__extrahook__' - ): - self.__subclasshook__ = _make_subclasshook(self) - - if origin and hasattr(origin, '__qualname__'): # Fix for Python 3.2. - self.__qualname__ = origin.__qualname__ - self.__tree_hash__ = (hash(self._subs_tree()) if origin else - super(GenericMeta, self).__hash__()) - return self - - def __init__(self, *args, **kwargs): - super(GenericMeta, self).__init__(*args, **kwargs) - if isinstance(self.__extra__, abc.ABCMeta): - self._abc_registry = self.__extra__._abc_registry - self._abc_cache = self.__extra__._abc_cache - elif self.__origin__ is not None: - self._abc_registry = self.__origin__._abc_registry - self._abc_cache = self.__origin__._abc_cache - - # _abc_negative_cache and _abc_negative_cache_version - # realised as descriptors, since GenClass[t1, t2, ...] always - # share subclass info with GenClass. - # This is an important memory optimization. - @property - def _abc_negative_cache(self): - if isinstance(self.__extra__, abc.ABCMeta): - return self.__extra__._abc_negative_cache - return _gorg(self)._abc_generic_negative_cache - - @_abc_negative_cache.setter - def _abc_negative_cache(self, value): - if self.__origin__ is None: - if isinstance(self.__extra__, abc.ABCMeta): - self.__extra__._abc_negative_cache = value - else: - self._abc_generic_negative_cache = value - - @property - def _abc_negative_cache_version(self): - if isinstance(self.__extra__, abc.ABCMeta): - return self.__extra__._abc_negative_cache_version - return _gorg(self)._abc_generic_negative_cache_version - - @_abc_negative_cache_version.setter - def _abc_negative_cache_version(self, value): - if self.__origin__ is None: - if isinstance(self.__extra__, abc.ABCMeta): - self.__extra__._abc_negative_cache_version = value - else: - self._abc_generic_negative_cache_version = value - - def _get_type_vars(self, tvars): - if self.__origin__ and self.__parameters__: - _get_type_vars(self.__parameters__, tvars) - - def _eval_type(self, globalns, localns): - ev_origin = (self.__origin__._eval_type(globalns, localns) - if self.__origin__ else None) - ev_args = tuple(_eval_type(a, globalns, localns) for a - in self.__args__) if self.__args__ else None - if ev_origin == self.__origin__ and ev_args == self.__args__: - return self - return self.__class__(self.__name__, - self.__bases__, - dict(self.__dict__), - tvars=_type_vars(ev_args) if ev_args else None, - args=ev_args, - origin=ev_origin, - extra=self.__extra__, - orig_bases=self.__orig_bases__) - - def __repr__(self): - if self.__origin__ is None: - return super(GenericMeta, self).__repr__() - return self._tree_repr(self._subs_tree()) - - def _tree_repr(self, tree): - arg_list = [] - for arg in tree[1:]: - if arg == (): - arg_list.append('()') - elif not isinstance(arg, tuple): - arg_list.append(_type_repr(arg)) - else: - arg_list.append(arg[0]._tree_repr(arg)) - return super(GenericMeta, self).__repr__() + '[%s]' % ', '.join(arg_list) - - def _subs_tree(self, tvars=None, args=None): - if self.__origin__ is None: - return self - tree_args = _subs_tree(self, tvars, args) - return (_gorg(self),) + tuple(tree_args) - - def __eq__(self, other): - if not isinstance(other, GenericMeta): - return NotImplemented - if self.__origin__ is None or other.__origin__ is None: - return self is other - return self.__tree_hash__ == other.__tree_hash__ - - def __hash__(self): - return self.__tree_hash__ - - @_tp_cache - def __getitem__(self, params): - if not isinstance(params, tuple): - params = (params,) - if not params and not _gorg(self) is Tuple: - raise TypeError( - "Parameter list to %s[...] cannot be empty" % _qualname(self)) - msg = "Parameters to generic types must be types." - params = tuple(_type_check(p, msg) for p in params) - if self is Generic: - # Generic can only be subscripted with unique type variables. - if not all(isinstance(p, TypeVar) for p in params): - raise TypeError( - "Parameters to Generic[...] must all be type variables") - if len(set(params)) != len(params): - raise TypeError( - "Parameters to Generic[...] must all be unique") - tvars = params - args = params - elif self in (Tuple, Callable): - tvars = _type_vars(params) - args = params - elif self is _Protocol: - # _Protocol is internal, don't check anything. - tvars = params - args = params - elif self.__origin__ in (Generic, _Protocol): - # Can't subscript Generic[...] or _Protocol[...]. - raise TypeError("Cannot subscript already-subscripted %s" % - repr(self)) - else: - # Subscripting a regular Generic subclass. - _check_generic(self, params) - tvars = _type_vars(params) - args = params - - prepend = (self,) if self.__origin__ is None else () - return self.__class__(self.__name__, - prepend + self.__bases__, - dict(self.__dict__), - tvars=tvars, - args=args, - origin=self, - extra=self.__extra__, - orig_bases=self.__orig_bases__) - - def __subclasscheck__(self, cls): - if self.__origin__ is not None: - if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools']: - raise TypeError("Parameterized generics cannot be used with class " - "or instance checks") - return False - if self is Generic: - raise TypeError("Class %r cannot be used with class " - "or instance checks" % self) - return super(GenericMeta, self).__subclasscheck__(cls) - - def __instancecheck__(self, instance): - # Since we extend ABC.__subclasscheck__ and - # ABC.__instancecheck__ inlines the cache checking done by the - # latter, we must extend __instancecheck__ too. For simplicity - # we just skip the cache check -- instance checks for generic - # classes are supposed to be rare anyways. - if not isinstance(instance, type): - return issubclass(instance.__class__, self) - return False - - def __copy__(self): - return self.__class__(self.__name__, self.__bases__, dict(self.__dict__), - self.__parameters__, self.__args__, self.__origin__, - self.__extra__, self.__orig_bases__) - - def __setattr__(self, attr, value): - # We consider all the subscripted genrics as proxies for original class - if ( - attr.startswith('__') and attr.endswith('__') or - attr.startswith('_abc_') - ): - super(GenericMeta, self).__setattr__(attr, value) - else: - super(GenericMeta, _gorg(self)).__setattr__(attr, value) - - -# Prevent checks for Generic to crash when defining Generic. -Generic = None - - -def _generic_new(base_cls, cls, *args, **kwds): - # Assure type is erased on instantiation, - # but attempt to store it in __orig_class__ - if cls.__origin__ is None: - return base_cls.__new__(cls) - else: - origin = _gorg(cls) - obj = base_cls.__new__(origin) - try: - obj.__orig_class__ = cls - except AttributeError: - pass - obj.__init__(*args, **kwds) - return obj - - -class Generic(object): - """Abstract base class for generic types. - - A generic type is typically declared by inheriting from - this class parameterized with one or more type variables. - For example, a generic mapping type might be defined as:: - - class Mapping(Generic[KT, VT]): - def __getitem__(self, key: KT) -> VT: - ... - # Etc. - - This class can then be used as follows:: - - def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: - try: - return mapping[key] - except KeyError: - return default - """ - - __metaclass__ = GenericMeta - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Generic): - raise TypeError("Type Generic cannot be instantiated; " - "it can be used only as a base class") - return _generic_new(cls.__next_in_mro__, cls, *args, **kwds) - - -class _TypingEmpty(object): - """Internal placeholder for () or []. Used by TupleMeta and CallableMeta - to allow empty list/tuple in specific places, without allowing them - to sneak in where prohibited. - """ - - -class _TypingEllipsis(object): - """Internal placeholder for ... (ellipsis).""" - - -class TupleMeta(GenericMeta): - """Metaclass for Tuple (internal).""" - - @_tp_cache - def __getitem__(self, parameters): - if self.__origin__ is not None or not _geqv(self, Tuple): - # Normal generic rules apply if this is not the first subscription - # or a subscription of a subclass. - return super(TupleMeta, self).__getitem__(parameters) - if parameters == (): - return super(TupleMeta, self).__getitem__((_TypingEmpty,)) - if not isinstance(parameters, tuple): - parameters = (parameters,) - if len(parameters) == 2 and parameters[1] is Ellipsis: - msg = "Tuple[t, ...]: t must be a type." - p = _type_check(parameters[0], msg) - return super(TupleMeta, self).__getitem__((p, _TypingEllipsis)) - msg = "Tuple[t0, t1, ...]: each t must be a type." - parameters = tuple(_type_check(p, msg) for p in parameters) - return super(TupleMeta, self).__getitem__(parameters) - - def __instancecheck__(self, obj): - if self.__args__ is None: - return isinstance(obj, tuple) - raise TypeError("Parameterized Tuple cannot be used " - "with isinstance().") - - def __subclasscheck__(self, cls): - if self.__args__ is None: - return issubclass(cls, tuple) - raise TypeError("Parameterized Tuple cannot be used " - "with issubclass().") - - -class Tuple(tuple): - """Tuple type; Tuple[X, Y] is the cross-product type of X and Y. - - Example: Tuple[T1, T2] is a tuple of two elements corresponding - to type variables T1 and T2. Tuple[int, float, str] is a tuple - of an int, a float and a string. - - To specify a variable-length tuple of homogeneous type, use Tuple[T, ...]. - """ - - __metaclass__ = TupleMeta - __extra__ = tuple - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Tuple): - raise TypeError("Type Tuple cannot be instantiated; " - "use tuple() instead") - return _generic_new(tuple, cls, *args, **kwds) - - -class CallableMeta(GenericMeta): - """ Metaclass for Callable.""" - - def __repr__(self): - if self.__origin__ is None: - return super(CallableMeta, self).__repr__() - return self._tree_repr(self._subs_tree()) - - def _tree_repr(self, tree): - if _gorg(self) is not Callable: - return super(CallableMeta, self)._tree_repr(tree) - # For actual Callable (not its subclass) we override - # super(CallableMeta, self)._tree_repr() for nice formatting. - arg_list = [] - for arg in tree[1:]: - if not isinstance(arg, tuple): - arg_list.append(_type_repr(arg)) - else: - arg_list.append(arg[0]._tree_repr(arg)) - if arg_list[0] == '...': - return repr(tree[0]) + '[..., %s]' % arg_list[1] - return (repr(tree[0]) + - '[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1])) - - def __getitem__(self, parameters): - """A thin wrapper around __getitem_inner__ to provide the latter - with hashable arguments to improve speed. - """ - - if self.__origin__ is not None or not _geqv(self, Callable): - return super(CallableMeta, self).__getitem__(parameters) - if not isinstance(parameters, tuple) or len(parameters) != 2: - raise TypeError("Callable must be used as " - "Callable[[arg, ...], result].") - args, result = parameters - if args is Ellipsis: - parameters = (Ellipsis, result) - else: - if not isinstance(args, list): - raise TypeError("Callable[args, result]: args must be a list." - " Got %.100r." % (args,)) - parameters = (tuple(args), result) - return self.__getitem_inner__(parameters) - - @_tp_cache - def __getitem_inner__(self, parameters): - args, result = parameters - msg = "Callable[args, result]: result must be a type." - result = _type_check(result, msg) - if args is Ellipsis: - return super(CallableMeta, self).__getitem__((_TypingEllipsis, result)) - msg = "Callable[[arg, ...], result]: each arg must be a type." - args = tuple(_type_check(arg, msg) for arg in args) - parameters = args + (result,) - return super(CallableMeta, self).__getitem__(parameters) - - -class Callable(object): - """Callable type; Callable[[int], str] is a function of (int) -> str. - - The subscription syntax must always be used with exactly two - values: the argument list and the return type. The argument list - must be a list of types or ellipsis; the return type must be a single type. - - There is no syntax to indicate optional or keyword arguments, - such function types are rarely used as callback types. - """ - - __metaclass__ = CallableMeta - __extra__ = collections_abc.Callable - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Callable): - raise TypeError("Type Callable cannot be instantiated; " - "use a non-abstract subclass instead") - return _generic_new(cls.__next_in_mro__, cls, *args, **kwds) - - -def cast(typ, val): - """Cast a value to a type. - - This returns the value unchanged. To the type checker this - signals that the return value has the designated type, but at - runtime we intentionally don't check anything (we want this - to be as fast as possible). - """ - return val - - -def _get_defaults(func): - """Internal helper to extract the default arguments, by name.""" - code = func.__code__ - pos_count = code.co_argcount - arg_names = code.co_varnames - arg_names = arg_names[:pos_count] - defaults = func.__defaults__ or () - kwdefaults = func.__kwdefaults__ - res = dict(kwdefaults) if kwdefaults else {} - pos_offset = pos_count - len(defaults) - for name, value in zip(arg_names[pos_offset:], defaults): - assert name not in res - res[name] = value - return res - - -def get_type_hints(obj, globalns=None, localns=None): - """In Python 2 this is not supported and always returns None.""" - return None - - -def no_type_check(arg): - """Decorator to indicate that annotations are not type hints. - - The argument must be a class or function; if it is a class, it - applies recursively to all methods and classes defined in that class - (but not to methods defined in its superclasses or subclasses). - - This mutates the function(s) or class(es) in place. - """ - if isinstance(arg, type): - arg_attrs = arg.__dict__.copy() - for attr, val in arg.__dict__.items(): - if val in arg.__bases__: - arg_attrs.pop(attr) - for obj in arg_attrs.values(): - if isinstance(obj, types.FunctionType): - obj.__no_type_check__ = True - if isinstance(obj, type): - no_type_check(obj) - try: - arg.__no_type_check__ = True - except TypeError: # built-in classes - pass - return arg - - -def no_type_check_decorator(decorator): - """Decorator to give another decorator the @no_type_check effect. - - This wraps the decorator with something that wraps the decorated - function in @no_type_check. - """ - - @functools.wraps(decorator) - def wrapped_decorator(*args, **kwds): - func = decorator(*args, **kwds) - func = no_type_check(func) - return func - - return wrapped_decorator - - -def _overload_dummy(*args, **kwds): - """Helper for @overload to raise when called.""" - raise NotImplementedError( - "You should not call an overloaded function. " - "A series of @overload-decorated functions " - "outside a stub module should always be followed " - "by an implementation that is not @overload-ed.") - - -def overload(func): - """Decorator for overloaded functions/methods. - - In a stub file, place two or more stub definitions for the same - function in a row, each decorated with @overload. For example: - - @overload - def utf8(value: None) -> None: ... - @overload - def utf8(value: bytes) -> bytes: ... - @overload - def utf8(value: str) -> bytes: ... - - In a non-stub file (i.e. a regular .py file), do the same but - follow it with an implementation. The implementation should *not* - be decorated with @overload. For example: - - @overload - def utf8(value: None) -> None: ... - @overload - def utf8(value: bytes) -> bytes: ... - @overload - def utf8(value: str) -> bytes: ... - def utf8(value): - # implementation goes here - """ - return _overload_dummy - - -class _ProtocolMeta(GenericMeta): - """Internal metaclass for _Protocol. - - This exists so _Protocol classes can be generic without deriving - from Generic. - """ - - def __instancecheck__(self, obj): - if _Protocol not in self.__bases__: - return super(_ProtocolMeta, self).__instancecheck__(obj) - raise TypeError("Protocols cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - if not self._is_protocol: - # No structural checks since this isn't a protocol. - return NotImplemented - - if self is _Protocol: - # Every class is a subclass of the empty protocol. - return True - - # Find all attributes defined in the protocol. - attrs = self._get_protocol_attrs() - - for attr in attrs: - if not any(attr in d.__dict__ for d in cls.__mro__): - return False - return True - - def _get_protocol_attrs(self): - # Get all Protocol base classes. - protocol_bases = [] - for c in self.__mro__: - if getattr(c, '_is_protocol', False) and c.__name__ != '_Protocol': - protocol_bases.append(c) - - # Get attributes included in protocol. - attrs = set() - for base in protocol_bases: - for attr in base.__dict__.keys(): - # Include attributes not defined in any non-protocol bases. - for c in self.__mro__: - if (c is not base and attr in c.__dict__ and - not getattr(c, '_is_protocol', False)): - break - else: - if (not attr.startswith('_abc_') and - attr != '__abstractmethods__' and - attr != '_is_protocol' and - attr != '__dict__' and - attr != '__args__' and - attr != '__slots__' and - attr != '_get_protocol_attrs' and - attr != '__next_in_mro__' and - attr != '__parameters__' and - attr != '__origin__' and - attr != '__orig_bases__' and - attr != '__extra__' and - attr != '__tree_hash__' and - attr != '__module__'): - attrs.add(attr) - - return attrs - - -class _Protocol(object): - """Internal base class for protocol classes. - - This implements a simple-minded structural issubclass check - (similar but more general than the one-offs in collections.abc - such as Hashable). - """ - - __metaclass__ = _ProtocolMeta - __slots__ = () - - _is_protocol = True - - -# Various ABCs mimicking those in collections.abc. -# A few are simply re-exported for completeness. - -Hashable = collections_abc.Hashable # Not generic. - - -class Iterable(Generic[T_co]): - __slots__ = () - __extra__ = collections_abc.Iterable - - -class Iterator(Iterable[T_co]): - __slots__ = () - __extra__ = collections_abc.Iterator - - -class SupportsInt(_Protocol): - __slots__ = () - - @abstractmethod - def __int__(self): - pass - - -class SupportsFloat(_Protocol): - __slots__ = () - - @abstractmethod - def __float__(self): - pass - - -class SupportsComplex(_Protocol): - __slots__ = () - - @abstractmethod - def __complex__(self): - pass - - -class SupportsAbs(_Protocol[T_co]): - __slots__ = () - - @abstractmethod - def __abs__(self): - pass - - -if hasattr(collections_abc, 'Reversible'): - class Reversible(Iterable[T_co]): - __slots__ = () - __extra__ = collections_abc.Reversible -else: - class Reversible(_Protocol[T_co]): - __slots__ = () - - @abstractmethod - def __reversed__(self): - pass - - -Sized = collections_abc.Sized # Not generic. - - -class Container(Generic[T_co]): - __slots__ = () - __extra__ = collections_abc.Container - - -# Callable was defined earlier. - - -class AbstractSet(Sized, Iterable[T_co], Container[T_co]): - __slots__ = () - __extra__ = collections_abc.Set - - -class MutableSet(AbstractSet[T]): - __slots__ = () - __extra__ = collections_abc.MutableSet - - -# NOTE: It is only covariant in the value type. -class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co]): - __slots__ = () - __extra__ = collections_abc.Mapping - - -class MutableMapping(Mapping[KT, VT]): - __slots__ = () - __extra__ = collections_abc.MutableMapping - - -if hasattr(collections_abc, 'Reversible'): - class Sequence(Sized, Reversible[T_co], Container[T_co]): - __slots__ = () - __extra__ = collections_abc.Sequence -else: - class Sequence(Sized, Iterable[T_co], Container[T_co]): - __slots__ = () - __extra__ = collections_abc.Sequence - - -class MutableSequence(Sequence[T]): - __slots__ = () - __extra__ = collections_abc.MutableSequence - - -class ByteString(Sequence[int]): - pass - - -ByteString.register(str) -ByteString.register(bytearray) - - -class List(list, MutableSequence[T]): - __slots__ = () - __extra__ = list - - def __new__(cls, *args, **kwds): - if _geqv(cls, List): - raise TypeError("Type List cannot be instantiated; " - "use list() instead") - return _generic_new(list, cls, *args, **kwds) - - -class Deque(collections.deque, MutableSequence[T]): - __slots__ = () - __extra__ = collections.deque - - def __new__(cls, *args, **kwds): - if _geqv(cls, Deque): - return collections.deque(*args, **kwds) - return _generic_new(collections.deque, cls, *args, **kwds) - - -class Set(set, MutableSet[T]): - __slots__ = () - __extra__ = set - - def __new__(cls, *args, **kwds): - if _geqv(cls, Set): - raise TypeError("Type Set cannot be instantiated; " - "use set() instead") - return _generic_new(set, cls, *args, **kwds) - - -class FrozenSet(frozenset, AbstractSet[T_co]): - __slots__ = () - __extra__ = frozenset - - def __new__(cls, *args, **kwds): - if _geqv(cls, FrozenSet): - raise TypeError("Type FrozenSet cannot be instantiated; " - "use frozenset() instead") - return _generic_new(frozenset, cls, *args, **kwds) - - -class MappingView(Sized, Iterable[T_co]): - __slots__ = () - __extra__ = collections_abc.MappingView - - -class KeysView(MappingView[KT], AbstractSet[KT]): - __slots__ = () - __extra__ = collections_abc.KeysView - - -class ItemsView(MappingView[Tuple[KT, VT_co]], - AbstractSet[Tuple[KT, VT_co]], - Generic[KT, VT_co]): - __slots__ = () - __extra__ = collections_abc.ItemsView - - -class ValuesView(MappingView[VT_co]): - __slots__ = () - __extra__ = collections_abc.ValuesView - - -class Dict(dict, MutableMapping[KT, VT]): - __slots__ = () - __extra__ = dict - - def __new__(cls, *args, **kwds): - if _geqv(cls, Dict): - raise TypeError("Type Dict cannot be instantiated; " - "use dict() instead") - return _generic_new(dict, cls, *args, **kwds) - - -class DefaultDict(collections.defaultdict, MutableMapping[KT, VT]): - __slots__ = () - __extra__ = collections.defaultdict - - def __new__(cls, *args, **kwds): - if _geqv(cls, DefaultDict): - return collections.defaultdict(*args, **kwds) - return _generic_new(collections.defaultdict, cls, *args, **kwds) - - -class Counter(collections.Counter, Dict[T, int]): - __slots__ = () - __extra__ = collections.Counter - - def __new__(cls, *args, **kwds): - if _geqv(cls, Counter): - return collections.Counter(*args, **kwds) - return _generic_new(collections.Counter, cls, *args, **kwds) - - -# Determine what base class to use for Generator. -if hasattr(collections_abc, 'Generator'): - # Sufficiently recent versions of 3.5 have a Generator ABC. - _G_base = collections_abc.Generator -else: - # Fall back on the exact type. - _G_base = types.GeneratorType - - -class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co]): - __slots__ = () - __extra__ = _G_base - - def __new__(cls, *args, **kwds): - if _geqv(cls, Generator): - raise TypeError("Type Generator cannot be instantiated; " - "create a subclass instead") - return _generic_new(_G_base, cls, *args, **kwds) - - -# Internal type variable used for Type[]. -CT_co = TypeVar('CT_co', covariant=True, bound=type) - - -# This is not a real generic class. Don't use outside annotations. -class Type(Generic[CT_co]): - """A special construct usable to annotate class objects. - - For example, suppose we have the following classes:: - - class User: ... # Abstract base for User classes - class BasicUser(User): ... - class ProUser(User): ... - class TeamUser(User): ... - - And a function that takes a class argument that's a subclass of - User and returns an instance of the corresponding class:: - - U = TypeVar('U', bound=User) - def new_user(user_class: Type[U]) -> U: - user = user_class() - # (Here we could write the user object to a database) - return user - - joe = new_user(BasicUser) - - At this point the type checker knows that joe has type BasicUser. - """ - __slots__ = () - __extra__ = type - - -def NamedTuple(typename, fields): - """Typed version of namedtuple. - - Usage:: - - Employee = typing.NamedTuple('Employee', [('name', str), ('id', int)]) - - This is equivalent to:: - - Employee = collections.namedtuple('Employee', ['name', 'id']) - - The resulting class has one extra attribute: _field_types, - giving a dict mapping field names to types. (The field names - are in the _fields attribute, which is part of the namedtuple - API.) - """ - fields = [(n, t) for n, t in fields] - cls = collections.namedtuple(typename, [n for n, t in fields]) - cls._field_types = dict(fields) - # Set the module to the caller's module (otherwise it'd be 'typing'). - try: - cls.__module__ = sys._getframe(1).f_globals.get('__name__', '__main__') - except (AttributeError, ValueError): - pass - return cls - - -def NewType(name, tp): - """NewType creates simple unique types with almost zero - runtime overhead. NewType(name, tp) is considered a subtype of tp - by static type checkers. At runtime, NewType(name, tp) returns - a dummy function that simply returns its argument. Usage:: - - UserId = NewType('UserId', int) - - def name_by_id(user_id): - # type: (UserId) -> str - ... - - UserId('user') # Fails type check - - name_by_id(42) # Fails type check - name_by_id(UserId(42)) # OK - - num = UserId(5) + 1 # type: int - """ - - def new_type(x): - return x - - # Some versions of Python 2 complain because of making all strings unicode - new_type.__name__ = str(name) - new_type.__supertype__ = tp - return new_type - - -# Python-version-specific alias (Python 2: unicode; Python 3: str) -Text = unicode - - -# Constant that's True when type checking, but False here. -TYPE_CHECKING = False - - -class IO(Generic[AnyStr]): - """Generic base class for TextIO and BinaryIO. - - This is an abstract, generic version of the return of open(). - - NOTE: This does not distinguish between the different possible - classes (text vs. binary, read vs. write vs. read/write, - append-only, unbuffered). The TextIO and BinaryIO subclasses - below capture the distinctions between text vs. binary, which is - pervasive in the interface; however we currently do not offer a - way to track the other distinctions in the type system. - """ - - __slots__ = () - - @abstractproperty - def mode(self): - pass - - @abstractproperty - def name(self): - pass - - @abstractmethod - def close(self): - pass - - @abstractmethod - def closed(self): - pass - - @abstractmethod - def fileno(self): - pass - - @abstractmethod - def flush(self): - pass - - @abstractmethod - def isatty(self): - pass - - @abstractmethod - def read(self, n=-1): - pass - - @abstractmethod - def readable(self): - pass - - @abstractmethod - def readline(self, limit=-1): - pass - - @abstractmethod - def readlines(self, hint=-1): - pass - - @abstractmethod - def seek(self, offset, whence=0): - pass - - @abstractmethod - def seekable(self): - pass - - @abstractmethod - def tell(self): - pass - - @abstractmethod - def truncate(self, size=None): - pass - - @abstractmethod - def writable(self): - pass - - @abstractmethod - def write(self, s): - pass - - @abstractmethod - def writelines(self, lines): - pass - - @abstractmethod - def __enter__(self): - pass - - @abstractmethod - def __exit__(self, type, value, traceback): - pass - - -class BinaryIO(IO[bytes]): - """Typed version of the return of open() in binary mode.""" - - __slots__ = () - - @abstractmethod - def write(self, s): - pass - - @abstractmethod - def __enter__(self): - pass - - -class TextIO(IO[unicode]): - """Typed version of the return of open() in text mode.""" - - __slots__ = () - - @abstractproperty - def buffer(self): - pass - - @abstractproperty - def encoding(self): - pass - - @abstractproperty - def errors(self): - pass - - @abstractproperty - def line_buffering(self): - pass - - @abstractproperty - def newlines(self): - pass - - @abstractmethod - def __enter__(self): - pass - - -class io(object): - """Wrapper namespace for IO generic classes.""" - - __all__ = ['IO', 'TextIO', 'BinaryIO'] - IO = IO - TextIO = TextIO - BinaryIO = BinaryIO - - -io.__name__ = __name__ + b'.io' -sys.modules[io.__name__] = io - - -Pattern = _TypeAlias('Pattern', AnyStr, type(stdlib_re.compile('')), - lambda p: p.pattern) -Match = _TypeAlias('Match', AnyStr, type(stdlib_re.match('', '')), - lambda m: m.re.pattern) - - -class re(object): - """Wrapper namespace for re type aliases.""" - - __all__ = ['Pattern', 'Match'] - Pattern = Pattern - Match = Match - - -re.__name__ = __name__ + b'.re' -sys.modules[re.__name__] = re diff --git a/lib-typing/3.2/mod_generics_cache.py b/lib-typing/3.2/mod_generics_cache.py deleted file mode 100644 index d9a60b4b28c3..000000000000 --- a/lib-typing/3.2/mod_generics_cache.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Module for testing the behavior of generics across different modules.""" - -from typing import TypeVar, Generic - -T = TypeVar('T') - - -class A(Generic[T]): - pass - - -class B(Generic[T]): - class A(Generic[T]): - pass diff --git a/lib-typing/3.2/test_typing.py b/lib-typing/3.2/test_typing.py deleted file mode 100644 index 586a7870013a..000000000000 --- a/lib-typing/3.2/test_typing.py +++ /dev/null @@ -1,2422 +0,0 @@ -import contextlib -import collections -import pickle -import re -import sys -from unittest import TestCase, main, skipUnless, SkipTest -from copy import copy, deepcopy - -from typing import Any -from typing import TypeVar, AnyStr -from typing import T, KT, VT # Not in __all__. -from typing import Union, Optional -from typing import Tuple, List, MutableMapping -from typing import Callable -from typing import Generic, ClassVar, GenericMeta -from typing import cast -from typing import get_type_hints -from typing import no_type_check, no_type_check_decorator -from typing import Type -from typing import NewType -from typing import NamedTuple -from typing import IO, TextIO, BinaryIO -from typing import Pattern, Match -import abc -import typing -import weakref -try: - import collections.abc as collections_abc -except ImportError: - import collections as collections_abc # Fallback for PY3.2. - - -class BaseTestCase(TestCase): - - def assertIsSubclass(self, cls, class_or_tuple, msg=None): - if not issubclass(cls, class_or_tuple): - message = '%r is not a subclass of %r' % (cls, class_or_tuple) - if msg is not None: - message += ' : %s' % msg - raise self.failureException(message) - - def assertNotIsSubclass(self, cls, class_or_tuple, msg=None): - if issubclass(cls, class_or_tuple): - message = '%r is a subclass of %r' % (cls, class_or_tuple) - if msg is not None: - message += ' : %s' % msg - raise self.failureException(message) - - def clear_caches(self): - for f in typing._cleanups: - f() - - -class Employee: - pass - - -class Manager(Employee): - pass - - -class Founder(Employee): - pass - - -class ManagingFounder(Manager, Founder): - pass - - -class AnyTests(BaseTestCase): - - def test_any_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance(42, Any) - - def test_any_subclass_type_error(self): - with self.assertRaises(TypeError): - issubclass(Employee, Any) - with self.assertRaises(TypeError): - issubclass(Any, Employee) - - def test_repr(self): - self.assertEqual(repr(Any), 'typing.Any') - - def test_errors(self): - with self.assertRaises(TypeError): - issubclass(42, Any) - with self.assertRaises(TypeError): - Any[int] # Any is not a generic type. - - def test_cannot_subclass(self): - with self.assertRaises(TypeError): - class A(Any): - pass - with self.assertRaises(TypeError): - class A(type(Any)): - pass - - def test_cannot_instantiate(self): - with self.assertRaises(TypeError): - Any() - with self.assertRaises(TypeError): - type(Any)() - - def test_any_works_with_alias(self): - # These expressions must simply not fail. - typing.Match[Any] - typing.Pattern[Any] - typing.IO[Any] - - -class TypeVarTests(BaseTestCase): - - def test_basic_plain(self): - T = TypeVar('T') - # T equals itself. - self.assertEqual(T, T) - # T is an instance of TypeVar - self.assertIsInstance(T, TypeVar) - - def test_typevar_instance_type_error(self): - T = TypeVar('T') - with self.assertRaises(TypeError): - isinstance(42, T) - - def test_typevar_subclass_type_error(self): - T = TypeVar('T') - with self.assertRaises(TypeError): - issubclass(int, T) - with self.assertRaises(TypeError): - issubclass(T, int) - - def test_constrained_error(self): - with self.assertRaises(TypeError): - X = TypeVar('X', int) - X - - def test_union_unique(self): - X = TypeVar('X') - Y = TypeVar('Y') - self.assertNotEqual(X, Y) - self.assertEqual(Union[X], X) - self.assertNotEqual(Union[X], Union[X, Y]) - self.assertEqual(Union[X, X], X) - self.assertNotEqual(Union[X, int], Union[X]) - self.assertNotEqual(Union[X, int], Union[int]) - self.assertEqual(Union[X, int].__args__, (X, int)) - self.assertEqual(Union[X, int].__parameters__, (X,)) - self.assertIs(Union[X, int].__origin__, Union) - - def test_union_constrained(self): - A = TypeVar('A', str, bytes) - self.assertNotEqual(Union[A, str], Union[A]) - - def test_repr(self): - self.assertEqual(repr(T), '~T') - self.assertEqual(repr(KT), '~KT') - self.assertEqual(repr(VT), '~VT') - self.assertEqual(repr(AnyStr), '~AnyStr') - T_co = TypeVar('T_co', covariant=True) - self.assertEqual(repr(T_co), '+T_co') - T_contra = TypeVar('T_contra', contravariant=True) - self.assertEqual(repr(T_contra), '-T_contra') - - def test_no_redefinition(self): - self.assertNotEqual(TypeVar('T'), TypeVar('T')) - self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str)) - - def test_cannot_subclass_vars(self): - with self.assertRaises(TypeError): - class V(TypeVar('T')): - pass - - def test_cannot_subclass_var_itself(self): - with self.assertRaises(TypeError): - class V(TypeVar): - pass - - def test_cannot_instantiate_vars(self): - with self.assertRaises(TypeError): - TypeVar('A')() - - def test_bound_errors(self): - with self.assertRaises(TypeError): - TypeVar('X', bound=42) - with self.assertRaises(TypeError): - TypeVar('X', str, float, bound=Employee) - - def test_no_bivariant(self): - with self.assertRaises(ValueError): - TypeVar('T', covariant=True, contravariant=True) - - -class UnionTests(BaseTestCase): - - def test_basics(self): - u = Union[int, float] - self.assertNotEqual(u, Union) - - def test_subclass_error(self): - with self.assertRaises(TypeError): - issubclass(int, Union) - with self.assertRaises(TypeError): - issubclass(Union, int) - with self.assertRaises(TypeError): - issubclass(int, Union[int, str]) - with self.assertRaises(TypeError): - issubclass(Union[int, str], int) - - def test_union_any(self): - u = Union[Any] - self.assertEqual(u, Any) - u1 = Union[int, Any] - u2 = Union[Any, int] - u3 = Union[Any, object] - self.assertEqual(u1, u2) - self.assertNotEqual(u1, Any) - self.assertNotEqual(u2, Any) - self.assertNotEqual(u3, Any) - - def test_union_object(self): - u = Union[object] - self.assertEqual(u, object) - u = Union[int, object] - self.assertEqual(u, object) - u = Union[object, int] - self.assertEqual(u, object) - - def test_unordered(self): - u1 = Union[int, float] - u2 = Union[float, int] - self.assertEqual(u1, u2) - - def test_single_class_disappears(self): - t = Union[Employee] - self.assertIs(t, Employee) - - def test_base_class_disappears(self): - u = Union[Employee, Manager, int] - self.assertEqual(u, Union[int, Employee]) - u = Union[Manager, int, Employee] - self.assertEqual(u, Union[int, Employee]) - u = Union[Employee, Manager] - self.assertIs(u, Employee) - - def test_union_union(self): - u = Union[int, float] - v = Union[u, Employee] - self.assertEqual(v, Union[int, float, Employee]) - - def test_repr(self): - self.assertEqual(repr(Union), 'typing.Union') - u = Union[Employee, int] - self.assertEqual(repr(u), 'typing.Union[%s.Employee, int]' % __name__) - u = Union[int, Employee] - self.assertEqual(repr(u), 'typing.Union[int, %s.Employee]' % __name__) - T = TypeVar('T') - u = Union[T, int][int] - self.assertEqual(repr(u), repr(int)) - u = Union[List[int], int] - self.assertEqual(repr(u), 'typing.Union[typing.List[int], int]') - - def test_cannot_subclass(self): - with self.assertRaises(TypeError): - class C(Union): - pass - with self.assertRaises(TypeError): - class C(type(Union)): - pass - with self.assertRaises(TypeError): - class C(Union[int, str]): - pass - - def test_cannot_instantiate(self): - with self.assertRaises(TypeError): - Union() - with self.assertRaises(TypeError): - type(Union)() - u = Union[int, float] - with self.assertRaises(TypeError): - u() - with self.assertRaises(TypeError): - type(u)() - - def test_union_generalization(self): - self.assertFalse(Union[str, typing.Iterable[int]] == str) - self.assertFalse(Union[str, typing.Iterable[int]] == typing.Iterable[int]) - self.assertTrue(Union[str, typing.Iterable] == typing.Iterable) - - def test_union_compare_other(self): - self.assertNotEqual(Union, object) - self.assertNotEqual(Union, Any) - self.assertNotEqual(ClassVar, Union) - self.assertNotEqual(Optional, Union) - self.assertNotEqual([None], Optional) - self.assertNotEqual(Optional, typing.Mapping) - self.assertNotEqual(Optional[typing.MutableMapping], Union) - - def test_optional(self): - o = Optional[int] - u = Union[int, None] - self.assertEqual(o, u) - - def test_empty(self): - with self.assertRaises(TypeError): - Union[()] - - def test_union_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance(42, Union[int, str]) - - def test_no_eval_union(self): - u = Union[int, str] - def f(x: u): ... - self.assertIs(get_type_hints(f)['x'], u) - - def test_function_repr_union(self): - def fun() -> int: ... - self.assertEqual(repr(Union[fun, int]), 'typing.Union[fun, int]') - - def test_union_str_pattern(self): - # Shouldn't crash; see http://bugs.python.org/issue25390 - A = Union[str, Pattern] - A - - def test_etree(self): - # See https://github.com/python/typing/issues/229 - # (Only relevant for Python 2.) - try: - from xml.etree.cElementTree import Element - except ImportError: - raise SkipTest("cElementTree not found") - Union[Element, str] # Shouldn't crash - - def Elem(*args): - return Element(*args) - - Union[Elem, str] # Nor should this - - -class TupleTests(BaseTestCase): - - def test_basics(self): - with self.assertRaises(TypeError): - issubclass(Tuple, Tuple[int, str]) - with self.assertRaises(TypeError): - issubclass(tuple, Tuple[int, str]) - - class TP(tuple): ... - self.assertTrue(issubclass(tuple, Tuple)) - self.assertTrue(issubclass(TP, Tuple)) - - def test_equality(self): - self.assertEqual(Tuple[int], Tuple[int]) - self.assertEqual(Tuple[int, ...], Tuple[int, ...]) - self.assertNotEqual(Tuple[int], Tuple[int, int]) - self.assertNotEqual(Tuple[int], Tuple[int, ...]) - - def test_tuple_subclass(self): - class MyTuple(tuple): - pass - self.assertTrue(issubclass(MyTuple, Tuple)) - - def test_tuple_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance((0, 0), Tuple[int, int]) - self.assertIsInstance((0, 0), Tuple) - - def test_repr(self): - self.assertEqual(repr(Tuple), 'typing.Tuple') - self.assertEqual(repr(Tuple[()]), 'typing.Tuple[()]') - self.assertEqual(repr(Tuple[int, float]), 'typing.Tuple[int, float]') - self.assertEqual(repr(Tuple[int, ...]), 'typing.Tuple[int, ...]') - - def test_errors(self): - with self.assertRaises(TypeError): - issubclass(42, Tuple) - with self.assertRaises(TypeError): - issubclass(42, Tuple[int]) - - -class CallableTests(BaseTestCase): - - def test_self_subclass(self): - with self.assertRaises(TypeError): - self.assertTrue(issubclass(type(lambda x: x), Callable[[int], int])) - self.assertTrue(issubclass(type(lambda x: x), Callable)) - - def test_eq_hash(self): - self.assertEqual(Callable[[int], int], Callable[[int], int]) - self.assertEqual(len({Callable[[int], int], Callable[[int], int]}), 1) - self.assertNotEqual(Callable[[int], int], Callable[[int], str]) - self.assertNotEqual(Callable[[int], int], Callable[[str], int]) - self.assertNotEqual(Callable[[int], int], Callable[[int, int], int]) - self.assertNotEqual(Callable[[int], int], Callable[[], int]) - self.assertNotEqual(Callable[[int], int], Callable) - - def test_cannot_instantiate(self): - with self.assertRaises(TypeError): - Callable() - with self.assertRaises(TypeError): - type(Callable)() - c = Callable[[int], str] - with self.assertRaises(TypeError): - c() - with self.assertRaises(TypeError): - type(c)() - - def test_callable_wrong_forms(self): - with self.assertRaises(TypeError): - Callable[[...], int] - with self.assertRaises(TypeError): - Callable[(), int] - with self.assertRaises(TypeError): - Callable[[()], int] - with self.assertRaises(TypeError): - Callable[[int, 1], 2] - with self.assertRaises(TypeError): - Callable[int] - - def test_callable_instance_works(self): - def f(): - pass - self.assertIsInstance(f, Callable) - self.assertNotIsInstance(None, Callable) - - def test_callable_instance_type_error(self): - def f(): - pass - with self.assertRaises(TypeError): - self.assertIsInstance(f, Callable[[], None]) - with self.assertRaises(TypeError): - self.assertIsInstance(f, Callable[[], Any]) - with self.assertRaises(TypeError): - self.assertNotIsInstance(None, Callable[[], None]) - with self.assertRaises(TypeError): - self.assertNotIsInstance(None, Callable[[], Any]) - - def test_repr(self): - ct0 = Callable[[], bool] - self.assertEqual(repr(ct0), 'typing.Callable[[], bool]') - ct2 = Callable[[str, float], int] - self.assertEqual(repr(ct2), 'typing.Callable[[str, float], int]') - ctv = Callable[..., str] - self.assertEqual(repr(ctv), 'typing.Callable[..., str]') - - def test_callable_with_ellipsis(self): - - def foo(a: Callable[..., T]): - pass - - self.assertEqual(get_type_hints(foo, globals(), locals()), - {'a': Callable[..., T]}) - - def test_ellipsis_in_generic(self): - # Shouldn't crash; see https://github.com/python/typing/issues/259 - typing.List[Callable[..., str]] - - -XK = TypeVar('XK', str, bytes) -XV = TypeVar('XV') - - -class SimpleMapping(Generic[XK, XV]): - - def __getitem__(self, key: XK) -> XV: - ... - - def __setitem__(self, key: XK, value: XV): - ... - - def get(self, key: XK, default: XV = None) -> XV: - ... - - -class MySimpleMapping(SimpleMapping[XK, XV]): - - def __init__(self): - self.store = {} - - def __getitem__(self, key: str): - return self.store[key] - - def __setitem__(self, key: str, value): - self.store[key] = value - - def get(self, key: str, default=None): - try: - return self.store[key] - except KeyError: - return default - - -class ProtocolTests(BaseTestCase): - - def test_supports_int(self): - self.assertIsSubclass(int, typing.SupportsInt) - self.assertNotIsSubclass(str, typing.SupportsInt) - - def test_supports_float(self): - self.assertIsSubclass(float, typing.SupportsFloat) - self.assertNotIsSubclass(str, typing.SupportsFloat) - - def test_supports_complex(self): - - # Note: complex itself doesn't have __complex__. - class C: - def __complex__(self): - return 0j - - self.assertIsSubclass(C, typing.SupportsComplex) - self.assertNotIsSubclass(str, typing.SupportsComplex) - - def test_supports_bytes(self): - - # Note: bytes itself doesn't have __bytes__. - class B: - def __bytes__(self): - return b'' - - self.assertIsSubclass(B, typing.SupportsBytes) - self.assertNotIsSubclass(str, typing.SupportsBytes) - - def test_supports_abs(self): - self.assertIsSubclass(float, typing.SupportsAbs) - self.assertIsSubclass(int, typing.SupportsAbs) - self.assertNotIsSubclass(str, typing.SupportsAbs) - - def test_supports_round(self): - issubclass(float, typing.SupportsRound) - self.assertIsSubclass(float, typing.SupportsRound) - self.assertIsSubclass(int, typing.SupportsRound) - self.assertNotIsSubclass(str, typing.SupportsRound) - - def test_reversible(self): - self.assertIsSubclass(list, typing.Reversible) - self.assertNotIsSubclass(int, typing.Reversible) - - def test_protocol_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance(0, typing.SupportsAbs) - class C1(typing.SupportsInt): - def __int__(self) -> int: - return 42 - class C2(C1): - pass - c = C2() - self.assertIsInstance(c, C1) - - -class GenericTests(BaseTestCase): - - def test_basics(self): - X = SimpleMapping[str, Any] - self.assertEqual(X.__parameters__, ()) - with self.assertRaises(TypeError): - X[str] - with self.assertRaises(TypeError): - X[str, str] - Y = SimpleMapping[XK, str] - self.assertEqual(Y.__parameters__, (XK,)) - Y[str] - with self.assertRaises(TypeError): - Y[str, str] - self.assertIsSubclass(SimpleMapping[str, int], SimpleMapping) - - def test_generic_errors(self): - T = TypeVar('T') - S = TypeVar('S') - with self.assertRaises(TypeError): - Generic[T]() - with self.assertRaises(TypeError): - Generic[T][T] - with self.assertRaises(TypeError): - Generic[T][S] - with self.assertRaises(TypeError): - isinstance([], List[int]) - with self.assertRaises(TypeError): - issubclass(list, List[int]) - with self.assertRaises(TypeError): - class NewGeneric(Generic): ... - with self.assertRaises(TypeError): - class MyGeneric(Generic[T], Generic[S]): ... - with self.assertRaises(TypeError): - class MyGeneric(List[T], Generic[S]): ... - - def test_init(self): - T = TypeVar('T') - S = TypeVar('S') - with self.assertRaises(TypeError): - Generic[T, T] - with self.assertRaises(TypeError): - Generic[T, S, T] - - def test_repr(self): - self.assertEqual(repr(SimpleMapping), - __name__ + '.' + 'SimpleMapping') - self.assertEqual(repr(MySimpleMapping), - __name__ + '.' + 'MySimpleMapping') - - def test_chain_repr(self): - T = TypeVar('T') - S = TypeVar('S') - - class C(Generic[T]): - pass - - X = C[Tuple[S, T]] - self.assertEqual(X, C[Tuple[S, T]]) - self.assertNotEqual(X, C[Tuple[T, S]]) - - Y = X[T, int] - self.assertEqual(Y, X[T, int]) - self.assertNotEqual(Y, X[S, int]) - self.assertNotEqual(Y, X[T, str]) - - Z = Y[str] - self.assertEqual(Z, Y[str]) - self.assertNotEqual(Z, Y[int]) - self.assertNotEqual(Z, Y[T]) - - self.assertTrue(str(Z).endswith( - '.C[typing.Tuple[str, int]]')) - - def test_new_repr(self): - T = TypeVar('T') - U = TypeVar('U', covariant=True) - S = TypeVar('S') - - self.assertEqual(repr(List), 'typing.List') - self.assertEqual(repr(List[T]), 'typing.List[~T]') - self.assertEqual(repr(List[U]), 'typing.List[+U]') - self.assertEqual(repr(List[S][T][int]), 'typing.List[int]') - self.assertEqual(repr(List[int]), 'typing.List[int]') - - def test_new_repr_complex(self): - T = TypeVar('T') - TS = TypeVar('TS') - - self.assertEqual(repr(typing.Mapping[T, TS][TS, T]), 'typing.Mapping[~TS, ~T]') - self.assertEqual(repr(List[Tuple[T, TS]][int, T]), - 'typing.List[typing.Tuple[int, ~T]]') - self.assertEqual( - repr(List[Tuple[T, T]][List[int]]), - 'typing.List[typing.Tuple[typing.List[int], typing.List[int]]]' - ) - - def test_new_repr_bare(self): - T = TypeVar('T') - self.assertEqual(repr(Generic[T]), 'typing.Generic[~T]') - self.assertEqual(repr(typing._Protocol[T]), 'typing.Protocol[~T]') - class C(typing.Dict[Any, Any]): ... - # this line should just work - repr(C.__mro__) - - def test_dict(self): - T = TypeVar('T') - - class B(Generic[T]): - pass - - b = B() - b.foo = 42 - self.assertEqual(b.__dict__, {'foo': 42}) - - class C(B[int]): - pass - - c = C() - c.bar = 'abc' - self.assertEqual(c.__dict__, {'bar': 'abc'}) - - def test_subscripted_generics_as_proxies(self): - T = TypeVar('T') - class C(Generic[T]): - x = 'def' - self.assertEqual(C[int].x, 'def') - self.assertEqual(C[C[int]].x, 'def') - C[C[int]].x = 'changed' - self.assertEqual(C.x, 'changed') - self.assertEqual(C[str].x, 'changed') - C[List[str]].z = 'new' - self.assertEqual(C.z, 'new') - self.assertEqual(C[Tuple[int]].z, 'new') - - self.assertEqual(C().x, 'changed') - self.assertEqual(C[Tuple[str]]().z, 'new') - - class D(C[T]): - pass - self.assertEqual(D[int].x, 'changed') - self.assertEqual(D.z, 'new') - D.z = 'from derived z' - D[int].x = 'from derived x' - self.assertEqual(C.x, 'changed') - self.assertEqual(C[int].z, 'new') - self.assertEqual(D.x, 'from derived x') - self.assertEqual(D[str].z, 'from derived z') - - def test_abc_registry_kept(self): - T = TypeVar('T') - class C(Generic[T]): ... - C.register(int) - self.assertIsInstance(1, C) - C[int] - self.assertIsInstance(1, C) - - def test_false_subclasses(self): - class MyMapping(MutableMapping[str, str]): pass - self.assertNotIsInstance({}, MyMapping) - self.assertNotIsSubclass(dict, MyMapping) - - def test_abc_bases(self): - class MM(MutableMapping[str, str]): - def __getitem__(self, k): - return None - def __setitem__(self, k, v): - pass - def __delitem__(self, k): - pass - def __iter__(self): - return iter(()) - def __len__(self): - return 0 - # this should just work - MM().update() - self.assertIsInstance(MM(), collections_abc.MutableMapping) - self.assertIsInstance(MM(), MutableMapping) - self.assertNotIsInstance(MM(), List) - self.assertNotIsInstance({}, MM) - - def test_multiple_bases(self): - class MM1(MutableMapping[str, str], collections_abc.MutableMapping): - pass - with self.assertRaises(TypeError): - # consistent MRO not possible - class MM2(collections_abc.MutableMapping, MutableMapping[str, str]): - pass - - def test_orig_bases(self): - T = TypeVar('T') - class C(typing.Dict[str, T]): ... - self.assertEqual(C.__orig_bases__, (typing.Dict[str, T],)) - - def test_naive_runtime_checks(self): - def naive_dict_check(obj, tp): - # Check if a dictionary conforms to Dict type - if len(tp.__parameters__) > 0: - raise NotImplementedError - if tp.__args__: - KT, VT = tp.__args__ - return all( - isinstance(k, KT) and isinstance(v, VT) - for k, v in obj.items() - ) - self.assertTrue(naive_dict_check({'x': 1}, typing.Dict[str, int])) - self.assertFalse(naive_dict_check({1: 'x'}, typing.Dict[str, int])) - with self.assertRaises(NotImplementedError): - naive_dict_check({1: 'x'}, typing.Dict[str, T]) - - def naive_generic_check(obj, tp): - # Check if an instance conforms to the generic class - if not hasattr(obj, '__orig_class__'): - raise NotImplementedError - return obj.__orig_class__ == tp - class Node(Generic[T]): ... - self.assertTrue(naive_generic_check(Node[int](), Node[int])) - self.assertFalse(naive_generic_check(Node[str](), Node[int])) - self.assertFalse(naive_generic_check(Node[str](), List)) - with self.assertRaises(NotImplementedError): - naive_generic_check([1, 2, 3], Node[int]) - - def naive_list_base_check(obj, tp): - # Check if list conforms to a List subclass - return all(isinstance(x, tp.__orig_bases__[0].__args__[0]) - for x in obj) - class C(List[int]): ... - self.assertTrue(naive_list_base_check([1, 2, 3], C)) - self.assertFalse(naive_list_base_check(['a', 'b'], C)) - - def test_multi_subscr_base(self): - T = TypeVar('T') - U = TypeVar('U') - V = TypeVar('V') - class C(List[T][U][V]): ... - class D(C, List[T][U][V]): ... - self.assertEqual(C.__parameters__, (V,)) - self.assertEqual(D.__parameters__, (V,)) - self.assertEqual(C[int].__parameters__, ()) - self.assertEqual(D[int].__parameters__, ()) - self.assertEqual(C[int].__args__, (int,)) - self.assertEqual(D[int].__args__, (int,)) - self.assertEqual(C.__bases__, (List,)) - self.assertEqual(D.__bases__, (C, List)) - self.assertEqual(C.__orig_bases__, (List[T][U][V],)) - self.assertEqual(D.__orig_bases__, (C, List[T][U][V])) - - def test_subscript_meta(self): - T = TypeVar('T') - self.assertEqual(Type[GenericMeta], Type[GenericMeta]) - self.assertEqual(Union[T, int][GenericMeta], Union[GenericMeta, int]) - self.assertEqual(Callable[..., GenericMeta].__args__, (Ellipsis, GenericMeta)) - - def test_generic_hashes(self): - try: - from test import mod_generics_cache - except ImportError: # for Python 3.4 and previous versions - import mod_generics_cache - class A(Generic[T]): - ... - - class B(Generic[T]): - class A(Generic[T]): - ... - - self.assertEqual(A, A) - self.assertEqual(mod_generics_cache.A[str], mod_generics_cache.A[str]) - self.assertEqual(B.A, B.A) - self.assertEqual(mod_generics_cache.B.A[B.A[str]], - mod_generics_cache.B.A[B.A[str]]) - - self.assertNotEqual(A, B.A) - self.assertNotEqual(A, mod_generics_cache.A) - self.assertNotEqual(A, mod_generics_cache.B.A) - self.assertNotEqual(B.A, mod_generics_cache.A) - self.assertNotEqual(B.A, mod_generics_cache.B.A) - - self.assertNotEqual(A[str], B.A[str]) - self.assertNotEqual(A[List[Any]], B.A[List[Any]]) - self.assertNotEqual(A[str], mod_generics_cache.A[str]) - self.assertNotEqual(A[str], mod_generics_cache.B.A[str]) - self.assertNotEqual(B.A[int], mod_generics_cache.A[int]) - self.assertNotEqual(B.A[List[Any]], mod_generics_cache.B.A[List[Any]]) - - self.assertNotEqual(Tuple[A[str]], Tuple[B.A[str]]) - self.assertNotEqual(Tuple[A[List[Any]]], Tuple[B.A[List[Any]]]) - self.assertNotEqual(Union[str, A[str]], Union[str, mod_generics_cache.A[str]]) - self.assertNotEqual(Union[A[str], A[str]], - Union[A[str], mod_generics_cache.A[str]]) - self.assertNotEqual(typing.FrozenSet[A[str]], - typing.FrozenSet[mod_generics_cache.B.A[str]]) - - if sys.version_info[:2] > (3, 2): - self.assertTrue(repr(Tuple[A[str]]).endswith('.A[str]]')) - self.assertTrue(repr(Tuple[B.A[str]]).endswith('.B.A[str]]')) - self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) - .endswith('mod_generics_cache.A[str]]')) - self.assertTrue(repr(Tuple[mod_generics_cache.B.A[str]]) - .endswith('mod_generics_cache.B.A[str]]')) - - def test_extended_generic_rules_eq(self): - T = TypeVar('T') - U = TypeVar('U') - self.assertEqual(Tuple[T, T][int], Tuple[int, int]) - self.assertEqual(typing.Iterable[Tuple[T, T]][T], typing.Iterable[Tuple[T, T]]) - with self.assertRaises(TypeError): - Tuple[T, int][()] - with self.assertRaises(TypeError): - Tuple[T, U][T, ...] - - self.assertEqual(Union[T, int][int], int) - self.assertEqual(Union[T, U][int, Union[int, str]], Union[int, str]) - class Base: ... - class Derived(Base): ... - self.assertEqual(Union[T, Base][Derived], Base) - with self.assertRaises(TypeError): - Union[T, int][1] - - self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT]) - self.assertEqual(Callable[..., List[T]][int], Callable[..., List[int]]) - with self.assertRaises(TypeError): - Callable[[T], U][..., int] - with self.assertRaises(TypeError): - Callable[[T], U][[], int] - - def test_extended_generic_rules_repr(self): - T = TypeVar('T') - self.assertEqual(repr(Union[Tuple, Callable]).replace('typing.', ''), - 'Union[Tuple, Callable]') - self.assertEqual(repr(Union[Tuple, Tuple[int]]).replace('typing.', ''), - 'Tuple') - self.assertEqual(repr(Callable[..., Optional[T]][int]).replace('typing.', ''), - 'Callable[..., Union[int, NoneType]]') - self.assertEqual(repr(Callable[[], List[T]][int]).replace('typing.', ''), - 'Callable[[], List[int]]') - - def test_generic_forward_ref(self): - def foobar(x: List[List['CC']]): ... - class CC: ... - self.assertEqual( - get_type_hints(foobar, globals(), locals()), - {'x': List[List[CC]]} - ) - T = TypeVar('T') - AT = Tuple[T, ...] - def barfoo(x: AT): ... - self.assertIs(get_type_hints(barfoo, globals(), locals())['x'], AT) - CT = Callable[..., List[T]] - def barfoo2(x: CT): ... - self.assertIs(get_type_hints(barfoo2, globals(), locals())['x'], CT) - - def test_extended_generic_rules_subclassing(self): - class T1(Tuple[T, KT]): ... - class T2(Tuple[T, ...]): ... - class C1(Callable[[T], T]): ... - class C2(Callable[..., int]): - def __call__(self): - return None - - self.assertEqual(T1.__parameters__, (T, KT)) - self.assertEqual(T1[int, str].__args__, (int, str)) - self.assertEqual(T1[int, T].__origin__, T1) - - self.assertEqual(T2.__parameters__, (T,)) - with self.assertRaises(TypeError): - T1[int] - with self.assertRaises(TypeError): - T2[int, str] - - self.assertEqual(repr(C1[int]).split('.')[-1], 'C1[int]') - self.assertEqual(C2.__parameters__, ()) - self.assertIsInstance(C2(), collections_abc.Callable) - self.assertIsSubclass(C2, collections_abc.Callable) - self.assertIsSubclass(C1, collections_abc.Callable) - self.assertIsInstance(T1(), tuple) - self.assertIsSubclass(T2, tuple) - self.assertIsSubclass(Tuple[int, ...], typing.Sequence) - self.assertIsSubclass(Tuple[int, ...], typing.Iterable) - - def test_fail_with_bare_union(self): - with self.assertRaises(TypeError): - List[Union] - with self.assertRaises(TypeError): - Tuple[Optional] - with self.assertRaises(TypeError): - ClassVar[ClassVar] - with self.assertRaises(TypeError): - List[ClassVar[int]] - - def test_fail_with_bare_generic(self): - T = TypeVar('T') - with self.assertRaises(TypeError): - List[Generic] - with self.assertRaises(TypeError): - Tuple[Generic[T]] - with self.assertRaises(TypeError): - List[typing._Protocol] - with self.assertRaises(TypeError): - isinstance(1, Generic) - - def test_type_erasure_special(self): - T = TypeVar('T') - # this is the only test that checks type caching - self.clear_caches() - class MyTup(Tuple[T, T]): ... - self.assertIs(MyTup[int]().__class__, MyTup) - self.assertIs(MyTup[int]().__orig_class__, MyTup[int]) - class MyCall(Callable[..., T]): - def __call__(self): return None - self.assertIs(MyCall[T]().__class__, MyCall) - self.assertIs(MyCall[T]().__orig_class__, MyCall[T]) - class MyDict(typing.Dict[T, T]): ... - self.assertIs(MyDict[int]().__class__, MyDict) - self.assertIs(MyDict[int]().__orig_class__, MyDict[int]) - class MyDef(typing.DefaultDict[str, T]): ... - self.assertIs(MyDef[int]().__class__, MyDef) - self.assertIs(MyDef[int]().__orig_class__, MyDef[int]) - # ChainMap was added in 3.3 - if sys.version_info >= (3, 3): - class MyChain(typing.ChainMap[str, T]): ... - self.assertIs(MyChain[int]().__class__, MyChain) - self.assertIs(MyChain[int]().__orig_class__, MyChain[int]) - - def test_all_repr_eq_any(self): - objs = (getattr(typing, el) for el in typing.__all__) - for obj in objs: - self.assertNotEqual(repr(obj), '') - self.assertEqual(obj, obj) - if getattr(obj, '__parameters__', None) and len(obj.__parameters__) == 1: - self.assertEqual(obj[Any].__args__, (Any,)) - if isinstance(obj, type): - for base in obj.__mro__: - self.assertNotEqual(repr(base), '') - self.assertEqual(base, base) - - def test_substitution_helper(self): - T = TypeVar('T') - KT = TypeVar('KT') - VT = TypeVar('VT') - class Map(Generic[KT, VT]): - def meth(self, k: KT, v: VT): ... - StrMap = Map[str, T] - obj = StrMap[int]() - - new_args = typing._subs_tree(obj.__orig_class__) - new_annots = {k: typing._replace_arg(v, type(obj).__parameters__, new_args) - for k, v in obj.meth.__annotations__.items()} - - self.assertEqual(new_annots, {'k': str, 'v': int}) - - def test_pickle(self): - global C # pickle wants to reference the class by name - T = TypeVar('T') - - class B(Generic[T]): - pass - - class C(B[int]): - pass - - c = C() - c.foo = 42 - c.bar = 'abc' - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - z = pickle.dumps(c, proto) - x = pickle.loads(z) - self.assertEqual(x.foo, 42) - self.assertEqual(x.bar, 'abc') - self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) - simples = [Any, Union, Tuple, Callable, ClassVar, List, typing.Iterable] - for s in simples: - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - z = pickle.dumps(s, proto) - x = pickle.loads(z) - self.assertEqual(s, x) - - def test_copy_and_deepcopy(self): - T = TypeVar('T') - class Node(Generic[T]): ... - things = [Union[T, int], Tuple[T, int], Callable[..., T], Callable[[int], int], - Tuple[Any, Any], Node[T], Node[int], Node[Any], typing.Iterable[T], - typing.Iterable[Any], typing.Iterable[int], typing.Dict[int, str], - typing.Dict[T, Any], ClassVar[int], ClassVar[List[T]], Tuple['T', 'T'], - Union['T', int], List['T'], typing.Mapping['T', int]] - for t in things + [Any]: - self.assertEqual(t, copy(t)) - self.assertEqual(t, deepcopy(t)) - - def test_weakref_all(self): - T = TypeVar('T') - things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any], - Optional[List[int]], typing.Mapping[int, str], - typing.re.Match[bytes], typing.Iterable['whatever']] - for t in things: - self.assertEqual(weakref.ref(t)(), t) - - def test_parameterized_slots(self): - T = TypeVar('T') - class C(Generic[T]): - __slots__ = ('potato',) - - c = C() - c_int = C[int]() - self.assertEqual(C.__slots__, C[str].__slots__) - - c.potato = 0 - c_int.potato = 0 - with self.assertRaises(AttributeError): - c.tomato = 0 - with self.assertRaises(AttributeError): - c_int.tomato = 0 - - def foo(x: C['C']): ... - self.assertEqual(get_type_hints(foo, globals(), locals())['x'], C[C]) - self.assertEqual(get_type_hints(foo, globals(), locals())['x'].__slots__, - C.__slots__) - self.assertEqual(copy(C[int]), deepcopy(C[int])) - - def test_parameterized_slots_dict(self): - T = TypeVar('T') - class D(Generic[T]): - __slots__ = {'banana': 42} - - d = D() - d_int = D[int]() - self.assertEqual(D.__slots__, D[str].__slots__) - - d.banana = 'yes' - d_int.banana = 'yes' - with self.assertRaises(AttributeError): - d.foobar = 'no' - with self.assertRaises(AttributeError): - d_int.foobar = 'no' - - def test_errors(self): - with self.assertRaises(TypeError): - B = SimpleMapping[XK, Any] - - class C(Generic[B]): - pass - - def test_repr_2(self): - PY32 = sys.version_info[:2] < (3, 3) - - class C(Generic[T]): - pass - - self.assertEqual(C.__module__, __name__) - if not PY32: - self.assertEqual(C.__qualname__, - 'GenericTests.test_repr_2..C') - self.assertEqual(repr(C).split('.')[-1], 'C') - X = C[int] - self.assertEqual(X.__module__, __name__) - if not PY32: - self.assertTrue(X.__qualname__.endswith('..C')) - self.assertEqual(repr(X).split('.')[-1], 'C[int]') - - class Y(C[int]): - pass - - self.assertEqual(Y.__module__, __name__) - if not PY32: - self.assertEqual(Y.__qualname__, - 'GenericTests.test_repr_2..Y') - self.assertEqual(repr(Y).split('.')[-1], 'Y') - - def test_eq_1(self): - self.assertEqual(Generic, Generic) - self.assertEqual(Generic[T], Generic[T]) - self.assertNotEqual(Generic[KT], Generic[VT]) - - def test_eq_2(self): - - class A(Generic[T]): - pass - - class B(Generic[T]): - pass - - self.assertEqual(A, A) - self.assertNotEqual(A, B) - self.assertEqual(A[T], A[T]) - self.assertNotEqual(A[T], B[T]) - - def test_multiple_inheritance(self): - - class A(Generic[T, VT]): - pass - - class B(Generic[KT, T]): - pass - - class C(A[T, VT], Generic[VT, T, KT], B[KT, T]): - pass - - self.assertEqual(C.__parameters__, (VT, T, KT)) - - def test_nested(self): - - G = Generic - - class Visitor(G[T]): - - a = None - - def set(self, a: T): - self.a = a - - def get(self): - return self.a - - def visit(self) -> T: - return self.a - - V = Visitor[typing.List[int]] - - class IntListVisitor(V): - - def append(self, x: int): - self.a.append(x) - - a = IntListVisitor() - a.set([]) - a.append(1) - a.append(42) - self.assertEqual(a.get(), [1, 42]) - - def test_type_erasure(self): - T = TypeVar('T') - - class Node(Generic[T]): - def __init__(self, label: T, - left: 'Node[T]' = None, - right: 'Node[T]' = None): - self.label = label # type: T - self.left = left # type: Optional[Node[T]] - self.right = right # type: Optional[Node[T]] - - def foo(x: T): - a = Node(x) - b = Node[T](x) - c = Node[Any](x) - self.assertIs(type(a), Node) - self.assertIs(type(b), Node) - self.assertIs(type(c), Node) - self.assertEqual(a.label, x) - self.assertEqual(b.label, x) - self.assertEqual(c.label, x) - - foo(42) - - def test_implicit_any(self): - T = TypeVar('T') - - class C(Generic[T]): - pass - - class D(C): - pass - - self.assertEqual(D.__parameters__, ()) - - with self.assertRaises(Exception): - D[int] - with self.assertRaises(Exception): - D[Any] - with self.assertRaises(Exception): - D[T] - - -class ClassVarTests(BaseTestCase): - - def test_basics(self): - with self.assertRaises(TypeError): - ClassVar[1] - with self.assertRaises(TypeError): - ClassVar[int, str] - with self.assertRaises(TypeError): - ClassVar[int][str] - - def test_repr(self): - self.assertEqual(repr(ClassVar), 'typing.ClassVar') - cv = ClassVar[int] - self.assertEqual(repr(cv), 'typing.ClassVar[int]') - cv = ClassVar[Employee] - self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__) - - def test_cannot_subclass(self): - with self.assertRaises(TypeError): - class C(type(ClassVar)): - pass - with self.assertRaises(TypeError): - class C(type(ClassVar[int])): - pass - - def test_cannot_init(self): - with self.assertRaises(TypeError): - ClassVar() - with self.assertRaises(TypeError): - type(ClassVar)() - with self.assertRaises(TypeError): - type(ClassVar[Optional[int]])() - - def test_no_isinstance(self): - with self.assertRaises(TypeError): - isinstance(1, ClassVar[int]) - with self.assertRaises(TypeError): - issubclass(int, ClassVar) - - -class CastTests(BaseTestCase): - - def test_basics(self): - self.assertEqual(cast(int, 42), 42) - self.assertEqual(cast(float, 42), 42) - self.assertIs(type(cast(float, 42)), int) - self.assertEqual(cast(Any, 42), 42) - self.assertEqual(cast(list, 42), 42) - self.assertEqual(cast(Union[str, float], 42), 42) - self.assertEqual(cast(AnyStr, 42), 42) - self.assertEqual(cast(None, 42), 42) - - def test_errors(self): - # Bogus calls are not expected to fail. - cast(42, 42) - cast('hello', 42) - - -class ForwardRefTests(BaseTestCase): - - def test_basics(self): - - class Node(Generic[T]): - - def __init__(self, label: T): - self.label = label - self.left = self.right = None - - def add_both(self, - left: 'Optional[Node[T]]', - right: 'Node[T]' = None, - stuff: int = None, - blah=None): - self.left = left - self.right = right - - def add_left(self, node: Optional['Node[T]']): - self.add_both(node, None) - - def add_right(self, node: 'Node[T]' = None): - self.add_both(None, node) - - t = Node[int] - both_hints = get_type_hints(t.add_both, globals(), locals()) - self.assertEqual(both_hints['left'], Optional[Node[T]]) - self.assertEqual(both_hints['right'], Optional[Node[T]]) - self.assertEqual(both_hints['left'], both_hints['right']) - self.assertEqual(both_hints['stuff'], Optional[int]) - self.assertNotIn('blah', both_hints) - - left_hints = get_type_hints(t.add_left, globals(), locals()) - self.assertEqual(left_hints['node'], Optional[Node[T]]) - - right_hints = get_type_hints(t.add_right, globals(), locals()) - self.assertEqual(right_hints['node'], Optional[Node[T]]) - - def test_forwardref_instance_type_error(self): - fr = typing._ForwardRef('int') - with self.assertRaises(TypeError): - isinstance(42, fr) - - def test_forwardref_subclass_type_error(self): - fr = typing._ForwardRef('int') - with self.assertRaises(TypeError): - issubclass(int, fr) - - def test_forward_equality(self): - fr = typing._ForwardRef('int') - self.assertEqual(fr, typing._ForwardRef('int')) - self.assertNotEqual(List['int'], List[int]) - - def test_forward_repr(self): - self.assertEqual(repr(List['int']), "typing.List[_ForwardRef('int')]") - - def test_union_forward(self): - - def foo(a: Union['T']): - pass - - self.assertEqual(get_type_hints(foo, globals(), locals()), - {'a': Union[T]}) - - def test_tuple_forward(self): - - def foo(a: Tuple['T']): - pass - - self.assertEqual(get_type_hints(foo, globals(), locals()), - {'a': Tuple[T]}) - - def test_callable_forward(self): - - def foo(a: Callable[['T'], 'T']): - pass - - self.assertEqual(get_type_hints(foo, globals(), locals()), - {'a': Callable[[T], T]}) - - def test_callable_with_ellipsis_forward(self): - - def foo(a: 'Callable[..., T]'): - pass - - self.assertEqual(get_type_hints(foo, globals(), locals()), - {'a': Callable[..., T]}) - - def test_syntax_error(self): - - with self.assertRaises(SyntaxError): - Generic['/T'] - - def test_delayed_syntax_error(self): - - def foo(a: 'Node[T'): - pass - - with self.assertRaises(SyntaxError): - get_type_hints(foo) - - def test_type_error(self): - - def foo(a: Tuple['42']): - pass - - with self.assertRaises(TypeError): - get_type_hints(foo) - - def test_name_error(self): - - def foo(a: 'Noode[T]'): - pass - - with self.assertRaises(NameError): - get_type_hints(foo, locals()) - - def test_no_type_check(self): - - @no_type_check - def foo(a: 'whatevers') -> {}: - pass - - th = get_type_hints(foo) - self.assertEqual(th, {}) - - def test_no_type_check_class(self): - - @no_type_check - class C: - def foo(a: 'whatevers') -> {}: - pass - - cth = get_type_hints(C.foo) - self.assertEqual(cth, {}) - ith = get_type_hints(C().foo) - self.assertEqual(ith, {}) - - def test_no_type_check_no_bases(self): - class C: - def meth(self, x: int): ... - @no_type_check - class D(C): - c = C - # verify that @no_type_check never affects bases - self.assertEqual(get_type_hints(C.meth), {'x': int}) - - def test_meta_no_type_check(self): - - @no_type_check_decorator - def magic_decorator(deco): - return deco - - self.assertEqual(magic_decorator.__name__, 'magic_decorator') - - @magic_decorator - def foo(a: 'whatevers') -> {}: - pass - - @magic_decorator - class C: - def foo(a: 'whatevers') -> {}: - pass - - self.assertEqual(foo.__name__, 'foo') - th = get_type_hints(foo) - self.assertEqual(th, {}) - cth = get_type_hints(C.foo) - self.assertEqual(cth, {}) - ith = get_type_hints(C().foo) - self.assertEqual(ith, {}) - - def test_default_globals(self): - code = ("class C:\n" - " def foo(self, a: 'C') -> 'D': pass\n" - "class D:\n" - " def bar(self, b: 'D') -> C: pass\n" - ) - ns = {} - exec(code, ns) - hints = get_type_hints(ns['C'].foo) - self.assertEqual(hints, {'a': ns['C'], 'return': ns['D']}) - - -class OverloadTests(BaseTestCase): - - def test_overload_fails(self): - from typing import overload - - with self.assertRaises(RuntimeError): - - @overload - def blah(): - pass - - blah() - - def test_overload_succeeds(self): - from typing import overload - - @overload - def blah(): - pass - - def blah(): - pass - - blah() - - -ASYNCIO = sys.version_info[:2] >= (3, 5) - -ASYNCIO_TESTS = """ -import asyncio - -T_a = TypeVar('T_a') - -class AwaitableWrapper(typing.Awaitable[T_a]): - - def __init__(self, value): - self.value = value - - def __await__(self) -> typing.Iterator[T_a]: - yield - return self.value - -class AsyncIteratorWrapper(typing.AsyncIterator[T_a]): - - def __init__(self, value: typing.Iterable[T_a]): - self.value = value - - def __aiter__(self) -> typing.AsyncIterator[T_a]: - return self - - @asyncio.coroutine - def __anext__(self) -> T_a: - data = yield from self.value - if data: - return data - else: - raise StopAsyncIteration -""" - -if ASYNCIO: - try: - exec(ASYNCIO_TESTS) - except ImportError: - ASYNCIO = False -else: - # fake names for the sake of static analysis - asyncio = None - AwaitableWrapper = AsyncIteratorWrapper = object - -PY36 = sys.version_info[:2] >= (3, 6) - -PY36_TESTS = """ -from test import ann_module, ann_module2, ann_module3 - -class A: - y: float -class B(A): - x: ClassVar[Optional['B']] = None - y: int - b: int -class CSub(B): - z: ClassVar['CSub'] = B() -class G(Generic[T]): - lst: ClassVar[List[T]] = [] - -class NoneAndForward: - parent: 'NoneAndForward' - meaning: None - -class CoolEmployee(NamedTuple): - name: str - cool: int - -class CoolEmployeeWithDefault(NamedTuple): - name: str - cool: int = 0 - -class XMeth(NamedTuple): - x: int - def double(self): - return 2 * self.x - -class XRepr(NamedTuple): - x: int - y: int = 1 - def __str__(self): - return f'{self.x} -> {self.y}' - def __add__(self, other): - return 0 -""" - -if PY36: - exec(PY36_TESTS) -else: - # fake names for the sake of static analysis - ann_module = ann_module2 = ann_module3 = None - A = B = CSub = G = CoolEmployee = CoolEmployeeWithDefault = object - XMeth = XRepr = NoneAndForward = object - -gth = get_type_hints - - -class GetTypeHintTests(BaseTestCase): - def test_get_type_hints_from_various_objects(self): - # For invalid objects should fail with TypeError (not AttributeError etc). - with self.assertRaises(TypeError): - gth(123) - with self.assertRaises(TypeError): - gth('abc') - with self.assertRaises(TypeError): - gth(None) - - @skipUnless(PY36, 'Python 3.6 required') - def test_get_type_hints_modules(self): - ann_module_type_hints = {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str} - self.assertEqual(gth(ann_module), ann_module_type_hints) - self.assertEqual(gth(ann_module2), {}) - self.assertEqual(gth(ann_module3), {}) - - @skipUnless(PY36, 'Python 3.6 required') - def test_get_type_hints_classes(self): - self.assertEqual(gth(ann_module.C, ann_module.__dict__), - {'y': Optional[ann_module.C]}) - self.assertIsInstance(gth(ann_module.j_class), dict) - self.assertEqual(gth(ann_module.M), {'123': 123, 'o': type}) - self.assertEqual(gth(ann_module.D), - {'j': str, 'k': str, 'y': Optional[ann_module.C]}) - self.assertEqual(gth(ann_module.Y), {'z': int}) - self.assertEqual(gth(ann_module.h_class), - {'y': Optional[ann_module.C]}) - self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) - self.assertEqual(gth(ann_module.foo), {'x': int}) - self.assertEqual(gth(NoneAndForward, globals()), - {'parent': NoneAndForward, 'meaning': type(None)}) - - @skipUnless(PY36, 'Python 3.6 required') - def test_respect_no_type_check(self): - @no_type_check - class NoTpCheck: - class Inn: - def __init__(self, x: 'not a type'): ... - self.assertTrue(NoTpCheck.__no_type_check__) - self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__) - self.assertEqual(gth(ann_module2.NTC.meth), {}) - class ABase(Generic[T]): - def meth(x: int): ... - @no_type_check - class Der(ABase): ... - self.assertEqual(gth(ABase.meth), {'x': int}) - - def test_get_type_hints_for_builtins(self): - # Should not fail for built-in classes and functions. - self.assertEqual(gth(int), {}) - self.assertEqual(gth(type), {}) - self.assertEqual(gth(dir), {}) - self.assertEqual(gth(len), {}) - self.assertEqual(gth(object.__str__), {}) - self.assertEqual(gth(object().__str__), {}) - self.assertEqual(gth(str.join), {}) - - def test_previous_behavior(self): - def testf(x, y): ... - testf.__annotations__['x'] = 'int' - self.assertEqual(gth(testf), {'x': int}) - def testg(x: None): ... - self.assertEqual(gth(testg), {'x': type(None)}) - - def test_get_type_hints_for_object_with_annotations(self): - class A: ... - class B: ... - b = B() - b.__annotations__ = {'x': 'A'} - self.assertEqual(gth(b, locals()), {'x': A}) - - @skipUnless(PY36, 'Python 3.6 required') - def test_get_type_hints_ClassVar(self): - self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__), - {'var': typing.ClassVar[ann_module2.CV]}) - self.assertEqual(gth(B, globals()), - {'y': int, 'x': ClassVar[Optional[B]], 'b': int}) - self.assertEqual(gth(CSub, globals()), - {'z': ClassVar[CSub], 'y': int, 'b': int, - 'x': ClassVar[Optional[B]]}) - self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) - - -class CollectionsAbcTests(BaseTestCase): - - def test_hashable(self): - self.assertIsInstance(42, typing.Hashable) - self.assertNotIsInstance([], typing.Hashable) - - def test_iterable(self): - self.assertIsInstance([], typing.Iterable) - # Due to ABC caching, the second time takes a separate code - # path and could fail. So call this a few times. - self.assertIsInstance([], typing.Iterable) - self.assertIsInstance([], typing.Iterable) - self.assertNotIsInstance(42, typing.Iterable) - # Just in case, also test issubclass() a few times. - self.assertIsSubclass(list, typing.Iterable) - self.assertIsSubclass(list, typing.Iterable) - - def test_iterator(self): - it = iter([]) - self.assertIsInstance(it, typing.Iterator) - self.assertNotIsInstance(42, typing.Iterator) - - @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') - def test_awaitable(self): - ns = {} - exec( - "async def foo() -> typing.Awaitable[int]:\n" - " return await AwaitableWrapper(42)\n", - globals(), ns) - foo = ns['foo'] - g = foo() - self.assertIsInstance(g, typing.Awaitable) - self.assertNotIsInstance(foo, typing.Awaitable) - g.send(None) # Run foo() till completion, to avoid warning. - - @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') - def test_coroutine(self): - ns = {} - exec( - "async def foo():\n" - " return\n", - globals(), ns) - foo = ns['foo'] - g = foo() - self.assertIsInstance(g, typing.Coroutine) - with self.assertRaises(TypeError): - isinstance(g, typing.Coroutine[int]) - self.assertNotIsInstance(foo, typing.Coroutine) - try: - g.send(None) - except StopIteration: - pass - - @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') - def test_async_iterable(self): - base_it = range(10) # type: Iterator[int] - it = AsyncIteratorWrapper(base_it) - self.assertIsInstance(it, typing.AsyncIterable) - self.assertIsInstance(it, typing.AsyncIterable) - self.assertNotIsInstance(42, typing.AsyncIterable) - - @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') - def test_async_iterator(self): - base_it = range(10) # type: Iterator[int] - it = AsyncIteratorWrapper(base_it) - self.assertIsInstance(it, typing.AsyncIterator) - self.assertNotIsInstance(42, typing.AsyncIterator) - - def test_sized(self): - self.assertIsInstance([], typing.Sized) - self.assertNotIsInstance(42, typing.Sized) - - def test_container(self): - self.assertIsInstance([], typing.Container) - self.assertNotIsInstance(42, typing.Container) - - def test_collection(self): - if hasattr(typing, 'Collection'): - self.assertIsInstance(tuple(), typing.Collection) - self.assertIsInstance(frozenset(), typing.Collection) - self.assertIsSubclass(dict, typing.Collection) - self.assertNotIsInstance(42, typing.Collection) - - def test_abstractset(self): - self.assertIsInstance(set(), typing.AbstractSet) - self.assertNotIsInstance(42, typing.AbstractSet) - - def test_mutableset(self): - self.assertIsInstance(set(), typing.MutableSet) - self.assertNotIsInstance(frozenset(), typing.MutableSet) - - def test_mapping(self): - self.assertIsInstance({}, typing.Mapping) - self.assertNotIsInstance(42, typing.Mapping) - - def test_mutablemapping(self): - self.assertIsInstance({}, typing.MutableMapping) - self.assertNotIsInstance(42, typing.MutableMapping) - - def test_sequence(self): - self.assertIsInstance([], typing.Sequence) - self.assertNotIsInstance(42, typing.Sequence) - - def test_mutablesequence(self): - self.assertIsInstance([], typing.MutableSequence) - self.assertNotIsInstance((), typing.MutableSequence) - - def test_bytestring(self): - self.assertIsInstance(b'', typing.ByteString) - self.assertIsInstance(bytearray(b''), typing.ByteString) - - def test_list(self): - self.assertIsSubclass(list, typing.List) - - def test_deque(self): - self.assertIsSubclass(collections.deque, typing.Deque) - class MyDeque(typing.Deque[int]): ... - self.assertIsInstance(MyDeque(), collections.deque) - - def test_counter(self): - self.assertIsSubclass(collections.Counter, typing.Counter) - - def test_set(self): - self.assertIsSubclass(set, typing.Set) - self.assertNotIsSubclass(frozenset, typing.Set) - - def test_frozenset(self): - self.assertIsSubclass(frozenset, typing.FrozenSet) - self.assertNotIsSubclass(set, typing.FrozenSet) - - def test_dict(self): - self.assertIsSubclass(dict, typing.Dict) - - def test_no_list_instantiation(self): - with self.assertRaises(TypeError): - typing.List() - with self.assertRaises(TypeError): - typing.List[T]() - with self.assertRaises(TypeError): - typing.List[int]() - - def test_list_subclass(self): - - class MyList(typing.List[int]): - pass - - a = MyList() - self.assertIsInstance(a, MyList) - self.assertIsInstance(a, typing.Sequence) - - self.assertIsSubclass(MyList, list) - self.assertNotIsSubclass(list, MyList) - - def test_no_dict_instantiation(self): - with self.assertRaises(TypeError): - typing.Dict() - with self.assertRaises(TypeError): - typing.Dict[KT, VT]() - with self.assertRaises(TypeError): - typing.Dict[str, int]() - - def test_dict_subclass(self): - - class MyDict(typing.Dict[str, int]): - pass - - d = MyDict() - self.assertIsInstance(d, MyDict) - self.assertIsInstance(d, typing.MutableMapping) - - self.assertIsSubclass(MyDict, dict) - self.assertNotIsSubclass(dict, MyDict) - - def test_defaultdict_instantiation(self): - self.assertIs(type(typing.DefaultDict()), collections.defaultdict) - self.assertIs(type(typing.DefaultDict[KT, VT]()), collections.defaultdict) - self.assertIs(type(typing.DefaultDict[str, int]()), collections.defaultdict) - - def test_defaultdict_subclass(self): - - class MyDefDict(typing.DefaultDict[str, int]): - pass - - dd = MyDefDict() - self.assertIsInstance(dd, MyDefDict) - - self.assertIsSubclass(MyDefDict, collections.defaultdict) - self.assertNotIsSubclass(collections.defaultdict, MyDefDict) - - @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') - def test_chainmap_instantiation(self): - self.assertIs(type(typing.ChainMap()), collections.ChainMap) - self.assertIs(type(typing.ChainMap[KT, VT]()), collections.ChainMap) - self.assertIs(type(typing.ChainMap[str, int]()), collections.ChainMap) - class CM(typing.ChainMap[KT, VT]): ... - self.assertIs(type(CM[int, str]()), CM) - - @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') - def test_chainmap_subclass(self): - - class MyChainMap(typing.ChainMap[str, int]): - pass - - cm = MyChainMap() - self.assertIsInstance(cm, MyChainMap) - - self.assertIsSubclass(MyChainMap, collections.ChainMap) - self.assertNotIsSubclass(collections.ChainMap, MyChainMap) - - def test_deque_instantiation(self): - self.assertIs(type(typing.Deque()), collections.deque) - self.assertIs(type(typing.Deque[T]()), collections.deque) - self.assertIs(type(typing.Deque[int]()), collections.deque) - class D(typing.Deque[T]): ... - self.assertIs(type(D[int]()), D) - - def test_counter_instantiation(self): - self.assertIs(type(typing.Counter()), collections.Counter) - self.assertIs(type(typing.Counter[T]()), collections.Counter) - self.assertIs(type(typing.Counter[int]()), collections.Counter) - class C(typing.Counter[T]): ... - self.assertIs(type(C[int]()), C) - - def test_counter_subclass_instantiation(self): - - class MyCounter(typing.Counter[int]): - pass - - d = MyCounter() - self.assertIsInstance(d, MyCounter) - self.assertIsInstance(d, typing.Counter) - self.assertIsInstance(d, collections.Counter) - - def test_no_set_instantiation(self): - with self.assertRaises(TypeError): - typing.Set() - with self.assertRaises(TypeError): - typing.Set[T]() - with self.assertRaises(TypeError): - typing.Set[int]() - - def test_set_subclass_instantiation(self): - - class MySet(typing.Set[int]): - pass - - d = MySet() - self.assertIsInstance(d, MySet) - - def test_no_frozenset_instantiation(self): - with self.assertRaises(TypeError): - typing.FrozenSet() - with self.assertRaises(TypeError): - typing.FrozenSet[T]() - with self.assertRaises(TypeError): - typing.FrozenSet[int]() - - def test_frozenset_subclass_instantiation(self): - - class MyFrozenSet(typing.FrozenSet[int]): - pass - - d = MyFrozenSet() - self.assertIsInstance(d, MyFrozenSet) - - def test_no_tuple_instantiation(self): - with self.assertRaises(TypeError): - Tuple() - with self.assertRaises(TypeError): - Tuple[T]() - with self.assertRaises(TypeError): - Tuple[int]() - - def test_generator(self): - def foo(): - yield 42 - g = foo() - self.assertIsSubclass(type(g), typing.Generator) - - def test_no_generator_instantiation(self): - with self.assertRaises(TypeError): - typing.Generator() - with self.assertRaises(TypeError): - typing.Generator[T, T, T]() - with self.assertRaises(TypeError): - typing.Generator[int, int, int]() - - @skipUnless(PY36, 'Python 3.6 required') - def test_async_generator(self): - ns = {} - exec("async def f():\n" - " yield 42\n", globals(), ns) - g = ns['f']() - self.assertIsSubclass(type(g), typing.AsyncGenerator) - - @skipUnless(PY36, 'Python 3.6 required') - def test_no_async_generator_instantiation(self): - with self.assertRaises(TypeError): - typing.AsyncGenerator() - with self.assertRaises(TypeError): - typing.AsyncGenerator[T, T]() - with self.assertRaises(TypeError): - typing.AsyncGenerator[int, int]() - - def test_subclassing(self): - - class MMA(typing.MutableMapping): - pass - - with self.assertRaises(TypeError): # It's abstract - MMA() - - class MMC(MMA): - def __getitem__(self, k): - return None - def __setitem__(self, k, v): - pass - def __delitem__(self, k): - pass - def __iter__(self): - return iter(()) - def __len__(self): - return 0 - - self.assertEqual(len(MMC()), 0) - assert callable(MMC.update) - self.assertIsInstance(MMC(), typing.Mapping) - - class MMB(typing.MutableMapping[KT, VT]): - def __getitem__(self, k): - return None - def __setitem__(self, k, v): - pass - def __delitem__(self, k): - pass - def __iter__(self): - return iter(()) - def __len__(self): - return 0 - - self.assertEqual(len(MMB()), 0) - self.assertEqual(len(MMB[str, str]()), 0) - self.assertEqual(len(MMB[KT, VT]()), 0) - - self.assertNotIsSubclass(dict, MMA) - self.assertNotIsSubclass(dict, MMB) - - self.assertIsSubclass(MMA, typing.Mapping) - self.assertIsSubclass(MMB, typing.Mapping) - self.assertIsSubclass(MMC, typing.Mapping) - - self.assertIsInstance(MMB[KT, VT](), typing.Mapping) - self.assertIsInstance(MMB[KT, VT](), collections.Mapping) - - self.assertIsSubclass(MMA, collections.Mapping) - self.assertIsSubclass(MMB, collections.Mapping) - self.assertIsSubclass(MMC, collections.Mapping) - - self.assertIsSubclass(MMB[str, str], typing.Mapping) - self.assertIsSubclass(MMC, MMA) - - class I(typing.Iterable): ... - self.assertNotIsSubclass(list, I) - - class G(typing.Generator[int, int, int]): ... - def g(): yield 0 - self.assertIsSubclass(G, typing.Generator) - self.assertIsSubclass(G, typing.Iterable) - if hasattr(collections, 'Generator'): - self.assertIsSubclass(G, collections.Generator) - self.assertIsSubclass(G, collections.Iterable) - self.assertNotIsSubclass(type(g), G) - - @skipUnless(PY36, 'Python 3.6 required') - def test_subclassing_async_generator(self): - class G(typing.AsyncGenerator[int, int]): - def asend(self, value): - pass - def athrow(self, typ, val=None, tb=None): - pass - - ns = {} - exec('async def g(): yield 0', globals(), ns) - g = ns['g'] - self.assertIsSubclass(G, typing.AsyncGenerator) - self.assertIsSubclass(G, typing.AsyncIterable) - self.assertIsSubclass(G, collections.AsyncGenerator) - self.assertIsSubclass(G, collections.AsyncIterable) - self.assertNotIsSubclass(type(g), G) - - instance = G() - self.assertIsInstance(instance, typing.AsyncGenerator) - self.assertIsInstance(instance, typing.AsyncIterable) - self.assertIsInstance(instance, collections.AsyncGenerator) - self.assertIsInstance(instance, collections.AsyncIterable) - self.assertNotIsInstance(type(g), G) - self.assertNotIsInstance(g, G) - - def test_subclassing_subclasshook(self): - - class Base(typing.Iterable): - @classmethod - def __subclasshook__(cls, other): - if other.__name__ == 'Foo': - return True - else: - return False - - class C(Base): ... - class Foo: ... - class Bar: ... - self.assertIsSubclass(Foo, Base) - self.assertIsSubclass(Foo, C) - self.assertNotIsSubclass(Bar, C) - - def test_subclassing_register(self): - - class A(typing.Container): ... - class B(A): ... - - class C: ... - A.register(C) - self.assertIsSubclass(C, A) - self.assertNotIsSubclass(C, B) - - class D: ... - B.register(D) - self.assertIsSubclass(D, A) - self.assertIsSubclass(D, B) - - class M(): ... - collections.MutableMapping.register(M) - self.assertIsSubclass(M, typing.Mapping) - - def test_collections_as_base(self): - - class M(collections.Mapping): ... - self.assertIsSubclass(M, typing.Mapping) - self.assertIsSubclass(M, typing.Iterable) - - class S(collections.MutableSequence): ... - self.assertIsSubclass(S, typing.MutableSequence) - self.assertIsSubclass(S, typing.Iterable) - - class I(collections.Iterable): ... - self.assertIsSubclass(I, typing.Iterable) - - class A(collections.Mapping, metaclass=abc.ABCMeta): ... - class B: ... - A.register(B) - self.assertIsSubclass(B, typing.Mapping) - - -class OtherABCTests(BaseTestCase): - - @skipUnless(hasattr(typing, 'ContextManager'), - 'requires typing.ContextManager') - def test_contextmanager(self): - @contextlib.contextmanager - def manager(): - yield 42 - - cm = manager() - self.assertIsInstance(cm, typing.ContextManager) - self.assertNotIsInstance(42, typing.ContextManager) - - -class TypeTests(BaseTestCase): - - def test_type_basic(self): - - class User: pass - class BasicUser(User): pass - class ProUser(User): pass - - def new_user(user_class: Type[User]) -> User: - return user_class() - - new_user(BasicUser) - - def test_type_typevar(self): - - class User: pass - class BasicUser(User): pass - class ProUser(User): pass - - U = TypeVar('U', bound=User) - - def new_user(user_class: Type[U]) -> U: - return user_class() - - new_user(BasicUser) - - def test_type_optional(self): - A = Optional[Type[BaseException]] - - def foo(a: A) -> Optional[BaseException]: - if a is None: - return None - else: - return a() - - assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt) - assert foo(None) is None - - -class NewTypeTests(BaseTestCase): - - def test_basic(self): - UserId = NewType('UserId', int) - UserName = NewType('UserName', str) - self.assertIsInstance(UserId(5), int) - self.assertIsInstance(UserName('Joe'), str) - self.assertEqual(UserId(5) + 1, 6) - - def test_errors(self): - UserId = NewType('UserId', int) - UserName = NewType('UserName', str) - with self.assertRaises(TypeError): - issubclass(UserId, int) - with self.assertRaises(TypeError): - class D(UserName): - pass - - -class NamedTupleTests(BaseTestCase): - - def test_basics(self): - Emp = NamedTuple('Emp', [('name', str), ('id', int)]) - self.assertIsSubclass(Emp, tuple) - joe = Emp('Joe', 42) - jim = Emp(name='Jim', id=1) - self.assertIsInstance(joe, Emp) - self.assertIsInstance(joe, tuple) - self.assertEqual(joe.name, 'Joe') - self.assertEqual(joe.id, 42) - self.assertEqual(jim.name, 'Jim') - self.assertEqual(jim.id, 1) - self.assertEqual(Emp.__name__, 'Emp') - self.assertEqual(Emp._fields, ('name', 'id')) - self.assertEqual(Emp.__annotations__, - collections.OrderedDict([('name', str), ('id', int)])) - self.assertIs(Emp._field_types, Emp.__annotations__) - - def test_namedtuple_pyversion(self): - if sys.version_info[:2] < (3, 6): - with self.assertRaises(TypeError): - NamedTuple('Name', one=int, other=str) - with self.assertRaises(TypeError): - class NotYet(NamedTuple): - whatever = 0 - - @skipUnless(PY36, 'Python 3.6 required') - def test_annotation_usage(self): - tim = CoolEmployee('Tim', 9000) - self.assertIsInstance(tim, CoolEmployee) - self.assertIsInstance(tim, tuple) - self.assertEqual(tim.name, 'Tim') - self.assertEqual(tim.cool, 9000) - self.assertEqual(CoolEmployee.__name__, 'CoolEmployee') - self.assertEqual(CoolEmployee._fields, ('name', 'cool')) - self.assertEqual(CoolEmployee.__annotations__, - collections.OrderedDict(name=str, cool=int)) - self.assertIs(CoolEmployee._field_types, CoolEmployee.__annotations__) - - @skipUnless(PY36, 'Python 3.6 required') - def test_annotation_usage_with_default(self): - jelle = CoolEmployeeWithDefault('Jelle') - self.assertIsInstance(jelle, CoolEmployeeWithDefault) - self.assertIsInstance(jelle, tuple) - self.assertEqual(jelle.name, 'Jelle') - self.assertEqual(jelle.cool, 0) - cooler_employee = CoolEmployeeWithDefault('Sjoerd', 1) - self.assertEqual(cooler_employee.cool, 1) - - self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault') - self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool')) - self.assertEqual(CoolEmployeeWithDefault._field_types, dict(name=str, cool=int)) - self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0)) - - with self.assertRaises(TypeError): - exec(""" -class NonDefaultAfterDefault(NamedTuple): - x: int = 3 - y: int -""") - - @skipUnless(PY36, 'Python 3.6 required') - def test_annotation_usage_with_methods(self): - self.assertEqual(XMeth(1).double(), 2) - self.assertEqual(XMeth(42).x, XMeth(42)[0]) - self.assertEqual(str(XRepr(42)), '42 -> 1') - self.assertEqual(XRepr(1, 2) + XRepr(3), 0) - - with self.assertRaises(AttributeError): - exec(""" -class XMethBad(NamedTuple): - x: int - def _fields(self): - return 'no chance for this' -""") - - @skipUnless(PY36, 'Python 3.6 required') - def test_namedtuple_keyword_usage(self): - LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int) - nick = LocalEmployee('Nick', 25) - self.assertIsInstance(nick, tuple) - self.assertEqual(nick.name, 'Nick') - self.assertEqual(LocalEmployee.__name__, 'LocalEmployee') - self.assertEqual(LocalEmployee._fields, ('name', 'age')) - self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) - self.assertIs(LocalEmployee._field_types, LocalEmployee.__annotations__) - with self.assertRaises(TypeError): - NamedTuple('Name', [('x', int)], y=str) - with self.assertRaises(TypeError): - NamedTuple('Name', x=1, y='a') - - def test_pickle(self): - global Emp # pickle wants to reference the class by name - Emp = NamedTuple('Emp', [('name', str), ('id', int)]) - jane = Emp('jane', 37) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - z = pickle.dumps(jane, proto) - jane2 = pickle.loads(z) - self.assertEqual(jane2, jane) - - -class IOTests(BaseTestCase): - - def test_io(self): - - def stuff(a: IO) -> AnyStr: - return a.readline() - - a = stuff.__annotations__['a'] - self.assertEqual(a.__parameters__, (AnyStr,)) - - def test_textio(self): - - def stuff(a: TextIO) -> str: - return a.readline() - - a = stuff.__annotations__['a'] - self.assertEqual(a.__parameters__, ()) - - def test_binaryio(self): - - def stuff(a: BinaryIO) -> bytes: - return a.readline() - - a = stuff.__annotations__['a'] - self.assertEqual(a.__parameters__, ()) - - def test_io_submodule(self): - from typing.io import IO, TextIO, BinaryIO, __all__, __name__ - self.assertIs(IO, typing.IO) - self.assertIs(TextIO, typing.TextIO) - self.assertIs(BinaryIO, typing.BinaryIO) - self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO'])) - self.assertEqual(__name__, 'typing.io') - - -class RETests(BaseTestCase): - # Much of this is really testing _TypeAlias. - - def test_basics(self): - pat = re.compile('[a-z]+', re.I) - self.assertIsSubclass(pat.__class__, Pattern) - self.assertIsSubclass(type(pat), Pattern) - self.assertIsInstance(pat, Pattern) - - mat = pat.search('12345abcde.....') - self.assertIsSubclass(mat.__class__, Match) - self.assertIsSubclass(type(mat), Match) - self.assertIsInstance(mat, Match) - - # these should just work - Pattern[Union[str, bytes]] - Match[Union[bytes, str]] - - def test_alias_equality(self): - self.assertEqual(Pattern[str], Pattern[str]) - self.assertNotEqual(Pattern[str], Pattern[bytes]) - self.assertNotEqual(Pattern[str], Match[str]) - self.assertNotEqual(Pattern[str], str) - - def test_errors(self): - with self.assertRaises(TypeError): - # Doesn't fit AnyStr. - Pattern[int] - with self.assertRaises(TypeError): - # Can't change type vars? - Match[T] - m = Match[Union[str, bytes]] - with self.assertRaises(TypeError): - # Too complicated? - m[str] - with self.assertRaises(TypeError): - # We don't support isinstance(). - isinstance(42, Pattern[str]) - with self.assertRaises(TypeError): - # We don't support issubclass(). - issubclass(Pattern[bytes], Pattern[str]) - - def test_repr(self): - self.assertEqual(repr(Pattern), 'Pattern[~AnyStr]') - self.assertEqual(repr(Pattern[str]), 'Pattern[str]') - self.assertEqual(repr(Pattern[bytes]), 'Pattern[bytes]') - self.assertEqual(repr(Match), 'Match[~AnyStr]') - self.assertEqual(repr(Match[str]), 'Match[str]') - self.assertEqual(repr(Match[bytes]), 'Match[bytes]') - - def test_re_submodule(self): - from typing.re import Match, Pattern, __all__, __name__ - self.assertIs(Match, typing.Match) - self.assertIs(Pattern, typing.Pattern) - self.assertEqual(set(__all__), set(['Match', 'Pattern'])) - self.assertEqual(__name__, 'typing.re') - - def test_cannot_subclass(self): - with self.assertRaises(TypeError) as ex: - - class A(typing.Match): - pass - - self.assertEqual(str(ex.exception), - "Cannot subclass typing._TypeAlias") - - -class AllTests(BaseTestCase): - """Tests for __all__.""" - - def test_all(self): - from typing import __all__ as a - # Just spot-check the first and last of every category. - self.assertIn('AbstractSet', a) - self.assertIn('ValuesView', a) - self.assertIn('cast', a) - self.assertIn('overload', a) - if hasattr(contextlib, 'AbstractContextManager'): - self.assertIn('ContextManager', a) - # Check that io and re are not exported. - self.assertNotIn('io', a) - self.assertNotIn('re', a) - # Spot-check that stdlib modules aren't exported. - self.assertNotIn('os', a) - self.assertNotIn('sys', a) - # Check that Text is defined. - self.assertIn('Text', a) - - -if __name__ == '__main__': - main() diff --git a/lib-typing/3.2/typing.py b/lib-typing/3.2/typing.py deleted file mode 100644 index 9a0f49099a31..000000000000 --- a/lib-typing/3.2/typing.py +++ /dev/null @@ -1,2335 +0,0 @@ -import abc -from abc import abstractmethod, abstractproperty -import collections -import contextlib -import functools -import re as stdlib_re # Avoid confusion with the re we export. -import sys -import types -try: - import collections.abc as collections_abc -except ImportError: - import collections as collections_abc # Fallback for PY3.2. -try: - from types import SlotWrapperType, MethodWrapperType, MethodDescriptorType -except ImportError: - SlotWrapperType = type(object.__init__) - MethodWrapperType = type(object().__str__) - MethodDescriptorType = type(str.join) - - -# Please keep __all__ alphabetized within each category. -__all__ = [ - # Super-special typing primitives. - 'Any', - 'Callable', - 'ClassVar', - 'Generic', - 'Optional', - 'Tuple', - 'Type', - 'TypeVar', - 'Union', - - # ABCs (from collections.abc). - 'AbstractSet', # collections.abc.Set. - 'GenericMeta', # subclass of abc.ABCMeta and a metaclass - # for 'Generic' and ABCs below. - 'ByteString', - 'Container', - 'Hashable', - 'ItemsView', - 'Iterable', - 'Iterator', - 'KeysView', - 'Mapping', - 'MappingView', - 'MutableMapping', - 'MutableSequence', - 'MutableSet', - 'Sequence', - 'Sized', - 'ValuesView', - # The following are added depending on presence - # of their non-generic counterparts in stdlib: - # Awaitable, - # AsyncIterator, - # AsyncIterable, - # Coroutine, - # Collection, - # ContextManager, - # AsyncGenerator, - - # Structural checks, a.k.a. protocols. - 'Reversible', - 'SupportsAbs', - 'SupportsFloat', - 'SupportsInt', - 'SupportsRound', - - # Concrete collection types. - 'Counter', - 'Deque', - 'Dict', - 'DefaultDict', - 'List', - 'Set', - 'FrozenSet', - 'NamedTuple', # Not really a type. - 'Generator', - - # One-off things. - 'AnyStr', - 'cast', - 'get_type_hints', - 'NewType', - 'no_type_check', - 'no_type_check_decorator', - 'overload', - 'Text', - 'TYPE_CHECKING', -] - -# The pseudo-submodules 're' and 'io' are part of the public -# namespace, but excluded from __all__ because they might stomp on -# legitimate imports of those modules. - - -def _qualname(x): - if sys.version_info[:2] >= (3, 3): - return x.__qualname__ - else: - # Fall back to just name. - return x.__name__ - - -def _trim_name(nm): - whitelist = ('_TypeAlias', '_ForwardRef', '_TypingBase', '_FinalTypingBase') - if nm.startswith('_') and nm not in whitelist: - nm = nm[1:] - return nm - - -class TypingMeta(type): - """Metaclass for most types defined in typing module - (not a part of public API). - - This overrides __new__() to require an extra keyword parameter - '_root', which serves as a guard against naive subclassing of the - typing classes. Any legitimate class defined using a metaclass - derived from TypingMeta must pass _root=True. - - This also defines a dummy constructor (all the work for most typing - constructs is done in __new__) and a nicer repr(). - """ - - _is_protocol = False - - def __new__(cls, name, bases, namespace, *, _root=False): - if not _root: - raise TypeError("Cannot subclass %s" % - (', '.join(map(_type_repr, bases)) or '()')) - return super().__new__(cls, name, bases, namespace) - - def __init__(self, *args, **kwds): - pass - - def _eval_type(self, globalns, localns): - """Override this in subclasses to interpret forward references. - - For example, List['C'] is internally stored as - List[_ForwardRef('C')], which should evaluate to List[C], - where C is an object found in globalns or localns (searching - localns first, of course). - """ - return self - - def _get_type_vars(self, tvars): - pass - - def __repr__(self): - qname = _trim_name(_qualname(self)) - return '%s.%s' % (self.__module__, qname) - - -class _TypingBase(metaclass=TypingMeta, _root=True): - """Internal indicator of special typing constructs.""" - - __slots__ = ('__weakref__',) - - def __init__(self, *args, **kwds): - pass - - def __new__(cls, *args, **kwds): - """Constructor. - - This only exists to give a better error message in case - someone tries to subclass a special typing object (not a good idea). - """ - if (len(args) == 3 and - isinstance(args[0], str) and - isinstance(args[1], tuple)): - # Close enough. - raise TypeError("Cannot subclass %r" % cls) - return super().__new__(cls) - - # Things that are not classes also need these. - def _eval_type(self, globalns, localns): - return self - - def _get_type_vars(self, tvars): - pass - - def __repr__(self): - cls = type(self) - qname = _trim_name(_qualname(cls)) - return '%s.%s' % (cls.__module__, qname) - - def __call__(self, *args, **kwds): - raise TypeError("Cannot instantiate %r" % type(self)) - - -class _FinalTypingBase(_TypingBase, _root=True): - """Internal mix-in class to prevent instantiation. - - Prevents instantiation unless _root=True is given in class call. - It is used to create pseudo-singleton instances Any, Union, Optional, etc. - """ - - __slots__ = () - - def __new__(cls, *args, _root=False, **kwds): - self = super().__new__(cls, *args, **kwds) - if _root is True: - return self - raise TypeError("Cannot instantiate %r" % cls) - - def __reduce__(self): - return _trim_name(type(self).__name__) - - -class _ForwardRef(_TypingBase, _root=True): - """Internal wrapper to hold a forward reference.""" - - __slots__ = ('__forward_arg__', '__forward_code__', - '__forward_evaluated__', '__forward_value__') - - def __init__(self, arg): - super().__init__(arg) - if not isinstance(arg, str): - raise TypeError('Forward reference must be a string -- got %r' % (arg,)) - try: - code = compile(arg, '', 'eval') - except SyntaxError: - raise SyntaxError('Forward reference must be an expression -- got %r' % - (arg,)) - self.__forward_arg__ = arg - self.__forward_code__ = code - self.__forward_evaluated__ = False - self.__forward_value__ = None - - def _eval_type(self, globalns, localns): - if not self.__forward_evaluated__ or localns is not globalns: - if globalns is None and localns is None: - globalns = localns = {} - elif globalns is None: - globalns = localns - elif localns is None: - localns = globalns - self.__forward_value__ = _type_check( - eval(self.__forward_code__, globalns, localns), - "Forward references must evaluate to types.") - self.__forward_evaluated__ = True - return self.__forward_value__ - - def __eq__(self, other): - if not isinstance(other, _ForwardRef): - return NotImplemented - return (self.__forward_arg__ == other.__forward_arg__ and - self.__forward_value__ == other.__forward_value__) - - def __hash__(self): - return hash((self.__forward_arg__, self.__forward_value__)) - - def __instancecheck__(self, obj): - raise TypeError("Forward references cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - raise TypeError("Forward references cannot be used with issubclass().") - - def __repr__(self): - return '_ForwardRef(%r)' % (self.__forward_arg__,) - - -class _TypeAlias(_TypingBase, _root=True): - """Internal helper class for defining generic variants of concrete types. - - Note that this is not a type; let's call it a pseudo-type. It cannot - be used in instance and subclass checks in parameterized form, i.e. - ``isinstance(42, Match[str])`` raises ``TypeError`` instead of returning - ``False``. - """ - - __slots__ = ('name', 'type_var', 'impl_type', 'type_checker') - - def __init__(self, name, type_var, impl_type, type_checker): - """Initializer. - - Args: - name: The name, e.g. 'Pattern'. - type_var: The type parameter, e.g. AnyStr, or the - specific type, e.g. str. - impl_type: The implementation type. - type_checker: Function that takes an impl_type instance. - and returns a value that should be a type_var instance. - """ - assert isinstance(name, str), repr(name) - assert isinstance(impl_type, type), repr(impl_type) - assert not isinstance(impl_type, TypingMeta), repr(impl_type) - assert isinstance(type_var, (type, _TypingBase)), repr(type_var) - self.name = name - self.type_var = type_var - self.impl_type = impl_type - self.type_checker = type_checker - - def __repr__(self): - return "%s[%s]" % (self.name, _type_repr(self.type_var)) - - def __getitem__(self, parameter): - if not isinstance(self.type_var, TypeVar): - raise TypeError("%s cannot be further parameterized." % self) - if self.type_var.__constraints__ and isinstance(parameter, type): - if not issubclass(parameter, self.type_var.__constraints__): - raise TypeError("%s is not a valid substitution for %s." % - (parameter, self.type_var)) - if isinstance(parameter, TypeVar) and parameter is not self.type_var: - raise TypeError("%s cannot be re-parameterized." % self) - return self.__class__(self.name, parameter, - self.impl_type, self.type_checker) - - def __eq__(self, other): - if not isinstance(other, _TypeAlias): - return NotImplemented - return self.name == other.name and self.type_var == other.type_var - - def __hash__(self): - return hash((self.name, self.type_var)) - - def __instancecheck__(self, obj): - if not isinstance(self.type_var, TypeVar): - raise TypeError("Parameterized type aliases cannot be used " - "with isinstance().") - return isinstance(obj, self.impl_type) - - def __subclasscheck__(self, cls): - if not isinstance(self.type_var, TypeVar): - raise TypeError("Parameterized type aliases cannot be used " - "with issubclass().") - return issubclass(cls, self.impl_type) - - -def _get_type_vars(types, tvars): - for t in types: - if isinstance(t, TypingMeta) or isinstance(t, _TypingBase): - t._get_type_vars(tvars) - - -def _type_vars(types): - tvars = [] - _get_type_vars(types, tvars) - return tuple(tvars) - - -def _eval_type(t, globalns, localns): - if isinstance(t, TypingMeta) or isinstance(t, _TypingBase): - return t._eval_type(globalns, localns) - return t - - -def _type_check(arg, msg): - """Check that the argument is a type, and return it (internal helper). - - As a special case, accept None and return type(None) instead. - Also, _TypeAlias instances (e.g. Match, Pattern) are acceptable. - - The msg argument is a human-readable error message, e.g. - - "Union[arg, ...]: arg should be a type." - - We append the repr() of the actual value (truncated to 100 chars). - """ - if arg is None: - return type(None) - if isinstance(arg, str): - arg = _ForwardRef(arg) - if ( - isinstance(arg, _TypingBase) and type(arg).__name__ == '_ClassVar' or - not isinstance(arg, (type, _TypingBase)) and not callable(arg) - ): - raise TypeError(msg + " Got %.100r." % (arg,)) - # Bare Union etc. are not valid as type arguments - if ( - type(arg).__name__ in ('_Union', '_Optional') and - not getattr(arg, '__origin__', None) or - isinstance(arg, TypingMeta) and _gorg(arg) in (Generic, _Protocol) - ): - raise TypeError("Plain %s is not valid as type argument" % arg) - return arg - - -def _type_repr(obj): - """Return the repr() of an object, special-casing types (internal helper). - - If obj is a type, we return a shorter version than the default - type.__repr__, based on the module and qualified name, which is - typically enough to uniquely identify a type. For everything - else, we fall back on repr(obj). - """ - if isinstance(obj, type) and not isinstance(obj, TypingMeta): - if obj.__module__ == 'builtins': - return _qualname(obj) - return '%s.%s' % (obj.__module__, _qualname(obj)) - if obj is ...: - return('...') - if isinstance(obj, types.FunctionType): - return obj.__name__ - return repr(obj) - - -class _Any(_FinalTypingBase, _root=True): - """Special type indicating an unconstrained type. - - - Any is compatible with every type. - - Any assumed to have all methods. - - All values assumed to be instances of Any. - - Note that all the above statements are true from the point of view of - static type checkers. At runtime, Any should not be used with instance - or class checks. - """ - - __slots__ = () - - def __instancecheck__(self, obj): - raise TypeError("Any cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - raise TypeError("Any cannot be used with issubclass().") - - -Any = _Any(_root=True) - - -class TypeVar(_TypingBase, _root=True): - """Type variable. - - Usage:: - - T = TypeVar('T') # Can be anything - A = TypeVar('A', str, bytes) # Must be str or bytes - - Type variables exist primarily for the benefit of static type - checkers. They serve as the parameters for generic types as well - as for generic function definitions. See class Generic for more - information on generic types. Generic functions work as follows: - - def repeat(x: T, n: int) -> List[T]: - '''Return a list containing n references to x.''' - return [x]*n - - def longest(x: A, y: A) -> A: - '''Return the longest of two strings.''' - return x if len(x) >= len(y) else y - - The latter example's signature is essentially the overloading - of (str, str) -> str and (bytes, bytes) -> bytes. Also note - that if the arguments are instances of some subclass of str, - the return type is still plain str. - - At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError. - - Type variables defined with covariant=True or contravariant=True - can be used do declare covariant or contravariant generic types. - See PEP 484 for more details. By default generic types are invariant - in all type variables. - - Type variables can be introspected. e.g.: - - T.__name__ == 'T' - T.__constraints__ == () - T.__covariant__ == False - T.__contravariant__ = False - A.__constraints__ == (str, bytes) - """ - - __slots__ = ('__name__', '__bound__', '__constraints__', - '__covariant__', '__contravariant__') - - def __init__(self, name, *constraints, bound=None, - covariant=False, contravariant=False): - super().__init__(name, *constraints, bound=bound, - covariant=covariant, contravariant=contravariant) - self.__name__ = name - if covariant and contravariant: - raise ValueError("Bivariant types are not supported.") - self.__covariant__ = bool(covariant) - self.__contravariant__ = bool(contravariant) - if constraints and bound is not None: - raise TypeError("Constraints cannot be combined with bound=...") - if constraints and len(constraints) == 1: - raise TypeError("A single constraint is not allowed") - msg = "TypeVar(name, constraint, ...): constraints must be types." - self.__constraints__ = tuple(_type_check(t, msg) for t in constraints) - if bound: - self.__bound__ = _type_check(bound, "Bound must be a type.") - else: - self.__bound__ = None - - def _get_type_vars(self, tvars): - if self not in tvars: - tvars.append(self) - - def __repr__(self): - if self.__covariant__: - prefix = '+' - elif self.__contravariant__: - prefix = '-' - else: - prefix = '~' - return prefix + self.__name__ - - def __instancecheck__(self, instance): - raise TypeError("Type variables cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - raise TypeError("Type variables cannot be used with issubclass().") - - -# Some unconstrained type variables. These are used by the container types. -# (These are not for export.) -T = TypeVar('T') # Any type. -KT = TypeVar('KT') # Key type. -VT = TypeVar('VT') # Value type. -T_co = TypeVar('T_co', covariant=True) # Any type covariant containers. -V_co = TypeVar('V_co', covariant=True) # Any type covariant containers. -VT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers. -T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant. - -# A useful type variable with constraints. This represents string types. -# (This one *is* for export!) -AnyStr = TypeVar('AnyStr', bytes, str) - - -def _replace_arg(arg, tvars, args): - """An internal helper function: replace arg if it is a type variable - found in tvars with corresponding substitution from args or - with corresponding substitution sub-tree if arg is a generic type. - """ - - if tvars is None: - tvars = [] - if hasattr(arg, '_subs_tree') and isinstance(arg, (GenericMeta, _TypingBase)): - return arg._subs_tree(tvars, args) - if isinstance(arg, TypeVar): - for i, tvar in enumerate(tvars): - if arg == tvar: - return args[i] - return arg - - -# Special typing constructs Union, Optional, Generic, Callable and Tuple -# use three special attributes for internal bookkeeping of generic types: -# * __parameters__ is a tuple of unique free type parameters of a generic -# type, for example, Dict[T, T].__parameters__ == (T,); -# * __origin__ keeps a reference to a type that was subscripted, -# e.g., Union[T, int].__origin__ == Union; -# * __args__ is a tuple of all arguments used in subscripting, -# e.g., Dict[T, int].__args__ == (T, int). - - -def _subs_tree(cls, tvars=None, args=None): - """An internal helper function: calculate substitution tree - for generic cls after replacing its type parameters with - substitutions in tvars -> args (if any). - Repeat the same following __origin__'s. - - Return a list of arguments with all possible substitutions - performed. Arguments that are generic classes themselves are represented - as tuples (so that no new classes are created by this function). - For example: _subs_tree(List[Tuple[int, T]][str]) == [(Tuple, int, str)] - """ - - if cls.__origin__ is None: - return cls - # Make of chain of origins (i.e. cls -> cls.__origin__) - current = cls.__origin__ - orig_chain = [] - while current.__origin__ is not None: - orig_chain.append(current) - current = current.__origin__ - # Replace type variables in __args__ if asked ... - tree_args = [] - for arg in cls.__args__: - tree_args.append(_replace_arg(arg, tvars, args)) - # ... then continue replacing down the origin chain. - for ocls in orig_chain: - new_tree_args = [] - for arg in ocls.__args__: - new_tree_args.append(_replace_arg(arg, ocls.__parameters__, tree_args)) - tree_args = new_tree_args - return tree_args - - -def _remove_dups_flatten(parameters): - """An internal helper for Union creation and substitution: flatten Union's - among parameters, then remove duplicates and strict subclasses. - """ - - # Flatten out Union[Union[...], ...]. - params = [] - for p in parameters: - if isinstance(p, _Union) and p.__origin__ is Union: - params.extend(p.__args__) - elif isinstance(p, tuple) and len(p) > 0 and p[0] is Union: - params.extend(p[1:]) - else: - params.append(p) - # Weed out strict duplicates, preserving the first of each occurrence. - all_params = set(params) - if len(all_params) < len(params): - new_params = [] - for t in params: - if t in all_params: - new_params.append(t) - all_params.remove(t) - params = new_params - assert not all_params, all_params - # Weed out subclasses. - # E.g. Union[int, Employee, Manager] == Union[int, Employee]. - # If object is present it will be sole survivor among proper classes. - # Never discard type variables. - # (In particular, Union[str, AnyStr] != AnyStr.) - all_params = set(params) - for t1 in params: - if not isinstance(t1, type): - continue - if any(isinstance(t2, type) and issubclass(t1, t2) - for t2 in all_params - {t1} - if not (isinstance(t2, GenericMeta) and - t2.__origin__ is not None)): - all_params.remove(t1) - return tuple(t for t in params if t in all_params) - - -def _check_generic(cls, parameters): - # Check correct count for parameters of a generic cls (internal helper). - if not cls.__parameters__: - raise TypeError("%s is not a generic class" % repr(cls)) - alen = len(parameters) - elen = len(cls.__parameters__) - if alen != elen: - raise TypeError("Too %s parameters for %s; actual %s, expected %s" % - ("many" if alen > elen else "few", repr(cls), alen, elen)) - - -_cleanups = [] - - -def _tp_cache(func): - """Internal wrapper caching __getitem__ of generic types with a fallback to - original function for non-hashable arguments. - """ - - cached = functools.lru_cache()(func) - _cleanups.append(cached.cache_clear) - - @functools.wraps(func) - def inner(*args, **kwds): - try: - return cached(*args, **kwds) - except TypeError: - pass # All real errors (not unhashable args) are raised below. - return func(*args, **kwds) - return inner - - -class _Union(_FinalTypingBase, _root=True): - """Union type; Union[X, Y] means either X or Y. - - To define a union, use e.g. Union[int, str]. Details: - - - The arguments must be types and there must be at least one. - - - None as an argument is a special case and is replaced by - type(None). - - - Unions of unions are flattened, e.g.:: - - Union[Union[int, str], float] == Union[int, str, float] - - - Unions of a single argument vanish, e.g.:: - - Union[int] == int # The constructor actually returns int - - - Redundant arguments are skipped, e.g.:: - - Union[int, str, int] == Union[int, str] - - - When comparing unions, the argument order is ignored, e.g.:: - - Union[int, str] == Union[str, int] - - - When two arguments have a subclass relationship, the least - derived argument is kept, e.g.:: - - class Employee: pass - class Manager(Employee): pass - Union[int, Employee, Manager] == Union[int, Employee] - Union[Manager, int, Employee] == Union[int, Employee] - Union[Employee, Manager] == Employee - - - Similar for object:: - - Union[int, object] == object - - - You cannot subclass or instantiate a union. - - - You can use Optional[X] as a shorthand for Union[X, None]. - """ - - __slots__ = ('__parameters__', '__args__', '__origin__', '__tree_hash__') - - def __new__(cls, parameters=None, origin=None, *args, _root=False): - self = super().__new__(cls, parameters, origin, *args, _root=_root) - if origin is None: - self.__parameters__ = None - self.__args__ = None - self.__origin__ = None - self.__tree_hash__ = hash(frozenset(('Union',))) - return self - if not isinstance(parameters, tuple): - raise TypeError("Expected parameters=") - if origin is Union: - parameters = _remove_dups_flatten(parameters) - # It's not a union if there's only one type left. - if len(parameters) == 1: - return parameters[0] - self.__parameters__ = _type_vars(parameters) - self.__args__ = parameters - self.__origin__ = origin - # Pre-calculate the __hash__ on instantiation. - # This improves speed for complex substitutions. - subs_tree = self._subs_tree() - if isinstance(subs_tree, tuple): - self.__tree_hash__ = hash(frozenset(subs_tree)) - else: - self.__tree_hash__ = hash(subs_tree) - return self - - def _eval_type(self, globalns, localns): - if self.__args__ is None: - return self - ev_args = tuple(_eval_type(t, globalns, localns) for t in self.__args__) - ev_origin = _eval_type(self.__origin__, globalns, localns) - if ev_args == self.__args__ and ev_origin == self.__origin__: - # Everything is already evaluated. - return self - return self.__class__(ev_args, ev_origin, _root=True) - - def _get_type_vars(self, tvars): - if self.__origin__ and self.__parameters__: - _get_type_vars(self.__parameters__, tvars) - - def __repr__(self): - if self.__origin__ is None: - return super().__repr__() - tree = self._subs_tree() - if not isinstance(tree, tuple): - return repr(tree) - return tree[0]._tree_repr(tree) - - def _tree_repr(self, tree): - arg_list = [] - for arg in tree[1:]: - if not isinstance(arg, tuple): - arg_list.append(_type_repr(arg)) - else: - arg_list.append(arg[0]._tree_repr(arg)) - return super().__repr__() + '[%s]' % ', '.join(arg_list) - - @_tp_cache - def __getitem__(self, parameters): - if parameters == (): - raise TypeError("Cannot take a Union of no types.") - if not isinstance(parameters, tuple): - parameters = (parameters,) - if self.__origin__ is None: - msg = "Union[arg, ...]: each arg must be a type." - else: - msg = "Parameters to generic types must be types." - parameters = tuple(_type_check(p, msg) for p in parameters) - if self is not Union: - _check_generic(self, parameters) - return self.__class__(parameters, origin=self, _root=True) - - def _subs_tree(self, tvars=None, args=None): - if self is Union: - return Union # Nothing to substitute - tree_args = _subs_tree(self, tvars, args) - tree_args = _remove_dups_flatten(tree_args) - if len(tree_args) == 1: - return tree_args[0] # Union of a single type is that type - return (Union,) + tree_args - - def __eq__(self, other): - if isinstance(other, _Union): - return self.__tree_hash__ == other.__tree_hash__ - elif self is not Union: - return self._subs_tree() == other - else: - return self is other - - def __hash__(self): - return self.__tree_hash__ - - def __instancecheck__(self, obj): - raise TypeError("Unions cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - raise TypeError("Unions cannot be used with issubclass().") - - -Union = _Union(_root=True) - - -class _Optional(_FinalTypingBase, _root=True): - """Optional type. - - Optional[X] is equivalent to Union[X, None]. - """ - - __slots__ = () - - @_tp_cache - def __getitem__(self, arg): - arg = _type_check(arg, "Optional[t] requires a single type.") - return Union[arg, type(None)] - - -Optional = _Optional(_root=True) - - -def _gorg(a): - """Return the farthest origin of a generic class (internal helper).""" - assert isinstance(a, GenericMeta) - while a.__origin__ is not None: - a = a.__origin__ - return a - - -def _geqv(a, b): - """Return whether two generic classes are equivalent (internal helper). - - The intention is to consider generic class X and any of its - parameterized forms (X[T], X[int], etc.) as equivalent. - - However, X is not equivalent to a subclass of X. - - The relation is reflexive, symmetric and transitive. - """ - assert isinstance(a, GenericMeta) and isinstance(b, GenericMeta) - # Reduce each to its origin. - return _gorg(a) is _gorg(b) - - -def _next_in_mro(cls): - """Helper for Generic.__new__. - - Returns the class after the last occurrence of Generic or - Generic[...] in cls.__mro__. - """ - next_in_mro = object - # Look for the last occurrence of Generic or Generic[...]. - for i, c in enumerate(cls.__mro__[:-1]): - if isinstance(c, GenericMeta) and _gorg(c) is Generic: - next_in_mro = cls.__mro__[i + 1] - return next_in_mro - - -def _make_subclasshook(cls): - """Construct a __subclasshook__ callable that incorporates - the associated __extra__ class in subclass checks performed - against cls. - """ - if isinstance(cls.__extra__, abc.ABCMeta): - # The logic mirrors that of ABCMeta.__subclasscheck__. - # Registered classes need not be checked here because - # cls and its extra share the same _abc_registry. - def __extrahook__(subclass): - res = cls.__extra__.__subclasshook__(subclass) - if res is not NotImplemented: - return res - if cls.__extra__ in subclass.__mro__: - return True - for scls in cls.__extra__.__subclasses__(): - if isinstance(scls, GenericMeta): - continue - if issubclass(subclass, scls): - return True - return NotImplemented - else: - # For non-ABC extras we'll just call issubclass(). - def __extrahook__(subclass): - if cls.__extra__ and issubclass(subclass, cls.__extra__): - return True - return NotImplemented - return __extrahook__ - - -def _no_slots_copy(dct): - """Internal helper: copy class __dict__ and clean slots class variables. - (They will be re-created if necessary by normal class machinery.) - """ - dict_copy = dict(dct) - if '__slots__' in dict_copy: - for slot in dict_copy['__slots__']: - dict_copy.pop(slot, None) - return dict_copy - - -class GenericMeta(TypingMeta, abc.ABCMeta): - """Metaclass for generic types. - - This is a metaclass for typing.Generic and generic ABCs defined in - typing module. User defined subclasses of GenericMeta can override - __new__ and invoke super().__new__. Note that GenericMeta.__new__ - has strict rules on what is allowed in its bases argument: - * plain Generic is disallowed in bases; - * Generic[...] should appear in bases at most once; - * if Generic[...] is present, then it should list all type variables - that appear in other bases. - In addition, type of all generic bases is erased, e.g., C[int] is - stripped to plain C. - """ - - def __new__(cls, name, bases, namespace, - tvars=None, args=None, origin=None, extra=None, orig_bases=None): - """Create a new generic class. GenericMeta.__new__ accepts - keyword arguments that are used for internal bookkeeping, therefore - an override should pass unused keyword arguments to super(). - """ - if tvars is not None: - # Called from __getitem__() below. - assert origin is not None - assert all(isinstance(t, TypeVar) for t in tvars), tvars - else: - # Called from class statement. - assert tvars is None, tvars - assert args is None, args - assert origin is None, origin - - # Get the full set of tvars from the bases. - tvars = _type_vars(bases) - # Look for Generic[T1, ..., Tn]. - # If found, tvars must be a subset of it. - # If not found, tvars is it. - # Also check for and reject plain Generic, - # and reject multiple Generic[...]. - gvars = None - for base in bases: - if base is Generic: - raise TypeError("Cannot inherit from plain Generic") - if (isinstance(base, GenericMeta) and - base.__origin__ is Generic): - if gvars is not None: - raise TypeError( - "Cannot inherit from Generic[...] multiple types.") - gvars = base.__parameters__ - if gvars is None: - gvars = tvars - else: - tvarset = set(tvars) - gvarset = set(gvars) - if not tvarset <= gvarset: - raise TypeError( - "Some type variables (%s) " - "are not listed in Generic[%s]" % - (", ".join(str(t) for t in tvars if t not in gvarset), - ", ".join(str(g) for g in gvars))) - tvars = gvars - - initial_bases = bases - if extra is not None and type(extra) is abc.ABCMeta and extra not in bases: - bases = (extra,) + bases - bases = tuple(_gorg(b) if isinstance(b, GenericMeta) else b for b in bases) - - # remove bare Generic from bases if there are other generic bases - if any(isinstance(b, GenericMeta) and b is not Generic for b in bases): - bases = tuple(b for b in bases if b is not Generic) - namespace.update({'__origin__': origin, '__extra__': extra}) - self = super().__new__(cls, name, bases, namespace, _root=True) - - self.__parameters__ = tvars - # Be prepared that GenericMeta will be subclassed by TupleMeta - # and CallableMeta, those two allow ..., (), or [] in __args___. - self.__args__ = tuple(... if a is _TypingEllipsis else - () if a is _TypingEmpty else - a for a in args) if args else None - # Speed hack (https://github.com/python/typing/issues/196). - self.__next_in_mro__ = _next_in_mro(self) - # Preserve base classes on subclassing (__bases__ are type erased now). - if orig_bases is None: - self.__orig_bases__ = initial_bases - - # This allows unparameterized generic collections to be used - # with issubclass() and isinstance() in the same way as their - # collections.abc counterparts (e.g., isinstance([], Iterable)). - if ( - '__subclasshook__' not in namespace and extra or - # allow overriding - getattr(self.__subclasshook__, '__name__', '') == '__extrahook__' - ): - self.__subclasshook__ = _make_subclasshook(self) - if isinstance(extra, abc.ABCMeta): - self._abc_registry = extra._abc_registry - self._abc_cache = extra._abc_cache - elif origin is not None: - self._abc_registry = origin._abc_registry - self._abc_cache = origin._abc_cache - - if origin and hasattr(origin, '__qualname__'): # Fix for Python 3.2. - self.__qualname__ = origin.__qualname__ - self.__tree_hash__ = (hash(self._subs_tree()) if origin else - super(GenericMeta, self).__hash__()) - return self - - # _abc_negative_cache and _abc_negative_cache_version - # realised as descriptors, since GenClass[t1, t2, ...] always - # share subclass info with GenClass. - # This is an important memory optimization. - @property - def _abc_negative_cache(self): - if isinstance(self.__extra__, abc.ABCMeta): - return self.__extra__._abc_negative_cache - return _gorg(self)._abc_generic_negative_cache - - @_abc_negative_cache.setter - def _abc_negative_cache(self, value): - if self.__origin__ is None: - if isinstance(self.__extra__, abc.ABCMeta): - self.__extra__._abc_negative_cache = value - else: - self._abc_generic_negative_cache = value - - @property - def _abc_negative_cache_version(self): - if isinstance(self.__extra__, abc.ABCMeta): - return self.__extra__._abc_negative_cache_version - return _gorg(self)._abc_generic_negative_cache_version - - @_abc_negative_cache_version.setter - def _abc_negative_cache_version(self, value): - if self.__origin__ is None: - if isinstance(self.__extra__, abc.ABCMeta): - self.__extra__._abc_negative_cache_version = value - else: - self._abc_generic_negative_cache_version = value - - def _get_type_vars(self, tvars): - if self.__origin__ and self.__parameters__: - _get_type_vars(self.__parameters__, tvars) - - def _eval_type(self, globalns, localns): - ev_origin = (self.__origin__._eval_type(globalns, localns) - if self.__origin__ else None) - ev_args = tuple(_eval_type(a, globalns, localns) for a - in self.__args__) if self.__args__ else None - if ev_origin == self.__origin__ and ev_args == self.__args__: - return self - return self.__class__(self.__name__, - self.__bases__, - _no_slots_copy(self.__dict__), - tvars=_type_vars(ev_args) if ev_args else None, - args=ev_args, - origin=ev_origin, - extra=self.__extra__, - orig_bases=self.__orig_bases__) - - def __repr__(self): - if self.__origin__ is None: - return super().__repr__() - return self._tree_repr(self._subs_tree()) - - def _tree_repr(self, tree): - arg_list = [] - for arg in tree[1:]: - if arg == (): - arg_list.append('()') - elif not isinstance(arg, tuple): - arg_list.append(_type_repr(arg)) - else: - arg_list.append(arg[0]._tree_repr(arg)) - return super().__repr__() + '[%s]' % ', '.join(arg_list) - - def _subs_tree(self, tvars=None, args=None): - if self.__origin__ is None: - return self - tree_args = _subs_tree(self, tvars, args) - return (_gorg(self),) + tuple(tree_args) - - def __eq__(self, other): - if not isinstance(other, GenericMeta): - return NotImplemented - if self.__origin__ is None or other.__origin__ is None: - return self is other - return self.__tree_hash__ == other.__tree_hash__ - - def __hash__(self): - return self.__tree_hash__ - - @_tp_cache - def __getitem__(self, params): - if not isinstance(params, tuple): - params = (params,) - if not params and not _gorg(self) is Tuple: - raise TypeError( - "Parameter list to %s[...] cannot be empty" % _qualname(self)) - msg = "Parameters to generic types must be types." - params = tuple(_type_check(p, msg) for p in params) - if self is Generic: - # Generic can only be subscripted with unique type variables. - if not all(isinstance(p, TypeVar) for p in params): - raise TypeError( - "Parameters to Generic[...] must all be type variables") - if len(set(params)) != len(params): - raise TypeError( - "Parameters to Generic[...] must all be unique") - tvars = params - args = params - elif self in (Tuple, Callable): - tvars = _type_vars(params) - args = params - elif self is _Protocol: - # _Protocol is internal, don't check anything. - tvars = params - args = params - elif self.__origin__ in (Generic, _Protocol): - # Can't subscript Generic[...] or _Protocol[...]. - raise TypeError("Cannot subscript already-subscripted %s" % - repr(self)) - else: - # Subscripting a regular Generic subclass. - _check_generic(self, params) - tvars = _type_vars(params) - args = params - - prepend = (self,) if self.__origin__ is None else () - return self.__class__(self.__name__, - prepend + self.__bases__, - _no_slots_copy(self.__dict__), - tvars=tvars, - args=args, - origin=self, - extra=self.__extra__, - orig_bases=self.__orig_bases__) - - def __subclasscheck__(self, cls): - if self.__origin__ is not None: - if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools']: - raise TypeError("Parameterized generics cannot be used with class " - "or instance checks") - return False - if self is Generic: - raise TypeError("Class %r cannot be used with class " - "or instance checks" % self) - return super().__subclasscheck__(cls) - - def __instancecheck__(self, instance): - # Since we extend ABC.__subclasscheck__ and - # ABC.__instancecheck__ inlines the cache checking done by the - # latter, we must extend __instancecheck__ too. For simplicity - # we just skip the cache check -- instance checks for generic - # classes are supposed to be rare anyways. - return issubclass(instance.__class__, self) - - def __copy__(self): - return self.__class__(self.__name__, self.__bases__, - _no_slots_copy(self.__dict__), - self.__parameters__, self.__args__, self.__origin__, - self.__extra__, self.__orig_bases__) - - def __setattr__(self, attr, value): - # We consider all the subscripted genrics as proxies for original class - if ( - attr.startswith('__') and attr.endswith('__') or - attr.startswith('_abc_') - ): - super(GenericMeta, self).__setattr__(attr, value) - else: - super(GenericMeta, _gorg(self)).__setattr__(attr, value) - - -# Prevent checks for Generic to crash when defining Generic. -Generic = None - - -def _generic_new(base_cls, cls, *args, **kwds): - # Assure type is erased on instantiation, - # but attempt to store it in __orig_class__ - if cls.__origin__ is None: - return base_cls.__new__(cls) - else: - origin = _gorg(cls) - obj = base_cls.__new__(origin) - try: - obj.__orig_class__ = cls - except AttributeError: - pass - obj.__init__(*args, **kwds) - return obj - - -class Generic(metaclass=GenericMeta): - """Abstract base class for generic types. - - A generic type is typically declared by inheriting from - this class parameterized with one or more type variables. - For example, a generic mapping type might be defined as:: - - class Mapping(Generic[KT, VT]): - def __getitem__(self, key: KT) -> VT: - ... - # Etc. - - This class can then be used as follows:: - - def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: - try: - return mapping[key] - except KeyError: - return default - """ - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Generic): - raise TypeError("Type Generic cannot be instantiated; " - "it can be used only as a base class") - return _generic_new(cls.__next_in_mro__, cls, *args, **kwds) - - -class _TypingEmpty: - """Internal placeholder for () or []. Used by TupleMeta and CallableMeta - to allow empty list/tuple in specific places, without allowing them - to sneak in where prohibited. - """ - - -class _TypingEllipsis: - """Internal placeholder for ... (ellipsis).""" - - -class TupleMeta(GenericMeta): - """Metaclass for Tuple (internal).""" - - @_tp_cache - def __getitem__(self, parameters): - if self.__origin__ is not None or not _geqv(self, Tuple): - # Normal generic rules apply if this is not the first subscription - # or a subscription of a subclass. - return super().__getitem__(parameters) - if parameters == (): - return super().__getitem__((_TypingEmpty,)) - if not isinstance(parameters, tuple): - parameters = (parameters,) - if len(parameters) == 2 and parameters[1] is ...: - msg = "Tuple[t, ...]: t must be a type." - p = _type_check(parameters[0], msg) - return super().__getitem__((p, _TypingEllipsis)) - msg = "Tuple[t0, t1, ...]: each t must be a type." - parameters = tuple(_type_check(p, msg) for p in parameters) - return super().__getitem__(parameters) - - def __instancecheck__(self, obj): - if self.__args__ is None: - return isinstance(obj, tuple) - raise TypeError("Parameterized Tuple cannot be used " - "with isinstance().") - - def __subclasscheck__(self, cls): - if self.__args__ is None: - return issubclass(cls, tuple) - raise TypeError("Parameterized Tuple cannot be used " - "with issubclass().") - - -class Tuple(tuple, extra=tuple, metaclass=TupleMeta): - """Tuple type; Tuple[X, Y] is the cross-product type of X and Y. - - Example: Tuple[T1, T2] is a tuple of two elements corresponding - to type variables T1 and T2. Tuple[int, float, str] is a tuple - of an int, a float and a string. - - To specify a variable-length tuple of homogeneous type, use Tuple[T, ...]. - """ - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Tuple): - raise TypeError("Type Tuple cannot be instantiated; " - "use tuple() instead") - return _generic_new(tuple, cls, *args, **kwds) - - -class CallableMeta(GenericMeta): - """Metaclass for Callable (internal).""" - - def __repr__(self): - if self.__origin__ is None: - return super().__repr__() - return self._tree_repr(self._subs_tree()) - - def _tree_repr(self, tree): - if _gorg(self) is not Callable: - return super()._tree_repr(tree) - # For actual Callable (not its subclass) we override - # super()._tree_repr() for nice formatting. - arg_list = [] - for arg in tree[1:]: - if not isinstance(arg, tuple): - arg_list.append(_type_repr(arg)) - else: - arg_list.append(arg[0]._tree_repr(arg)) - if arg_list[0] == '...': - return repr(tree[0]) + '[..., %s]' % arg_list[1] - return (repr(tree[0]) + - '[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1])) - - def __getitem__(self, parameters): - """A thin wrapper around __getitem_inner__ to provide the latter - with hashable arguments to improve speed. - """ - - if self.__origin__ is not None or not _geqv(self, Callable): - return super().__getitem__(parameters) - if not isinstance(parameters, tuple) or len(parameters) != 2: - raise TypeError("Callable must be used as " - "Callable[[arg, ...], result].") - args, result = parameters - if args is Ellipsis: - parameters = (Ellipsis, result) - else: - if not isinstance(args, list): - raise TypeError("Callable[args, result]: args must be a list." - " Got %.100r." % (args,)) - parameters = (tuple(args), result) - return self.__getitem_inner__(parameters) - - @_tp_cache - def __getitem_inner__(self, parameters): - args, result = parameters - msg = "Callable[args, result]: result must be a type." - result = _type_check(result, msg) - if args is Ellipsis: - return super().__getitem__((_TypingEllipsis, result)) - msg = "Callable[[arg, ...], result]: each arg must be a type." - args = tuple(_type_check(arg, msg) for arg in args) - parameters = args + (result,) - return super().__getitem__(parameters) - - -class Callable(extra=collections_abc.Callable, metaclass=CallableMeta): - """Callable type; Callable[[int], str] is a function of (int) -> str. - - The subscription syntax must always be used with exactly two - values: the argument list and the return type. The argument list - must be a list of types or ellipsis; the return type must be a single type. - - There is no syntax to indicate optional or keyword arguments, - such function types are rarely used as callback types. - """ - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Callable): - raise TypeError("Type Callable cannot be instantiated; " - "use a non-abstract subclass instead") - return _generic_new(cls.__next_in_mro__, cls, *args, **kwds) - - -class _ClassVar(_FinalTypingBase, _root=True): - """Special type construct to mark class variables. - - An annotation wrapped in ClassVar indicates that a given - attribute is intended to be used as a class variable and - should not be set on instances of that class. Usage:: - - class Starship: - stats: ClassVar[Dict[str, int]] = {} # class variable - damage: int = 10 # instance variable - - ClassVar accepts only types and cannot be further subscribed. - - Note that ClassVar is not a class itself, and should not - be used with isinstance() or issubclass(). - """ - - __slots__ = ('__type__',) - - def __init__(self, tp=None, **kwds): - self.__type__ = tp - - def __getitem__(self, item): - cls = type(self) - if self.__type__ is None: - return cls(_type_check(item, - '{} accepts only single type.'.format(cls.__name__[1:])), - _root=True) - raise TypeError('{} cannot be further subscripted' - .format(cls.__name__[1:])) - - def _eval_type(self, globalns, localns): - new_tp = _eval_type(self.__type__, globalns, localns) - if new_tp == self.__type__: - return self - return type(self)(new_tp, _root=True) - - def __repr__(self): - r = super().__repr__() - if self.__type__ is not None: - r += '[{}]'.format(_type_repr(self.__type__)) - return r - - def __hash__(self): - return hash((type(self).__name__, self.__type__)) - - def __eq__(self, other): - if not isinstance(other, _ClassVar): - return NotImplemented - if self.__type__ is not None: - return self.__type__ == other.__type__ - return self is other - - -ClassVar = _ClassVar(_root=True) - - -def cast(typ, val): - """Cast a value to a type. - - This returns the value unchanged. To the type checker this - signals that the return value has the designated type, but at - runtime we intentionally don't check anything (we want this - to be as fast as possible). - """ - return val - - -def _get_defaults(func): - """Internal helper to extract the default arguments, by name.""" - try: - code = func.__code__ - except AttributeError: - # Some built-in functions don't have __code__, __defaults__, etc. - return {} - pos_count = code.co_argcount - arg_names = code.co_varnames - arg_names = arg_names[:pos_count] - defaults = func.__defaults__ or () - kwdefaults = func.__kwdefaults__ - res = dict(kwdefaults) if kwdefaults else {} - pos_offset = pos_count - len(defaults) - for name, value in zip(arg_names[pos_offset:], defaults): - assert name not in res - res[name] = value - return res - - -_allowed_types = (types.FunctionType, types.BuiltinFunctionType, - types.MethodType, types.ModuleType, - SlotWrapperType, MethodWrapperType, MethodDescriptorType) - - -def get_type_hints(obj, globalns=None, localns=None): - """Return type hints for an object. - - This is often the same as obj.__annotations__, but it handles - forward references encoded as string literals, and if necessary - adds Optional[t] if a default value equal to None is set. - - The argument may be a module, class, method, or function. The annotations - are returned as a dictionary. For classes, annotations include also - inherited members. - - TypeError is raised if the argument is not of a type that can contain - annotations, and an empty dictionary is returned if no annotations are - present. - - BEWARE -- the behavior of globalns and localns is counterintuitive - (unless you are familiar with how eval() and exec() work). The - search order is locals first, then globals. - - - If no dict arguments are passed, an attempt is made to use the - globals from obj, and these are also used as the locals. If the - object does not appear to have globals, an exception is raised. - - - If one dict argument is passed, it is used for both globals and - locals. - - - If two dict arguments are passed, they specify globals and - locals, respectively. - """ - - if getattr(obj, '__no_type_check__', None): - return {} - if globalns is None: - globalns = getattr(obj, '__globals__', {}) - if localns is None: - localns = globalns - elif localns is None: - localns = globalns - # Classes require a special treatment. - if isinstance(obj, type): - hints = {} - for base in reversed(obj.__mro__): - ann = base.__dict__.get('__annotations__', {}) - for name, value in ann.items(): - if value is None: - value = type(None) - if isinstance(value, str): - value = _ForwardRef(value) - value = _eval_type(value, globalns, localns) - hints[name] = value - return hints - hints = getattr(obj, '__annotations__', None) - if hints is None: - # Return empty annotations for something that _could_ have them. - if isinstance(obj, _allowed_types): - return {} - else: - raise TypeError('{!r} is not a module, class, method, ' - 'or function.'.format(obj)) - defaults = _get_defaults(obj) - hints = dict(hints) - for name, value in hints.items(): - if value is None: - value = type(None) - if isinstance(value, str): - value = _ForwardRef(value) - value = _eval_type(value, globalns, localns) - if name in defaults and defaults[name] is None: - value = Optional[value] - hints[name] = value - return hints - - -def no_type_check(arg): - """Decorator to indicate that annotations are not type hints. - - The argument must be a class or function; if it is a class, it - applies recursively to all methods and classes defined in that class - (but not to methods defined in its superclasses or subclasses). - - This mutates the function(s) or class(es) in place. - """ - if isinstance(arg, type): - arg_attrs = arg.__dict__.copy() - for attr, val in arg.__dict__.items(): - if val in arg.__bases__: - arg_attrs.pop(attr) - for obj in arg_attrs.values(): - if isinstance(obj, types.FunctionType): - obj.__no_type_check__ = True - if isinstance(obj, type): - no_type_check(obj) - try: - arg.__no_type_check__ = True - except TypeError: # built-in classes - pass - return arg - - -def no_type_check_decorator(decorator): - """Decorator to give another decorator the @no_type_check effect. - - This wraps the decorator with something that wraps the decorated - function in @no_type_check. - """ - - @functools.wraps(decorator) - def wrapped_decorator(*args, **kwds): - func = decorator(*args, **kwds) - func = no_type_check(func) - return func - - return wrapped_decorator - - -def _overload_dummy(*args, **kwds): - """Helper for @overload to raise when called.""" - raise NotImplementedError( - "You should not call an overloaded function. " - "A series of @overload-decorated functions " - "outside a stub module should always be followed " - "by an implementation that is not @overload-ed.") - - -def overload(func): - """Decorator for overloaded functions/methods. - - In a stub file, place two or more stub definitions for the same - function in a row, each decorated with @overload. For example: - - @overload - def utf8(value: None) -> None: ... - @overload - def utf8(value: bytes) -> bytes: ... - @overload - def utf8(value: str) -> bytes: ... - - In a non-stub file (i.e. a regular .py file), do the same but - follow it with an implementation. The implementation should *not* - be decorated with @overload. For example: - - @overload - def utf8(value: None) -> None: ... - @overload - def utf8(value: bytes) -> bytes: ... - @overload - def utf8(value: str) -> bytes: ... - def utf8(value): - # implementation goes here - """ - return _overload_dummy - - -class _ProtocolMeta(GenericMeta): - """Internal metaclass for _Protocol. - - This exists so _Protocol classes can be generic without deriving - from Generic. - """ - - def __instancecheck__(self, obj): - if _Protocol not in self.__bases__: - return super().__instancecheck__(obj) - raise TypeError("Protocols cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - if not self._is_protocol: - # No structural checks since this isn't a protocol. - return NotImplemented - - if self is _Protocol: - # Every class is a subclass of the empty protocol. - return True - - # Find all attributes defined in the protocol. - attrs = self._get_protocol_attrs() - - for attr in attrs: - if not any(attr in d.__dict__ for d in cls.__mro__): - return False - return True - - def _get_protocol_attrs(self): - # Get all Protocol base classes. - protocol_bases = [] - for c in self.__mro__: - if getattr(c, '_is_protocol', False) and c.__name__ != '_Protocol': - protocol_bases.append(c) - - # Get attributes included in protocol. - attrs = set() - for base in protocol_bases: - for attr in base.__dict__.keys(): - # Include attributes not defined in any non-protocol bases. - for c in self.__mro__: - if (c is not base and attr in c.__dict__ and - not getattr(c, '_is_protocol', False)): - break - else: - if (not attr.startswith('_abc_') and - attr != '__abstractmethods__' and - attr != '__annotations__' and - attr != '__weakref__' and - attr != '_is_protocol' and - attr != '__dict__' and - attr != '__args__' and - attr != '__slots__' and - attr != '_get_protocol_attrs' and - attr != '__next_in_mro__' and - attr != '__parameters__' and - attr != '__origin__' and - attr != '__orig_bases__' and - attr != '__extra__' and - attr != '__tree_hash__' and - attr != '__module__'): - attrs.add(attr) - - return attrs - - -class _Protocol(metaclass=_ProtocolMeta): - """Internal base class for protocol classes. - - This implements a simple-minded structural issubclass check - (similar but more general than the one-offs in collections.abc - such as Hashable). - """ - - __slots__ = () - - _is_protocol = True - - -# Various ABCs mimicking those in collections.abc. -# A few are simply re-exported for completeness. - -Hashable = collections_abc.Hashable # Not generic. - - -if hasattr(collections_abc, 'Awaitable'): - class Awaitable(Generic[T_co], extra=collections_abc.Awaitable): - __slots__ = () - - __all__.append('Awaitable') - - -if hasattr(collections_abc, 'Coroutine'): - class Coroutine(Awaitable[V_co], Generic[T_co, T_contra, V_co], - extra=collections_abc.Coroutine): - __slots__ = () - - __all__.append('Coroutine') - - -if hasattr(collections_abc, 'AsyncIterable'): - - class AsyncIterable(Generic[T_co], extra=collections_abc.AsyncIterable): - __slots__ = () - - class AsyncIterator(AsyncIterable[T_co], - extra=collections_abc.AsyncIterator): - __slots__ = () - - __all__.append('AsyncIterable') - __all__.append('AsyncIterator') - - -class Iterable(Generic[T_co], extra=collections_abc.Iterable): - __slots__ = () - - -class Iterator(Iterable[T_co], extra=collections_abc.Iterator): - __slots__ = () - - -class SupportsInt(_Protocol): - __slots__ = () - - @abstractmethod - def __int__(self) -> int: - pass - - -class SupportsFloat(_Protocol): - __slots__ = () - - @abstractmethod - def __float__(self) -> float: - pass - - -class SupportsComplex(_Protocol): - __slots__ = () - - @abstractmethod - def __complex__(self) -> complex: - pass - - -class SupportsBytes(_Protocol): - __slots__ = () - - @abstractmethod - def __bytes__(self) -> bytes: - pass - - -class SupportsAbs(_Protocol[T_co]): - __slots__ = () - - @abstractmethod - def __abs__(self) -> T_co: - pass - - -class SupportsRound(_Protocol[T_co]): - __slots__ = () - - @abstractmethod - def __round__(self, ndigits: int = 0) -> T_co: - pass - - -if hasattr(collections_abc, 'Reversible'): - class Reversible(Iterable[T_co], extra=collections_abc.Reversible): - __slots__ = () -else: - class Reversible(_Protocol[T_co]): - __slots__ = () - - @abstractmethod - def __reversed__(self) -> 'Iterator[T_co]': - pass - - -Sized = collections_abc.Sized # Not generic. - - -class Container(Generic[T_co], extra=collections_abc.Container): - __slots__ = () - - -if hasattr(collections_abc, 'Collection'): - class Collection(Sized, Iterable[T_co], Container[T_co], - extra=collections_abc.Collection): - __slots__ = () - - __all__.append('Collection') - - -# Callable was defined earlier. - -if hasattr(collections_abc, 'Collection'): - class AbstractSet(Collection[T_co], - extra=collections_abc.Set): - __slots__ = () -else: - class AbstractSet(Sized, Iterable[T_co], Container[T_co], - extra=collections_abc.Set): - __slots__ = () - - -class MutableSet(AbstractSet[T], extra=collections_abc.MutableSet): - __slots__ = () - - -# NOTE: It is only covariant in the value type. -if hasattr(collections_abc, 'Collection'): - class Mapping(Collection[KT], Generic[KT, VT_co], - extra=collections_abc.Mapping): - __slots__ = () -else: - class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co], - extra=collections_abc.Mapping): - __slots__ = () - - -class MutableMapping(Mapping[KT, VT], extra=collections_abc.MutableMapping): - __slots__ = () - - -if hasattr(collections_abc, 'Reversible'): - if hasattr(collections_abc, 'Collection'): - class Sequence(Reversible[T_co], Collection[T_co], - extra=collections_abc.Sequence): - __slots__ = () - else: - class Sequence(Sized, Reversible[T_co], Container[T_co], - extra=collections_abc.Sequence): - __slots__ = () -else: - class Sequence(Sized, Iterable[T_co], Container[T_co], - extra=collections_abc.Sequence): - __slots__ = () - - -class MutableSequence(Sequence[T], extra=collections_abc.MutableSequence): - __slots__ = () - - -class ByteString(Sequence[int], extra=collections_abc.ByteString): - __slots__ = () - - -class List(list, MutableSequence[T], extra=list): - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, List): - raise TypeError("Type List cannot be instantiated; " - "use list() instead") - return _generic_new(list, cls, *args, **kwds) - - -class Deque(collections.deque, MutableSequence[T], extra=collections.deque): - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Deque): - return collections.deque(*args, **kwds) - return _generic_new(collections.deque, cls, *args, **kwds) - - -class Set(set, MutableSet[T], extra=set): - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Set): - raise TypeError("Type Set cannot be instantiated; " - "use set() instead") - return _generic_new(set, cls, *args, **kwds) - - -class FrozenSet(frozenset, AbstractSet[T_co], extra=frozenset): - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, FrozenSet): - raise TypeError("Type FrozenSet cannot be instantiated; " - "use frozenset() instead") - return _generic_new(frozenset, cls, *args, **kwds) - - -class MappingView(Sized, Iterable[T_co], extra=collections_abc.MappingView): - __slots__ = () - - -class KeysView(MappingView[KT], AbstractSet[KT], - extra=collections_abc.KeysView): - __slots__ = () - - -class ItemsView(MappingView[Tuple[KT, VT_co]], - AbstractSet[Tuple[KT, VT_co]], - Generic[KT, VT_co], - extra=collections_abc.ItemsView): - __slots__ = () - - -class ValuesView(MappingView[VT_co], extra=collections_abc.ValuesView): - __slots__ = () - - -if hasattr(contextlib, 'AbstractContextManager'): - class ContextManager(Generic[T_co], extra=contextlib.AbstractContextManager): - __slots__ = () - __all__.append('ContextManager') - - -class Dict(dict, MutableMapping[KT, VT], extra=dict): - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Dict): - raise TypeError("Type Dict cannot be instantiated; " - "use dict() instead") - return _generic_new(dict, cls, *args, **kwds) - - -class DefaultDict(collections.defaultdict, MutableMapping[KT, VT], - extra=collections.defaultdict): - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, DefaultDict): - return collections.defaultdict(*args, **kwds) - return _generic_new(collections.defaultdict, cls, *args, **kwds) - - -class Counter(collections.Counter, Dict[T, int], extra=collections.Counter): - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Counter): - return collections.Counter(*args, **kwds) - return _generic_new(collections.Counter, cls, *args, **kwds) - - -if hasattr(collections, 'ChainMap'): - # ChainMap only exists in 3.3+ - __all__.append('ChainMap') - - class ChainMap(collections.ChainMap, MutableMapping[KT, VT], - extra=collections.ChainMap): - - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, ChainMap): - return collections.ChainMap(*args, **kwds) - return _generic_new(collections.ChainMap, cls, *args, **kwds) - - -# Determine what base class to use for Generator. -if hasattr(collections_abc, 'Generator'): - # Sufficiently recent versions of 3.5 have a Generator ABC. - _G_base = collections_abc.Generator -else: - # Fall back on the exact type. - _G_base = types.GeneratorType - - -class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co], - extra=_G_base): - __slots__ = () - - def __new__(cls, *args, **kwds): - if _geqv(cls, Generator): - raise TypeError("Type Generator cannot be instantiated; " - "create a subclass instead") - return _generic_new(_G_base, cls, *args, **kwds) - - -if hasattr(collections_abc, 'AsyncGenerator'): - class AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra], - extra=collections_abc.AsyncGenerator): - __slots__ = () - - __all__.append('AsyncGenerator') - - -# Internal type variable used for Type[]. -CT_co = TypeVar('CT_co', covariant=True, bound=type) - - -# This is not a real generic class. Don't use outside annotations. -class Type(Generic[CT_co], extra=type): - """A special construct usable to annotate class objects. - - For example, suppose we have the following classes:: - - class User: ... # Abstract base for User classes - class BasicUser(User): ... - class ProUser(User): ... - class TeamUser(User): ... - - And a function that takes a class argument that's a subclass of - User and returns an instance of the corresponding class:: - - U = TypeVar('U', bound=User) - def new_user(user_class: Type[U]) -> U: - user = user_class() - # (Here we could write the user object to a database) - return user - - joe = new_user(BasicUser) - - At this point the type checker knows that joe has type BasicUser. - """ - - __slots__ = () - - -def _make_nmtuple(name, types): - msg = "NamedTuple('Name', [(f0, t0), (f1, t1), ...]); each t must be a type" - types = [(n, _type_check(t, msg)) for n, t in types] - nm_tpl = collections.namedtuple(name, [n for n, t in types]) - # Prior to PEP 526, only _field_types attribute was assigned. - # Now, both __annotations__ and _field_types are used to maintain compatibility. - nm_tpl.__annotations__ = nm_tpl._field_types = collections.OrderedDict(types) - try: - nm_tpl.__module__ = sys._getframe(2).f_globals.get('__name__', '__main__') - except (AttributeError, ValueError): - pass - return nm_tpl - - -_PY36 = sys.version_info[:2] >= (3, 6) - -# attributes prohibited to set in NamedTuple class syntax -_prohibited = ('__new__', '__init__', '__slots__', '__getnewargs__', - '_fields', '_field_defaults', '_field_types', - '_make', '_replace', '_asdict') - -_special = ('__module__', '__name__', '__qualname__', '__annotations__') - - -class NamedTupleMeta(type): - - def __new__(cls, typename, bases, ns): - if ns.get('_root', False): - return super().__new__(cls, typename, bases, ns) - if not _PY36: - raise TypeError("Class syntax for NamedTuple is only supported" - " in Python 3.6+") - types = ns.get('__annotations__', {}) - nm_tpl = _make_nmtuple(typename, types.items()) - defaults = [] - defaults_dict = {} - for field_name in types: - if field_name in ns: - default_value = ns[field_name] - defaults.append(default_value) - defaults_dict[field_name] = default_value - elif defaults: - raise TypeError("Non-default namedtuple field {field_name} cannot " - "follow default field(s) {default_names}" - .format(field_name=field_name, - default_names=', '.join(defaults_dict.keys()))) - nm_tpl.__new__.__defaults__ = tuple(defaults) - nm_tpl._field_defaults = defaults_dict - # update from user namespace without overriding special namedtuple attributes - for key in ns: - if key in _prohibited: - raise AttributeError("Cannot overwrite NamedTuple attribute " + key) - elif key not in _special and key not in nm_tpl._fields: - setattr(nm_tpl, key, ns[key]) - return nm_tpl - - -class NamedTuple(metaclass=NamedTupleMeta): - """Typed version of namedtuple. - - Usage in Python versions >= 3.6:: - - class Employee(NamedTuple): - name: str - id: int - - This is equivalent to:: - - Employee = collections.namedtuple('Employee', ['name', 'id']) - - The resulting class has extra __annotations__ and _field_types - attributes, giving an ordered dict mapping field names to types. - __annotations__ should be preferred, while _field_types - is kept to maintain pre PEP 526 compatibility. (The field names - are in the _fields attribute, which is part of the namedtuple - API.) Alternative equivalent keyword syntax is also accepted:: - - Employee = NamedTuple('Employee', name=str, id=int) - - In Python versions <= 3.5 use:: - - Employee = NamedTuple('Employee', [('name', str), ('id', int)]) - """ - _root = True - - def __new__(self, typename, fields=None, **kwargs): - if kwargs and not _PY36: - raise TypeError("Keyword syntax for NamedTuple is only supported" - " in Python 3.6+") - if fields is None: - fields = kwargs.items() - elif kwargs: - raise TypeError("Either list of fields or keywords" - " can be provided to NamedTuple, not both") - return _make_nmtuple(typename, fields) - - -def NewType(name, tp): - """NewType creates simple unique types with almost zero - runtime overhead. NewType(name, tp) is considered a subtype of tp - by static type checkers. At runtime, NewType(name, tp) returns - a dummy function that simply returns its argument. Usage:: - - UserId = NewType('UserId', int) - - def name_by_id(user_id: UserId) -> str: - ... - - UserId('user') # Fails type check - - name_by_id(42) # Fails type check - name_by_id(UserId(42)) # OK - - num = UserId(5) + 1 # type: int - """ - - def new_type(x): - return x - - new_type.__name__ = name - new_type.__supertype__ = tp - return new_type - - -# Python-version-specific alias (Python 2: unicode; Python 3: str) -Text = str - - -# Constant that's True when type checking, but False here. -TYPE_CHECKING = False - - -class IO(Generic[AnyStr]): - """Generic base class for TextIO and BinaryIO. - - This is an abstract, generic version of the return of open(). - - NOTE: This does not distinguish between the different possible - classes (text vs. binary, read vs. write vs. read/write, - append-only, unbuffered). The TextIO and BinaryIO subclasses - below capture the distinctions between text vs. binary, which is - pervasive in the interface; however we currently do not offer a - way to track the other distinctions in the type system. - """ - - __slots__ = () - - @abstractproperty - def mode(self) -> str: - pass - - @abstractproperty - def name(self) -> str: - pass - - @abstractmethod - def close(self) -> None: - pass - - @abstractmethod - def closed(self) -> bool: - pass - - @abstractmethod - def fileno(self) -> int: - pass - - @abstractmethod - def flush(self) -> None: - pass - - @abstractmethod - def isatty(self) -> bool: - pass - - @abstractmethod - def read(self, n: int = -1) -> AnyStr: - pass - - @abstractmethod - def readable(self) -> bool: - pass - - @abstractmethod - def readline(self, limit: int = -1) -> AnyStr: - pass - - @abstractmethod - def readlines(self, hint: int = -1) -> List[AnyStr]: - pass - - @abstractmethod - def seek(self, offset: int, whence: int = 0) -> int: - pass - - @abstractmethod - def seekable(self) -> bool: - pass - - @abstractmethod - def tell(self) -> int: - pass - - @abstractmethod - def truncate(self, size: int = None) -> int: - pass - - @abstractmethod - def writable(self) -> bool: - pass - - @abstractmethod - def write(self, s: AnyStr) -> int: - pass - - @abstractmethod - def writelines(self, lines: List[AnyStr]) -> None: - pass - - @abstractmethod - def __enter__(self) -> 'IO[AnyStr]': - pass - - @abstractmethod - def __exit__(self, type, value, traceback) -> None: - pass - - -class BinaryIO(IO[bytes]): - """Typed version of the return of open() in binary mode.""" - - __slots__ = () - - @abstractmethod - def write(self, s: Union[bytes, bytearray]) -> int: - pass - - @abstractmethod - def __enter__(self) -> 'BinaryIO': - pass - - -class TextIO(IO[str]): - """Typed version of the return of open() in text mode.""" - - __slots__ = () - - @abstractproperty - def buffer(self) -> BinaryIO: - pass - - @abstractproperty - def encoding(self) -> str: - pass - - @abstractproperty - def errors(self) -> Optional[str]: - pass - - @abstractproperty - def line_buffering(self) -> bool: - pass - - @abstractproperty - def newlines(self) -> Any: - pass - - @abstractmethod - def __enter__(self) -> 'TextIO': - pass - - -class io: - """Wrapper namespace for IO generic classes.""" - - __all__ = ['IO', 'TextIO', 'BinaryIO'] - IO = IO - TextIO = TextIO - BinaryIO = BinaryIO - - -io.__name__ = __name__ + '.io' -sys.modules[io.__name__] = io - - -Pattern = _TypeAlias('Pattern', AnyStr, type(stdlib_re.compile('')), - lambda p: p.pattern) -Match = _TypeAlias('Match', AnyStr, type(stdlib_re.match('', '')), - lambda m: m.re.pattern) - - -class re: - """Wrapper namespace for re type aliases.""" - - __all__ = ['Pattern', 'Match'] - Pattern = Pattern - Match = Match - - -re.__name__ = __name__ + '.re' -sys.modules[re.__name__] = re diff --git a/mypy/test/testpythoneval.py b/mypy/test/testpythoneval.py index 85e9aa3751d7..602692e073e4 100644 --- a/mypy/test/testpythoneval.py +++ b/mypy/test/testpythoneval.py @@ -84,14 +84,8 @@ def test_python_evaluation(testcase: DataDrivenTestCase) -> None: # This uses the same PYTHONPATH as the current process. returncode, out = run(mypy_cmdline) if returncode == 0: - # Set up module path for the execution. - # This needs the typing module but *not* the mypy module. - vers_dir = '2.7' if py2 else '3.2' - typing_path = os.path.join(testcase.old_cwd, 'lib-typing', vers_dir) - assert os.path.isdir(typing_path) - env = os.environ.copy() - env['PYTHONPATH'] = typing_path - returncode, interp_out = run([interpreter, program], env=env) + # Execute the program. + returncode, interp_out = run([interpreter, program]) out += interp_out # Remove temp file. os.remove(program_path) diff --git a/runtests.py b/runtests.py index 3371f9ae8b91..e4f5ce44bb61 100755 --- a/runtests.py +++ b/runtests.py @@ -1,29 +1,6 @@ #!/usr/bin/env python3 """Mypy test runner.""" -if False: - import typing - -if True: - # When this is run as a script, `typing` is not available yet. - import sys - from os.path import join, isdir - - def get_versions(): # type: () -> typing.List[str] - major = sys.version_info[0] - minor = sys.version_info[1] - if major == 2: - return ['2.7'] - else: - # generates list of python versions to use. - # For Python2, this is only [2.7]. - # Otherwise, it is [3.4, 3.3, 3.2, 3.1, 3.0]. - return ['%d.%d' % (major, i) for i in range(minor, -1, -1)] - - sys.path[0:0] = [v for v in [join('lib-typing', v) for v in get_versions()] if isdir(v)] - # Now `typing` is available. - - from typing import Dict, List, Optional, Set, Iterable from mypy.waiter import Waiter, LazySubprocess @@ -33,8 +10,21 @@ def get_versions(): # type: () -> typing.List[str] import itertools import os +from os.path import join, isdir import re -import json +import sys + + +def get_versions(): # type: () -> List[str] + major = sys.version_info[0] + minor = sys.version_info[1] + if major == 2: + return ['2.7'] + else: + # generates list of python versions to use. + # For Python2, this is only [2.7]. + # Otherwise, it is [3.4, 3.3, 3.2, 3.1, 3.0]. + return ['%d.%d' % (major, i) for i in range(minor, -1, -1)] # Ideally, all tests would be `discover`able so that they can be driven @@ -430,7 +420,6 @@ def main() -> None: driver.prepend_path('PATH', [join(driver.cwd, 'scripts')]) driver.prepend_path('MYPYPATH', [driver.cwd]) driver.prepend_path('PYTHONPATH', [driver.cwd]) - driver.prepend_path('PYTHONPATH', [join(driver.cwd, 'lib-typing', v) for v in driver.versions]) driver.add_flake8() add_pytest(driver) diff --git a/setup.cfg b/setup.cfg index 0ec9131aa413..27244e880337 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,8 +13,6 @@ exclude = .cache, # Sphinx configuration is irrelevant docs/source/conf.py, - # external library with incompatible style - lib-typing/*, # conflicting styles misc/*, # external library with incompatible style diff --git a/test-data/unit/README.md b/test-data/unit/README.md index 64737e8ca3b4..baa62784c7b5 100644 --- a/test-data/unit/README.md +++ b/test-data/unit/README.md @@ -78,6 +78,11 @@ First install any additional dependencies needed for testing: $ python3 -m pip install -U -r test-requirements.txt +You must also have a Python 2.7 binary installed that can import the `typing` +module: + + $ python2 -m pip install -U typing + To run all tests, run the script `runtests.py` in the mypy repository: $ ./runtests.py @@ -110,13 +115,14 @@ finer control over which unit tests are run and how, you can run `py.test` or $ ./runtests.py mypy.test.testlex -a -v -a '*backslash*' You can also run the type checker for manual testing without -installing anything by setting up the Python module search path -suitably (the lib-typing/3.2 path entry is not needed for Python 3.5 -or when you have manually installed the `typing` module): +installing it by setting up the Python module search path suitably: - $ export PYTHONPATH=$PWD:$PWD/lib-typing/3.2 + $ export PYTHONPATH=$PWD $ python -m mypy PROGRAM.py +You will have to manually install the `typing` module if you're running Python +3.4 or earlier. + You can add the entry scripts to PATH for a single python3 version: $ export PATH=$PWD/scripts From ba55b1af4fa9f3c20e8dcee3a496f7f33597da93 Mon Sep 17 00:00:00 2001 From: Brian Weber Date: Tue, 23 May 2017 14:28:03 -0700 Subject: [PATCH 23/27] Consistent quote wrapping around MessageBuilder.format as per issue #3409 --- mypy/messages.py | 25 ++++--- test-data/unit/check-async-await.test | 40 +++++----- test-data/unit/check-class-namedtuple.test | 6 +- test-data/unit/check-classes.test | 52 ++++++------- test-data/unit/check-dynamic-typing.test | 2 +- test-data/unit/check-enum.test | 2 +- test-data/unit/check-expressions.test | 36 ++++----- test-data/unit/check-flags.test | 4 +- test-data/unit/check-functions.test | 16 ++-- test-data/unit/check-generic-subtyping.test | 66 ++++++++--------- test-data/unit/check-generics.test | 66 ++++++++--------- test-data/unit/check-ignore.test | 6 +- test-data/unit/check-incremental.test | 6 +- test-data/unit/check-inference-context.test | 46 ++++++------ test-data/unit/check-inference.test | 82 ++++++++++----------- test-data/unit/check-isinstance.test | 16 ++-- test-data/unit/check-kwargs.test | 24 +++--- test-data/unit/check-modules.test | 44 +++++------ test-data/unit/check-namedtuple.test | 6 +- test-data/unit/check-newsyntax.test | 14 ++-- test-data/unit/check-optional.test | 24 +++--- test-data/unit/check-overloading.test | 12 +-- test-data/unit/check-python2.test | 4 +- test-data/unit/check-statements.test | 10 +-- test-data/unit/check-tuples.test | 24 +++--- test-data/unit/check-type-checks.test | 2 +- test-data/unit/check-typeddict.test | 8 +- test-data/unit/check-typevar-values.test | 2 +- test-data/unit/check-unreachable-code.test | 2 +- test-data/unit/check-varargs.test | 44 +++++------ 30 files changed, 347 insertions(+), 344 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index 8dbf1dbeff95..461f1800b4a2 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -184,7 +184,7 @@ def format(self, typ: Type, verbosity: int = 0) -> str: Mostly behave like format_simple below, but never return an empty string. """ s = self.format_simple(typ, verbosity) - if s != '': + if s != '' and s != '""': # If format_simple returns a non-trivial result, use that. return s elif isinstance(typ, FunctionLike): @@ -242,6 +242,9 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: None -> None callable type -> "" (empty string) """ + return '"{}"'.format(self._format_simple(typ, verbosity)) + + def _format_simple(self, typ: Type, verbosity: int = 0) -> str: if isinstance(typ, Instance): itype = typ # Get the short name of the type. @@ -257,7 +260,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: # No type arguments. Place the type name in quotes to avoid # potential for confusion: otherwise, the type name could be # interpreted as a normal word. - return '"{}"'.format(base_str) + return base_str elif itype.type.fullname() == 'builtins.tuple': item_type_str = strip_quotes(self.format(itype.args[0])) return 'Tuple[{}, ...]'.format(item_type_str) @@ -281,15 +284,15 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: return '{}[...]'.format(base_str) elif isinstance(typ, TypeVarType): # This is similar to non-generic instance types. - return '"{}"'.format(typ.name) + return typ.name elif isinstance(typ, TupleType): # Prefer the name of the fallback class (if not tuple), as it's more informative. if typ.fallback.type.fullname() != 'builtins.tuple': - return self.format_simple(typ.fallback) + return self._format_simple(typ.fallback) items = [] for t in typ.items: items.append(strip_quotes(self.format(t))) - s = '"Tuple[{}]"'.format(', '.join(items)) + s = 'Tuple[{}]'.format(', '.join(items)) if len(s) < 400: return s else: @@ -297,11 +300,11 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: elif isinstance(typ, TypedDictType): # If the TypedDictType is named, return the name if typ.fallback.type.fullname() != 'typing.Mapping': - return self.format_simple(typ.fallback) + return self._format_simple(typ.fallback) items = [] for (item_name, item_type) in typ.items.items(): items.append('{}={}'.format(item_name, strip_quotes(self.format(item_type)))) - s = '"TypedDict({})"'.format(', '.join(items)) + s = 'TypedDict({})'.format(', '.join(items)) return s elif isinstance(typ, UnionType): # Only print Unions as Optionals if the Optional wouldn't have to contain another Union @@ -309,12 +312,12 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: sum(isinstance(t, NoneTyp) for t in typ.items) == 1) if print_as_optional: rest = [t for t in typ.items if not isinstance(t, NoneTyp)] - return '"Optional[{}]"'.format(strip_quotes(self.format(rest[0]))) + return 'Optional[{}]'.format(strip_quotes(self.format(rest[0]))) else: items = [] for t in typ.items: items.append(strip_quotes(self.format(t))) - s = '"Union[{}]"'.format(', '.join(items)) + s = 'Union[{}]'.format(', '.join(items)) if len(s) < 400: return s else: @@ -322,7 +325,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: elif isinstance(typ, NoneTyp): return 'None' elif isinstance(typ, AnyType): - return '"Any"' + return 'Any' elif isinstance(typ, DeletedType): return '' elif isinstance(typ, UninhabitedType): @@ -332,7 +335,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: return '' elif isinstance(typ, TypeType): return 'Type[{}]'.format( - strip_quotes(self.format_simple(typ.item, verbosity))) + strip_quotes(self._format_simple(typ.item, verbosity))) elif typ is None: raise RuntimeError('Type is None') else: diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 672bf2b408b8..7d9f7bde2a13 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -84,7 +84,7 @@ async def f() -> int: x = await g() return x [out] -main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type Awaitable[Any]) +main:7: error: Incompatible types in await (actual type "Generator[int, None, str]", expected type "Awaitable[Any]") [case testAwaitIteratorError] @@ -95,7 +95,7 @@ async def f() -> int: x = await g() return x [out] -main:6: error: Incompatible types in await (actual type Iterator[Any], expected type Awaitable[Any]) +main:6: error: Incompatible types in await (actual type "Iterator[Any]", expected type "Awaitable[Any]") [case testAwaitArgumentError] @@ -106,7 +106,7 @@ async def f() -> int: return x [builtins fixtures/async_await.pyi] [out] -main:5: error: Incompatible types in await (actual type "int", expected type Awaitable[Any]) +main:5: error: Incompatible types in await (actual type "int", expected type "Awaitable[Any]") [case testAwaitResultError] @@ -150,7 +150,7 @@ async def f() -> None: [builtins fixtures/async_await.pyi] [out] main:4: error: AsyncIterable expected -main:4: error: List[int] has no attribute "__aiter__" +main:4: error: "List[int]" has no attribute "__aiter__" [case testAsyncForTypeComments] @@ -232,13 +232,13 @@ async def wrong_iterable(obj: Iterable[int]): [out] main:18: error: AsyncIterable expected -main:18: error: Iterable[int] has no attribute "__aiter__"; maybe "__iter__"? +main:18: error: "Iterable[int]" has no attribute "__aiter__"; maybe "__iter__"? main:19: error: Iterable expected -main:19: error: asyncify[int] has no attribute "__iter__"; maybe "__aiter__"? +main:19: error: "asyncify[int]" has no attribute "__iter__"; maybe "__aiter__"? main:20: error: AsyncIterable expected -main:20: error: Iterable[int] has no attribute "__aiter__"; maybe "__iter__"? +main:20: error: "Iterable[int]" has no attribute "__aiter__"; maybe "__iter__"? main:21: error: Iterable expected -main:21: error: asyncify[int] has no attribute "__iter__"; maybe "__aiter__"? +main:21: error: "asyncify[int]" has no attribute "__iter__"; maybe "__aiter__"? [builtins fixtures/async_await.pyi] [case testAsyncWith] @@ -271,7 +271,7 @@ class C: def __aenter__(self) -> int: pass async def __aexit__(self, x, y, z) -> None: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type Awaitable[Any]) + async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type "Awaitable[Any]") pass [builtins fixtures/async_await.pyi] [out] @@ -282,7 +282,7 @@ class C: def __aenter__(self) -> None: pass async def __aexit__(self, x, y, z) -> None: pass async def f() -> None: - async with C() as x: # E: None has no attribute "__await__" + async with C() as x: # E: "None" has no attribute "__await__" pass [builtins fixtures/async_await.pyi] [out] @@ -293,7 +293,7 @@ class C: async def __aenter__(self) -> int: pass def __aexit__(self, x, y, z) -> int: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type Awaitable[Any]) + async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type "Awaitable[Any]") pass [builtins fixtures/async_await.pyi] [out] @@ -304,7 +304,7 @@ class C: async def __aenter__(self) -> int: pass def __aexit__(self, x, y, z) -> None: pass async def f() -> None: - async with C() as x: # E: None has no attribute "__await__" + async with C() as x: # E: "None" has no attribute "__await__" pass [builtins fixtures/async_await.pyi] [out] @@ -362,7 +362,7 @@ def g() -> Generator[Any, None, str]: return x [builtins fixtures/async_await.pyi] [out] -main:6: error: "yield from" can't be applied to Awaitable[str] +main:6: error: "yield from" can't be applied to "Awaitable[str]" [case testAwaitableSubclass] @@ -523,7 +523,7 @@ def h() -> None: [out] main:9: error: Iterable expected -main:9: error: AsyncGenerator[int, None] has no attribute "__iter__"; maybe "__aiter__"? +main:9: error: "AsyncGenerator[int, None]" has no attribute "__iter__"; maybe "__aiter__"? [case testAsyncGeneratorNoYieldFrom] # flags: --fast-parser --python-version 3.6 @@ -607,19 +607,19 @@ def plain_host_generator() -> Generator[str, None, None]: yield 'a' x = 0 x = yield from plain_generator() - x = yield from plain_coroutine() # E: "yield from" can't be applied to Awaitable[int] + x = yield from plain_coroutine() # E: "yield from" can't be applied to "Awaitable[int]" x = yield from decorated_generator() - x = yield from decorated_coroutine() # E: "yield from" can't be applied to AwaitableGenerator[Any, Any, int, Awaitable[int]] + x = yield from decorated_coroutine() # E: "yield from" can't be applied to "AwaitableGenerator[Any, Any, int, Awaitable[int]]" x = yield from other_iterator() x = yield from other_coroutine() # E: "yield from" can't be applied to "Aw" async def plain_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) + x = await plain_generator() # E: Incompatible types in await (actual type "Generator[str, None, int]", expected type "Awaitable[Any]") x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable[Any]") x = await other_coroutine() @coroutine @@ -636,11 +636,11 @@ def decorated_host_generator() -> Generator[str, None, None]: @coroutine async def decorated_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) + x = await plain_generator() # E: Incompatible types in await (actual type "Generator[str, None, int]", expected type "Awaitable[Any]") x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable[Any]") x = await other_coroutine() [builtins fixtures/async_await.pyi] diff --git a/test-data/unit/check-class-namedtuple.test b/test-data/unit/check-class-namedtuple.test index 7a81adb0a672..7ae6c1f936bf 100644 --- a/test-data/unit/check-class-namedtuple.test +++ b/test-data/unit/check-class-namedtuple.test @@ -221,7 +221,7 @@ class MyNamedTuple(NamedTuple): a: int b: str -MyNamedTuple.x # E: Type[MyNamedTuple] has no attribute "x" +MyNamedTuple.x # E: "Type[MyNamedTuple]" has no attribute "x" [case testNewNamedTupleEmptyItems] # flags: --python-version 3.6 @@ -439,13 +439,13 @@ class HasNone(NamedTuple): y: Optional[int] = None reveal_type(HasNone(1)) # E: Revealed type is 'Tuple[builtins.int, Union[builtins.int, builtins.None], fallback=__main__.HasNone]' -HasNone(None) # E: Argument 1 to "HasNone" has incompatible type None; expected "int" +HasNone(None) # E: Argument 1 to "HasNone" has incompatible type "None"; expected "int" HasNone(1, y=None) HasNone(1, y=2) class CannotBeNone(NamedTuple): x: int - y: int = None # E: Incompatible types in assignment (expression has type None, variable has type "int") + y: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [builtins fixtures/list.pyi] diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index 0b6bb6873d62..14034770803d 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -514,7 +514,7 @@ b = A.x # type: B # E: Incompatible types in assignment (expression has type "A" [case testAccessingUndefinedAttributeViaClass] import typing class A: pass -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAccessingUndefinedAttributeViaClassWithOverloadedInit] from foo import * @@ -525,7 +525,7 @@ class A: def __init__(self): pass @overload def __init__(self, x): pass -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAccessMethodOfClassWithOverloadedInit] from foo import * @@ -812,7 +812,7 @@ class C: cls(1) # E: Too many arguments for "C" cls.bar() cls.bar(1) # E: Too many arguments for "bar" of "C" - cls.bozo() # E: Type[C] has no attribute "bozo" + cls.bozo() # E: "Type[C]" has no attribute "bozo" [builtins fixtures/classmethod.pyi] [out] @@ -823,7 +823,7 @@ class C: def foo(cls) -> None: pass C.foo() C.foo(1) # E: Too many arguments for "foo" of "C" -C.bozo() # E: Type[C] has no attribute "bozo" +C.bozo() # E: "Type[C]" has no attribute "bozo" [builtins fixtures/classmethod.pyi] [case testClassMethodCalledOnInstance] @@ -833,7 +833,7 @@ class C: def foo(cls) -> None: pass C().foo() C().foo(1) # E: Too many arguments for "foo" of "C" -C.bozo() # E: Type[C] has no attribute "bozo" +C.bozo() # E: "Type[C]" has no attribute "bozo" [builtins fixtures/classmethod.pyi] [case testClassMethodMayCallAbstractMethod] @@ -1278,7 +1278,7 @@ class D: def __get__(self, inst: Any, own: str) -> Any: pass class A: f = D() -A().f # E: Argument 2 to "__get__" of "D" has incompatible type Type[A]; expected "str" +A().f # E: Argument 2 to "__get__" of "D" has incompatible type "Type[A]"; expected "str" [case testDescriptorGetSetDifferentTypes] from typing import Any @@ -1722,7 +1722,7 @@ class C: def f(x: type) -> None: pass def g(x: int) -> None: pass f(C) -g(C) # E: Argument 1 to "g" has incompatible type Type[C]; expected "int" +g(C) # E: Argument 1 to "g" has incompatible type "Type[C]"; expected "int" [builtins fixtures/__new__.pyi] [case testClassWith__new__AndCompatibilityWithType2] @@ -1733,7 +1733,7 @@ class C: def f(x: type) -> None: pass def g(x: int) -> None: pass f(C) -g(C) # E: Argument 1 to "g" has incompatible type Type[C]; expected "int" +g(C) # E: Argument 1 to "g" has incompatible type "Type[C]"; expected "int" [builtins fixtures/__new__.pyi] [case testGenericClassWith__new__] @@ -1813,7 +1813,7 @@ class B: [case testClassVsInstanceDisambiguation] class A: pass def f(x: A) -> None: pass -f(A) # E: Argument 1 to "f" has incompatible type Type[A]; expected "A" +f(A) # E: Argument 1 to "f" has incompatible type "Type[A]"; expected "A" [out] -- TODO @@ -2020,7 +2020,7 @@ class User: pass def new_user(user_class: Type[User]): return user_class() def foo(arg: Type[int]): - new_user(arg) # E: Argument 1 to "new_user" has incompatible type Type[int]; expected Type[User] + new_user(arg) # E: Argument 1 to "new_user" has incompatible type "Type[int]"; expected "Type[User]" [out] [case testTypeUsingTypeCUnionOverload] @@ -2059,7 +2059,7 @@ def foo(arg: Type[Any]): # Member access is ok and types as Any reveal_type(x) # E: Revealed type is 'Any' # But Type[Any] is distinct from Any - y: int = arg # E: Incompatible types in assignment (expression has type Type[Any], variable has type "int") + y: int = arg # E: Incompatible types in assignment (expression has type "Type[Any]", variable has type "int") [out] [case testTypeUsingTypeCTypeAnyMemberFallback] @@ -2100,7 +2100,7 @@ def process(cls: Type[User]): obj = cls() reveal_type(cls.bar(obj)) # E: Revealed type is 'builtins.int' cls.mro() # Defined in class type - cls.error # E: Type[User] has no attribute "error" + cls.error # E: "Type[User]" has no attribute "error" [builtins fixtures/classmethod.pyi] [out] @@ -2114,11 +2114,11 @@ class User: class ProUser(User): pass class BasicUser(User): pass def process(cls: Type[Union[BasicUser, ProUser]]): - cls.foo() # E: Type[Union[BasicUser, ProUser]] has no attribute "foo" + cls.foo() # E: "Type[Union[BasicUser, ProUser]]" has no attribute "foo" obj = cls() - cls.bar(obj) # E: Type[Union[BasicUser, ProUser]] has no attribute "bar" + cls.bar(obj) # E: "Type[Union[BasicUser, ProUser]]" has no attribute "bar" cls.mro() # Defined in class type - cls.error # E: Type[Union[BasicUser, ProUser]] has no attribute "error" + cls.error # E: "Type[Union[BasicUser, ProUser]]" has no attribute "error" [builtins fixtures/classmethod.pyi] [out] @@ -2134,7 +2134,7 @@ def process(cls: Type[U]): obj = cls() reveal_type(cls.bar(obj)) # E: Revealed type is 'builtins.int' cls.mro() # Defined in class type - cls.error # E: Type[U] has no attribute "error" + cls.error # E: "Type[U]" has no attribute "error" [builtins fixtures/classmethod.pyi] [out] @@ -2149,11 +2149,11 @@ class ProUser(User): pass class BasicUser(User): pass U = TypeVar('U', bound=Union[ProUser, BasicUser]) def process(cls: Type[U]): - cls.foo() # E: Type[U] has no attribute "foo" + cls.foo() # E: "Type[U]" has no attribute "foo" obj = cls() - cls.bar(obj) # E: Type[U] has no attribute "bar" + cls.bar(obj) # E: "Type[U]" has no attribute "bar" cls.mro() # Defined in class type - cls.error # E: Type[U] has no attribute "error" + cls.error # E: "Type[U]" has no attribute "error" [builtins fixtures/classmethod.pyi] [out] @@ -2621,7 +2621,7 @@ int.__eq__(3, 4) [builtins fixtures/args.pyi] [out] main:33: error: Too few arguments for "__eq__" of "int" -main:33: error: Unsupported operand types for == ("int" and Type[int]) +main:33: error: Unsupported operand types for == ("int" and "Type[int]") [case testMroSetAfterError] class C(str, str): @@ -2986,7 +2986,7 @@ class M: class A(metaclass=M): pass # E: Metaclasses not inheriting from 'type' are not supported -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testMetaclassTypeReveal] from typing import Type @@ -3057,7 +3057,7 @@ class Concrete(metaclass=Meta): pass reveal_type(Concrete + X()) # E: Revealed type is 'builtins.str' -Concrete + "hello" # E: Unsupported operand types for + (Type[Concrete] and "str") +Concrete + "hello" # E: Unsupported operand types for + ("Type[Concrete]" and "str") [case testMetaclassGetitem] class M(type): @@ -3085,7 +3085,7 @@ from missing import M class A(metaclass=M): y = 0 reveal_type(A.y) # E: Revealed type is 'builtins.int' -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAnyMetaclass] from typing import Any @@ -3093,7 +3093,7 @@ M = None # type: Any class A(metaclass=M): y = 0 reveal_type(A.y) # E: Revealed type is 'builtins.int' -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testInvalidVariableAsMetaclass] from typing import Any @@ -3104,7 +3104,7 @@ class A(metaclass=M): # E: Invalid metaclass 'M' class B(metaclass=MM): # E: Invalid metaclass 'MM' y = 0 reveal_type(A.y) # E: Revealed type is 'builtins.int' -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAnyAsBaseOfMetaclass] from typing import Any, Type @@ -3119,7 +3119,7 @@ class A(metaclass=MM): def h(a: Type[A], b: Type[object]) -> None: h(a, a) - h(b, a) # E: Argument 1 to "h" has incompatible type Type[object]; expected Type[A] + h(b, a) # E: Argument 1 to "h" has incompatible type "Type[object]"; expected "Type[A]" a.f(1) # E: Too many arguments for "f" of "A" reveal_type(a.y) # E: Revealed type is 'builtins.int' diff --git a/test-data/unit/check-dynamic-typing.test b/test-data/unit/check-dynamic-typing.test index 68a174e3cc81..22626cfffd88 100644 --- a/test-data/unit/check-dynamic-typing.test +++ b/test-data/unit/check-dynamic-typing.test @@ -485,7 +485,7 @@ class A: def __init__(self, a, b): pass [out] main:6: error: Too few arguments for "A" -main:7: error: Incompatible types in assignment (expression has type Type[A], variable has type Callable[[A], A]) +main:7: error: Incompatible types in assignment (expression has type "Type[A]", variable has type Callable[[A], A]) [case testUsingImplicitTypeObjectWithIs] diff --git a/test-data/unit/check-enum.test b/test-data/unit/check-enum.test index 011580effb35..d6e7a65abfc4 100644 --- a/test-data/unit/check-enum.test +++ b/test-data/unit/check-enum.test @@ -325,7 +325,7 @@ main:17: error: Enum() with dict literal requires string literals main:18: error: Unexpected arguments to Enum() main:19: error: Unexpected arguments to Enum() main:20: error: Unexpected arguments to Enum() -main:22: error: Type[W] has no attribute "c" +main:22: error: "Type[W]" has no attribute "c" [case testFunctionalEnumFlag] from enum import Flag, IntFlag diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index ae1498acdadd..6f27f4f29699 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -1135,7 +1135,7 @@ b'%a' % 3 from typing import Any, Dict a = None # type: Any ds, do, di = None, None, None # type: Dict[str, int], Dict[object, int], Dict[int, int] -'%(a)' % 1 # E: Format requires a mapping (expression has type "int", expected type for mapping is Dict[Any, Any]) +'%(a)' % 1 # E: Format requires a mapping (expression has type "int", expected type for mapping is "Dict[Any, Any]") '%()d' % a '%()d' % ds '%()d' % do @@ -1308,7 +1308,7 @@ class B: pass [out] main:5: error: Key expression in dictionary comprehension has incompatible type "A"; expected type "B" main:5: error: Value expression in dictionary comprehension has incompatible type "B"; expected type "A" -main:6: error: Incompatible types in assignment (expression has type Dict[A, B], variable has type "A") +main:6: error: Incompatible types in assignment (expression has type "Dict[A, B]", variable has type "A") [case testDictionaryComprehensionWithNonDirectMapping] @@ -1394,7 +1394,7 @@ cast(A, f) def f() -> None: pass [out] -main:5: error: Unsupported left operand type for + (None) +main:5: error: Unsupported left operand type for + ("None") main:6: error: Unsupported left operand type for + (Callable[[], None]) main:7: error: Unsupported operand types for + ("A" and Callable[[], None]) @@ -1532,7 +1532,7 @@ d1 = dict(a=1, b=2) # type: Dict[str, int] d2 = dict(a=1, b='') # type: Dict[str, int] # E: Dict entry 1 has incompatible type "str": "str" d3 = dict(a=1) # type: Dict[int, int] # E: Dict entry 0 has incompatible type "str": "int" d4 = dict(a=1, b=1) -d4.xyz # E: Dict[str, int] has no attribute "xyz" +d4.xyz # E: "Dict[str, int]" has no attribute "xyz" d5 = dict(a=1, b='') # type: Dict[str, Any] [builtins fixtures/dict.pyi] @@ -1546,7 +1546,7 @@ dict(undefined) # E: Name 'undefined' is not defined [case testDictFromList] from typing import Dict d = dict([(1, 'x'), (2, 'y')]) -d() # E: Dict[int, str] not callable +d() # E: "Dict[int, str]" not callable d2 = dict([(1, 'x')]) # type: Dict[str, str] # E: List item 0 has incompatible type "Tuple[int, str]" [builtins fixtures/dict.pyi] @@ -1555,10 +1555,10 @@ from typing import Dict it = [('x', 1)] d = dict(it, x=1) -d() # E: Dict[str, int] not callable +d() # E: "Dict[str, int]" not callable d2 = dict(it, x='') # E: Cannot infer type argument 2 of "dict" -d2() # E: Dict[Any, Any] not callable +d2() # E: "Dict[Any, Any]" not callable d3 = dict(it, x='') # type: Dict[str, int] # E: Argument 2 to "dict" has incompatible type "str"; expected "int" [builtins fixtures/dict.pyi] @@ -1570,7 +1570,7 @@ dict(it, x='y') # E: Keyword argument only valid with "str" key type in call to [case testDictFromIterableAndKeywordArg3] d = dict([], x=1) -d() # E: Dict[str, int] not callable +d() # E: "Dict[str, int]" not callable [builtins fixtures/dict.pyi] [case testDictFromIterableAndStarStarArgs] @@ -1579,20 +1579,20 @@ it = [('x', 1)] kw = {'x': 1} d = dict(it, **kw) -d() # E: Dict[str, int] not callable +d() # E: "Dict[str, int]" not callable kw2 = {'x': ''} d2 = dict(it, **kw2) # E: Cannot infer type argument 2 of "dict" -d2() # E: Dict[Any, Any] not callable +d2() # E: "Dict[Any, Any]" not callable -d3 = dict(it, **kw2) # type: Dict[str, int] # E: Argument 2 to "dict" has incompatible type **Dict[str, str]; expected "int" +d3 = dict(it, **kw2) # type: Dict[str, int] # E: Argument 2 to "dict" has incompatible type **"Dict[str, str]"; expected "int" [builtins fixtures/dict.pyi] [case testDictFromIterableAndStarStarArgs2] it = [(1, 'x')] kw = {'x': 'y'} d = dict(it, **kw) # E: Keyword argument only valid with "str" key type in call to "dict" -d() # E: Dict[int, str] not callable +d() # E: "Dict[int, str]" not callable [builtins fixtures/dict.pyi] [case testUserDefinedClassNamedDict] @@ -1612,10 +1612,10 @@ class D1(dict): pass # Implicit base class Dict[Any, Any] D1([(1, 2)], x=1) class D2(Dict[T, S], Generic[T, S]): pass da = D2([('x', 2)], x=1) -da() # E: D2[str, int] not callable +da() # E: "D2[str, int]" not callable D2([(1, 2)], x=1) # E: Keyword argument only valid with "str" key type in call to "dict" db = D2(x=1) -db() # E: D2[str, int] not callable +db() # E: "D2[str, int]" not callable [builtins fixtures/dict.pyi] [case testSpecialSignatureForSubclassOfDict2] @@ -1632,7 +1632,7 @@ S = TypeVar('S') class D(Dict[T, S], Generic[T, S]): def __init__(self, x: S, y: T) -> None: pass d = D(1, y='') -d() # E: D[str, int] not callable +d() # E: "D[str, int]" not callable [builtins fixtures/dict.pyi] [case testRevealType] @@ -1664,7 +1664,7 @@ None == None [builtins fixtures/ops.pyi] [case testLtNone] -None < None # E: Unsupported left operand type for < (None) +None < None # E: Unsupported left operand type for < ("None") [builtins fixtures/ops.pyi] [case testDictWithStarExpr] @@ -1679,6 +1679,6 @@ a = {'a': 1} b = {'z': 26, **a} c = {**b} d = {**a, **b, 'c': 3} -e = {1: 'a', **a} # E: Argument 1 to "update" of "dict" has incompatible type Dict[str, int]; expected Mapping[int, str] -f = {**b} # type: Dict[int, int] # E: List item 0 has incompatible type Dict[str, int] +e = {1: 'a', **a} # E: Argument 1 to "update" of "dict" has incompatible type "Dict[str, int]"; expected "Mapping[int, str]" +f = {**b} # type: Dict[int, int] # E: List item 0 has incompatible type "Dict[str, int]" [builtins fixtures/dict.pyi] diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test index 2b0e5549589a..b270ec8b854c 100644 --- a/test-data/unit/check-flags.test +++ b/test-data/unit/check-flags.test @@ -190,7 +190,7 @@ reveal_type(f() or no_return()) # E: Revealed type is 'builtins.int' # flags: --warn-no-return from mypy_extensions import NoReturn -x = 0 # type: NoReturn # E: Incompatible types in assignment (expression has type "int", variable has type NoReturn) +x = 0 # type: NoReturn # E: Incompatible types in assignment (expression has type "int", variable has type "NoReturn") [builtins fixtures/dict.pyi] [case testNoReturnImportFromTyping] @@ -206,7 +206,7 @@ def no_return() -> NoReturn: pass def f() -> NoReturn: no_return() -x: NoReturn = 0 # E: Incompatible types in assignment (expression has type "int", variable has type NoReturn) +x: NoReturn = 0 # E: Incompatible types in assignment (expression has type "int", variable has type "NoReturn") [builtins fixtures/dict.pyi] [case testShowErrorContextFunction] diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 343b4b79cf9f..3bd2de532384 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -254,7 +254,7 @@ class A: pass t = None # type: type a = None # type: A -a = A # E: Incompatible types in assignment (expression has type Type[A], variable has type "A") +a = A # E: Incompatible types in assignment (expression has type "Type[A]", variable has type "A") t = f # E: Incompatible types in assignment (expression has type Callable[[], None], variable has type "type") t = A @@ -334,10 +334,10 @@ def f(x: C) -> C: pass from typing import Any, Callable, List def f(fields: List[Callable[[Any], Any]]): pass class C: pass -f([C]) # E: List item 0 has incompatible type +f([C]) # E: List item 0 has incompatible type "" class D: def __init__(self, a, b): pass -f([D]) # E: List item 0 has incompatible type +f([D]) # E: List item 0 has incompatible type "" [builtins fixtures/list.pyi] [case testSubtypingTypeTypeAsCallable] @@ -352,7 +352,7 @@ from typing import Callable, Type class A: pass x = None # type: Callable[..., A] y = None # type: Type[A] -y = x # E: Incompatible types in assignment (expression has type Callable[..., A], variable has type Type[A]) +y = x # E: Incompatible types in assignment (expression has type Callable[..., A], variable has type "Type[A]") -- Default argument values -- ----------------------- @@ -517,7 +517,7 @@ class A(Generic[t]): g = f a = None # type: A[B] a.g(B()) -a.g(a) # E: Argument 1 has incompatible type A[B]; expected "B" +a.g(a) # E: Argument 1 has incompatible type "A[B]"; expected "B" [case testInvalidMethodAsDataAttributeInGenericClass] from typing import Any, TypeVar, Generic, Callable @@ -1479,7 +1479,7 @@ L = Callable[[Arg(name='x', type=int)], int] # ok # I have commented out the following test because I don't know how to expect the "defined here" note part of the error. # M = Callable[[Arg(gnome='x', type=int)], int] E: Invalid type alias E: Unexpected keyword argument "gnome" for "Arg" N = Callable[[Arg(name=None, type=int)], int] # ok -O = Callable[[List[Arg(int)]], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: Type expected within [...] # E: The type Type[List[Any]] is not generic and not indexable +O = Callable[[List[Arg(int)]], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: Type expected within [...] # E: The type "Type[List[Any]]" is not generic and not indexable P = Callable[[mypy_extensions.VarArg(int)], int] # ok Q = Callable[[Arg(int, type=int)], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "type" R = Callable[[Arg(int, 'x', name='y')], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "name" @@ -1735,7 +1735,7 @@ f(x=1, y="hello", z=[]) from typing import Dict def f(x, **kwargs): # type: (...) -> None success_dict_type = kwargs # type: Dict[str, str] - failure_dict_type = kwargs # type: Dict[int, str] # E: Incompatible types in assignment (expression has type Dict[str, Any], variable has type Dict[int, str]) + failure_dict_type = kwargs # type: Dict[int, str] # E: Incompatible types in assignment (expression has type "Dict[str, Any]", variable has type "Dict[int, str]") f(1, thing_in_kwargs=["hey"]) [builtins fixtures/dict.pyi] [out] @@ -1744,7 +1744,7 @@ f(1, thing_in_kwargs=["hey"]) from typing import Tuple, Any def f(x, *args): # type: (...) -> None success_tuple_type = args # type: Tuple[Any, ...] - fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type Tuple[Any, ...], variable has type None) + fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type "Tuple[Any, ...]", variable has type "None") f(1, "hello") [builtins fixtures/tuple.pyi] [out] diff --git a/test-data/unit/check-generic-subtyping.test b/test-data/unit/check-generic-subtyping.test index 6cae196bbe80..9c5d242368a8 100644 --- a/test-data/unit/check-generic-subtyping.test +++ b/test-data/unit/check-generic-subtyping.test @@ -13,9 +13,9 @@ ac = None # type: A[C] ad = None # type: A[D] b = None # type: B -b = ad # E: Incompatible types in assignment (expression has type A[D], variable has type "B") -ad = b # E: Incompatible types in assignment (expression has type "B", variable has type A[D]) -b = ac # E: Incompatible types in assignment (expression has type A[C], variable has type "B") +b = ad # E: Incompatible types in assignment (expression has type "A[D]", variable has type "B") +ad = b # E: Incompatible types in assignment (expression has type "B", variable has type "A[D]") +b = ac # E: Incompatible types in assignment (expression has type "A[C]", variable has type "B") b = b ac = b @@ -32,10 +32,10 @@ a = None # type: A bc = None # type: B[C] bd = None # type: B[D] -bc = bd # E: Incompatible types in assignment (expression has type B[D], variable has type B[C]) -bd = bc # E: Incompatible types in assignment (expression has type B[C], variable has type B[D]) -bc = a # E: Incompatible types in assignment (expression has type "A", variable has type B[C]) -bd = a # E: Incompatible types in assignment (expression has type "A", variable has type B[D]) +bc = bd # E: Incompatible types in assignment (expression has type "B[D]", variable has type "B[C]") +bd = bc # E: Incompatible types in assignment (expression has type "B[C]", variable has type "B[D]") +bc = a # E: Incompatible types in assignment (expression has type "A", variable has type "B[C]") +bd = a # E: Incompatible types in assignment (expression has type "A", variable has type "B[D]") a = bc a = bd @@ -54,10 +54,10 @@ ad = None # type: A[D] bcc = None # type: B[C, C] bdc = None # type: B[D, C] -ad = bcc # E: Incompatible types in assignment (expression has type B[C, C], variable has type A[D]) -ad = bdc # E: Incompatible types in assignment (expression has type B[D, C], variable has type A[D]) -bcc = ac # E: Incompatible types in assignment (expression has type A[C], variable has type B[C, C]) -bdc = ac # E: Incompatible types in assignment (expression has type A[C], variable has type B[D, C]) +ad = bcc # E: Incompatible types in assignment (expression has type "B[C, C]", variable has type "A[D]") +ad = bdc # E: Incompatible types in assignment (expression has type "B[D, C]", variable has type "A[D]") +bcc = ac # E: Incompatible types in assignment (expression has type "A[C]", variable has type "B[C, C]") +bdc = ac # E: Incompatible types in assignment (expression has type "A[C]", variable has type "B[D, C]") bcc = bcc bdc = bdc @@ -82,8 +82,8 @@ cef = None # type: C[E, F] cff = None # type: C[F, F] cfe = None # type: C[F, E] -ae = cef # E: Incompatible types in assignment (expression has type C[E, F], variable has type A[A[E]]) -af = cfe # E: Incompatible types in assignment (expression has type C[F, E], variable has type A[A[F]]) +ae = cef # E: Incompatible types in assignment (expression has type "C[E, F]", variable has type "A[A[E]]") +af = cfe # E: Incompatible types in assignment (expression has type "C[F, E]", variable has type "A[A[F]]") ae = cfe af = cef @@ -280,7 +280,7 @@ a = None # type: A bc = None # type: B[C] bd = None # type: B[D] -a = bc # E: Incompatible types in assignment (expression has type B[C], variable has type "A") +a = bc # E: Incompatible types in assignment (expression has type "B[C]", variable has type "A") bc = a bd = a @@ -305,8 +305,8 @@ a = None # type: A c = None # type: C bc = None # type: B[C] -a.x = c # E: Incompatible types in assignment (expression has type "C", variable has type B[Any]) -a.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected B[Any] +a.x = c # E: Incompatible types in assignment (expression has type "C", variable has type "B[Any]") +a.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected "B[Any]" a.x = bc a.f(bc) [out] @@ -325,8 +325,8 @@ class B(Generic[T]): class A(B): def g(self) -> None: - self.x = c # E: Incompatible types in assignment (expression has type "C", variable has type B[Any]) - self.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected B[Any] + self.x = c # E: Incompatible types in assignment (expression has type "C", variable has type "B[Any]") + self.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected "B[Any]" self.x = bc self.f(bc) @@ -394,7 +394,7 @@ B(1) C(1) C('a') # E: Argument 1 to "C" has incompatible type "str"; expected "int" D(A(1)) -D(1) # E: Argument 1 to "D" has incompatible type "int"; expected A[] +D(1) # E: Argument 1 to "D" has incompatible type "int"; expected "A[]" [case testInheritedConstructor2] @@ -427,9 +427,9 @@ adc = None # type: A[D, C] ic = None # type: I[C] id = None # type: I[D] -ic = acd # E: Incompatible types in assignment (expression has type A[C, D], variable has type I[C]) -id = adc # E: Incompatible types in assignment (expression has type A[D, C], variable has type I[D]) -adc = ic # E: Incompatible types in assignment (expression has type I[C], variable has type A[D, C]) +ic = acd # E: Incompatible types in assignment (expression has type "A[C, D]", variable has type "I[C]") +id = adc # E: Incompatible types in assignment (expression has type "A[D, C]", variable has type "I[D]") +adc = ic # E: Incompatible types in assignment (expression has type "I[C]", variable has type "A[D, C]") ic = adc id = acd @@ -451,11 +451,11 @@ class I(Generic[S]): pass class B(I[C]): pass class A(B): pass -ie = a # E: Incompatible types in assignment (expression has type "A", variable has type I[E]) -a = ic # E: Incompatible types in assignment (expression has type I[C], variable has type "A") -a = id # E: Incompatible types in assignment (expression has type I[D], variable has type "A") +ie = a # E: Incompatible types in assignment (expression has type "A", variable has type "I[E]") +a = ic # E: Incompatible types in assignment (expression has type "I[C]", variable has type "A") +a = id # E: Incompatible types in assignment (expression has type "I[D]", variable has type "A") a = b # E: Incompatible types in assignment (expression has type "B", variable has type "A") -id = a # E: Incompatible types in assignment (expression has type "A", variable has type I[D]) +id = a # E: Incompatible types in assignment (expression has type "A", variable has type "I[D]") ic = a b = a @@ -486,8 +486,8 @@ a, i, j = None, None, None # type: (A[object], I[object], J[object]) ii = a jj = a jj = i -a = i # E: Incompatible types in assignment (expression has type I[object], variable has type A[object]) -a = j # E: Incompatible types in assignment (expression has type J[object], variable has type A[object]) +a = i # E: Incompatible types in assignment (expression has type "I[object]", variable has type "A[object]") +a = j # E: Incompatible types in assignment (expression has type "J[object]", variable has type "A[object]") class J(Generic[t]): pass class X(metaclass=ABCMeta): pass @@ -546,7 +546,7 @@ class A(B): class C: pass class D: pass [out] -main:7: error: Incompatible types in assignment (expression has type "A", variable has type I[D]) +main:7: error: Incompatible types in assignment (expression has type "A", variable has type "I[D]") [case testSubclassingGenericABCWithDeepHierarchy2] from typing import Any, TypeVar, Generic @@ -704,7 +704,7 @@ a = None # type: G[A] b = None # type: G[B] c = None # type: G[C] -b = a # E: Incompatible types in assignment (expression has type G[A], variable has type G[B]) +b = a # E: Incompatible types in assignment (expression has type "G[A]", variable has type "G[B]") b = c [builtins fixtures/bool.pyi] [out] @@ -723,7 +723,7 @@ b = None # type: G[B] c = None # type: G[C] b = a -b = c # E: Incompatible types in assignment (expression has type G[C], variable has type G[B]) +b = c # E: Incompatible types in assignment (expression has type "G[C]", variable has type "G[B]") [builtins fixtures/bool.pyi] [out] @@ -740,8 +740,8 @@ a = None # type: G[A] b = None # type: G[B] c = None # type: G[C] -b = a # E: Incompatible types in assignment (expression has type G[A], variable has type G[B]) -b = c # E: Incompatible types in assignment (expression has type G[C], variable has type G[B]) +b = a # E: Incompatible types in assignment (expression has type "G[A]", variable has type "G[B]") +b = c # E: Incompatible types in assignment (expression has type "G[C]", variable has type "G[B]") [builtins fixtures/bool.pyi] [out] diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index 33106feca98d..f4a94281f8cd 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -79,8 +79,8 @@ class A(Generic[T]): pass class B: pass class C(B): pass [out] -main:4: error: Incompatible types in assignment (expression has type A[B], variable has type A[C]) -main:5: error: Incompatible types in assignment (expression has type A[C], variable has type A[B]) +main:4: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]") +main:5: error: Incompatible types in assignment (expression has type "A[C]", variable has type "A[B]") [case testGenericTypeCompatibilityWithAny] from typing import Any, TypeVar, Generic @@ -115,8 +115,8 @@ class A(Generic[T]): class B: pass class C: pass [out] -main:7: error: Incompatible types in assignment (expression has type A[C], variable has type A[B]) -main:8: error: Incompatible types in assignment (expression has type A[B], variable has type A[C]) +main:7: error: Incompatible types in assignment (expression has type "A[C]", variable has type "A[B]") +main:8: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]") [case testMultipleGenericTypeParametersWithMemberVars] from typing import TypeVar, Generic @@ -183,9 +183,9 @@ class A(Generic[S, T]): class B: pass class C(B):pass [out] -main:8: error: Incompatible types in assignment (expression has type A[B, C], variable has type A[B, B]) -main:9: error: Incompatible types in assignment (expression has type A[C, B], variable has type A[B, B]) -main:10: error: Incompatible types in assignment (expression has type A[B, B], variable has type A[B, C]) +main:8: error: Incompatible types in assignment (expression has type "A[B, C]", variable has type "A[B, B]") +main:9: error: Incompatible types in assignment (expression has type "A[C, B]", variable has type "A[B, B]") +main:10: error: Incompatible types in assignment (expression has type "A[B, B]", variable has type "A[B, C]") -- Simple generic type bodies @@ -208,7 +208,7 @@ x = None # type: B class B: pass [out] main:7: error: Argument 1 to "f" of "A" has incompatible type "B"; expected "T" -main:8: error: Incompatible types in assignment (expression has type A[T], variable has type A[B]) +main:8: error: Incompatible types in assignment (expression has type "A[T]", variable has type "A[B]") [case testGenericTypeBodyWithMultipleVariables] from typing import TypeVar, Generic @@ -229,8 +229,8 @@ class B: pass [out] main:8: error: Incompatible types in assignment (expression has type "T", variable has type "S") main:9: error: Incompatible types in assignment (expression has type "S", variable has type "T") -main:10: error: Incompatible types in assignment (expression has type A[S, T], variable has type A[S, B]) -main:11: error: Incompatible types in assignment (expression has type A[S, T], variable has type A[T, T]) +main:10: error: Incompatible types in assignment (expression has type "A[S, T]", variable has type "A[S, B]") +main:11: error: Incompatible types in assignment (expression has type "A[S, T]", variable has type "A[T, T]") [case testCompatibilityOfNoneWithTypeVar] from typing import TypeVar, Generic @@ -284,9 +284,9 @@ class B: pass class C: pass [out] main:8: error: Incompatible types in assignment (expression has type "C", variable has type "B") -main:9: error: Unsupported operand types for + (A[B, C] and "C") +main:9: error: Unsupported operand types for + ("A[B, C]" and "C") main:10: error: Incompatible types in assignment (expression has type "B", variable has type "C") -main:11: error: Invalid index type "B" for A[B, C]; expected type "C" +main:11: error: Invalid index type "B" for "A[B, C]"; expected type "C" [case testOperatorAssignmentWithIndexLvalue1] from typing import TypeVar, Generic @@ -309,7 +309,7 @@ class C: def __add__(self, o: 'C') -> 'C': pass [out] main:7: error: Unsupported operand types for + ("C" and "B") -main:8: error: Invalid index type "C" for A[C]; expected type "B" +main:8: error: Invalid index type "C" for "A[C]"; expected type "B" [case testOperatorAssignmentWithIndexLvalue2] from typing import TypeVar, Generic @@ -330,9 +330,9 @@ class B: pass class C: def __add__(self, o: 'C') -> 'C': pass [out] -main:7: error: Invalid index type "B" for A[C]; expected type "C" -main:8: error: Invalid index type "C" for A[C]; expected type "B" -main:9: error: Invalid index type "B" for A[C]; expected type "C" +main:7: error: Invalid index type "B" for "A[C]"; expected type "C" +main:8: error: Invalid index type "C" for "A[C]"; expected type "B" +main:9: error: Invalid index type "B" for "A[C]"; expected type "C" -- Nested generic types @@ -364,8 +364,8 @@ class B: class C: pass [out] -main:8: error: Incompatible types in assignment (expression has type A[B], variable has type A[C]) -main:9: error: Incompatible types in assignment (expression has type A[A[B]], variable has type A[A[C]]) +main:8: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]") +main:9: error: Incompatible types in assignment (expression has type "A[A[B]]", variable has type "A[A[C]]") -- Generic functions @@ -384,7 +384,7 @@ def f(s: S, t: T) -> p[T, A]: s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S") p_s_a = None # type: p[S, A] if s: - return p_s_a # E: Incompatible return value type (got p[S, A], expected p[T, A]) + return p_s_a # E: Incompatible return value type (got "p[S, A]", expected "p[T, A]") b = t # type: T c = s # type: S p_t_a = None # type: p[T, A] @@ -402,10 +402,10 @@ class A(Generic[T]): s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S") p_s_s = None # type: p[S, S] if s: - return p_s_s # E: Incompatible return value type (got p[S, S], expected p[S, T]) + return p_s_s # E: Incompatible return value type (got "p[S, S]", expected "p[S, T]") p_t_t = None # type: p[T, T] if t: - return p_t_t # E: Incompatible return value type (got p[T, T], expected p[S, T]) + return p_t_t # E: Incompatible return value type (got "p[T, T]", expected "p[S, T]") t = t s = s p_s_t = None # type: p[S, T] @@ -448,7 +448,7 @@ A[int, str, int]() # E: Type application has too many types (2 expected) a = None # type: A class A: pass a[A]() # E: Value of type "A" is not indexable -A[A]() # E: The type Type[A] is not generic and not indexable +A[A]() # E: The type "Type[A]" is not generic and not indexable [out] [case testTypeApplicationArgTypes] @@ -504,7 +504,7 @@ Alias[int]("a") # E: Argument 1 to "Node" has incompatible type "str"; expected [out] [case testTypeApplicationCrash] -type[int] # this was crashing, see #2302 (comment) # E: The type Type[type] is not generic and not indexable +type[int] # this was crashing, see #2302 (comment) # E: The type "Type[type]" is not generic and not indexable [out] @@ -564,7 +564,7 @@ def func(x: IntNode[T]) -> IntNode[T]: return x reveal_type(func) # E: Revealed type is 'def [T] (x: __main__.Node[builtins.int, T`-1]) -> __main__.Node[builtins.int, T`-1]' -func(1) # E: Argument 1 to "func" has incompatible type "int"; expected Node[int, ] +func(1) # E: Argument 1 to "func" has incompatible type "int"; expected "Node[int, ]" func(Node('x', 1)) # E: Argument 1 to "Node" has incompatible type "str"; expected "int" reveal_type(func(Node(1, 'x'))) # E: Revealed type is '__main__.Node[builtins.int, builtins.str*]' @@ -692,7 +692,7 @@ l.meth().append(1) reveal_type(l.meth()) # E: Revealed type is 'builtins.list*[builtins.int]' l.meth().append('x') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" -ListedNode[str]([]).x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type List[str]) +ListedNode[str]([]).x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "List[str]") [builtins fixtures/list.pyi] @@ -714,7 +714,7 @@ def f_bad(x: T) -> D[T]: return D(1) # Error, see out L[int]().append(Node((1, 1))) -L[int]().append(5) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected Node[Tuple[int, int]] +L[int]().append(5) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "Node[Tuple[int, int]]" x = D((1, 1)) # type: D[int] y = D(5) # type: D[int] # E: Argument 1 to "D" has incompatible type "int"; expected "Tuple[int, int]" @@ -778,7 +778,7 @@ if not isinstance(s, str): z = None # type: TNode # Same as TNode[Any] z.x -z.foo() # E: Item Node[int] of "Union[Any, Node[int]]" has no attribute "foo" +z.foo() # E: Item "Node[int]" of "Union[Any, Node[int]]" has no attribute "foo" [builtins fixtures/isinstance.pyi] @@ -847,7 +847,7 @@ def fun2(v: Vec[T], scale: T) -> Vec[T]: return v reveal_type(fun1([(1, 1)])) # E: Revealed type is 'builtins.int*' -fun1(1) # E: Argument 1 to "fun1" has incompatible type "int"; expected List[Tuple[int, int]] +fun1(1) # E: Argument 1 to "fun1" has incompatible type "int"; expected "List[Tuple[int, int]]" fun1([(1, 'x')]) # E: Cannot infer type argument 1 of "fun1" reveal_type(fun2([(1, 1)], 1)) # E: Revealed type is 'builtins.list[Tuple[builtins.int*, builtins.int*]]' @@ -868,7 +868,7 @@ n.y = 'x' # E: Incompatible types in assignment (expression has type "str", vari def f(x: Node[T, T]) -> TupledNode[T]: return Node(x.x, (x.x, x.x)) -f(1) # E: Argument 1 to "f" has incompatible type "int"; expected Node[, ] +f(1) # E: Argument 1 to "f" has incompatible type "int"; expected "Node[, ]" f(Node(1, 'x')) # E: Cannot infer type argument 1 of "f" reveal_type(Node('x', 'x')) # E: Revealed type is 'a.Node[builtins.str*, builtins.str*]' @@ -1221,7 +1221,7 @@ Z = TypeVar('Z') class OO: pass a = None # type: A[object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object] -f(a) # E: Argument 1 to "f" has incompatible type A[...]; expected "OO" +f(a) # E: Argument 1 to "f" has incompatible type "A[...]"; expected "OO" def f(a: OO) -> None: pass @@ -1232,7 +1232,7 @@ from typing import TypeVar, Generic S = TypeVar('S') T = TypeVar('T') a = None # type: A[object, B] -f(a) # E: Argument 1 to "f" has incompatible type A[object, B]; expected "B" +f(a) # E: Argument 1 to "f" has incompatible type "A[object, B]"; expected "B" def f(a: 'B') -> None: pass class A(Generic[S, T]): pass @@ -1243,7 +1243,7 @@ from typing import Callable, TypeVar, Generic S = TypeVar('S') T = TypeVar('T') a = None # type: A[object, Callable[[], None]] -f(a) # E: Argument 1 to "f" has incompatible type A[object, Callable[[], None]]; expected "B" +f(a) # E: Argument 1 to "f" has incompatible type "A[object, Callable[[], None]]"; expected "B" def f(a: 'B') -> None: pass class A(Generic[S, T]): pass @@ -1504,7 +1504,7 @@ T = TypeVar('T') class C(Generic[T]): def __init__(self) -> None: pass x = C # type: Callable[[], C[int]] -y = C # type: Callable[[], int] # E: Incompatible types in assignment (expression has type Type[C[Any]], variable has type Callable[[], int]) +y = C # type: Callable[[], int] # E: Incompatible types in assignment (expression has type "Type[C[Any]]", variable has type Callable[[], int]) -- Special cases diff --git a/test-data/unit/check-ignore.test b/test-data/unit/check-ignore.test index 3c81bd01d13a..5f2fd773a0c1 100644 --- a/test-data/unit/check-ignore.test +++ b/test-data/unit/check-ignore.test @@ -46,7 +46,7 @@ import b # type: ignore reveal_type(a.foo) # E: Revealed type is 'Any' reveal_type(b.foo) # E: Revealed type is 'builtins.int' a.bar() -b.bar() # E: Module has no attribute "bar" +b.bar() # E: "Module" has no attribute "bar" [file b.py] foo = 3 @@ -76,7 +76,7 @@ class B(A): import m m.x = object # type: ignore m.f() # type: ignore -m.y # E: Module has no attribute "y" +m.y # E: "Module" has no attribute "y" [file m.py] [builtins fixtures/module.pyi] @@ -194,7 +194,7 @@ foo(Child()) def bar(x: Base[str, str]) -> None: pass bar(Child()) [out] -main:19: error: Argument 1 to "bar" has incompatible type "Child"; expected Base[str, str] +main:19: error: Argument 1 to "bar" has incompatible type "Child"; expected "Base[str, str]" [case testTypeIgnoreLineNumberWithinFile] import m diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 23fafc24edf5..78da587098ec 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -325,7 +325,7 @@ const = 3 [stale mod3] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: Module has no attribute "mod4" +tmp/mod1.py:3: error: "Module" has no attribute "mod4" [case testIncrementalLongBrokenCascade] import mod1 @@ -360,7 +360,7 @@ const = 3 [stale mod6] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: Module has no attribute "mod7" +tmp/mod1.py:3: error: "Module" has no attribute "mod7" [case testIncrementalNestedBrokenCascade] import mod1 @@ -386,7 +386,7 @@ const = 3 [stale mod2.mod3] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: Module has no attribute "mod4" +tmp/mod1.py:3: error: "Module" has no attribute "mod4" [case testIncrementalNestedBrokenCascadeWithType1] import mod1, mod2.mod3.mod5 diff --git a/test-data/unit/check-inference-context.test b/test-data/unit/check-inference-context.test index 9896c1118a5a..4a8e5b1b8dc5 100644 --- a/test-data/unit/check-inference-context.test +++ b/test-data/unit/check-inference-context.test @@ -13,7 +13,7 @@ b = None # type: B ao = f() ab = f() -b = f() # E: Incompatible types in assignment (expression has type A[], variable has type "B") +b = f() # E: Incompatible types in assignment (expression has type "A[]", variable has type "B") def f() -> 'A[T]': pass @@ -29,7 +29,7 @@ b = None # type: B ao = A() ab = A() -b = A() # E: Incompatible types in assignment (expression has type A[], variable has type "B") +b = A() # E: Incompatible types in assignment (expression has type "A[]", variable has type "B") class A(Generic[T]): pass class B: pass @@ -74,10 +74,10 @@ def g() -> None: b = None # type: B x = f(o) - ab = x # E: Incompatible types in assignment (expression has type A[object], variable has type A[B]) + ab = x # E: Incompatible types in assignment (expression has type "A[object]", variable has type "A[B]") ao = x y = f(b) - ao = y # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) + ao = y # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") ab = y def f(a: T) -> 'A[T]': pass @@ -104,8 +104,8 @@ def g() -> None: ab = None # type: A[B] b = None # type: B x, y = f(b), f(b) - ao = x # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) - ao = y # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) + ao = x # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") + ao = y # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") ab = x ab = y @@ -122,8 +122,8 @@ def h() -> None: ab = None # type: A[B] b = None # type: B x, y = g(f(b)) - ao = x # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) - ao = y # E: Incompatible types in assignment (expression has type A[B], variable has type A[object]) + ao = x # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") + ao = y # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") ab = x ab = y @@ -161,8 +161,8 @@ class A(Generic[T]): pass class B: pass [builtins fixtures/tuple.pyi] [out] -main:8: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) -main:9: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) +main:8: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") +main:9: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") [case testInferenceWithTypeVariableTwiceInReturnTypeAndMultipleVariables] from typing import TypeVar, Tuple, Generic @@ -190,10 +190,10 @@ class A(Generic[T]): pass class B: pass [builtins fixtures/tuple.pyi] [out] -main:9: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) -main:10: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) -main:11: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) -main:12: error: Incompatible types in assignment (expression has type A[B], variable has type A[object]) +main:9: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") +main:10: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") +main:11: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") +main:12: error: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") -- Multiple tvar instances in arguments @@ -309,7 +309,7 @@ ab = None # type: A[B] ac = None # type: A[C] ab.g(f(o)) # E: Argument 1 to "f" has incompatible type "object"; expected "B" -ac = f(b).g(f(c)) # E: Incompatible types in assignment (expression has type A[B], variable has type A[C]) +ac = f(b).g(f(c)) # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]") ac = f(c).g(f(b)) # E: Argument 1 to "f" has incompatible type "B"; expected "C" ab = f(b).g(f(c)) @@ -334,7 +334,7 @@ aa = None # type: List[A] ao = None # type: List[object] a = None # type: A -a = [] # E: Incompatible types in assignment (expression has type List[], variable has type "A") +a = [] # E: Incompatible types in assignment (expression has type "List[]", variable has type "A") aa = [] ao = [] @@ -401,7 +401,7 @@ ab = None # type: List[B] b = None # type: B o = None # type: object -aao = [[o], ab] # E: List item 1 has incompatible type List[B] +aao = [[o], ab] # E: List item 1 has incompatible type "List[B]" aab = [[], [o]] # E: List item 0 has incompatible type "object" aao = [[None], [b], [], [o]] @@ -462,7 +462,7 @@ d = {A() : a_c, [case testInitializationWithInferredGenericType] from typing import TypeVar, Generic T = TypeVar('T') -c = f(A()) # type: C[A] # E: Argument 1 to "f" has incompatible type "A"; expected C[A] +c = f(A()) # type: C[A] # E: Argument 1 to "f" has incompatible type "A"; expected "C[A]" def f(x: T) -> T: pass class C(Generic[T]): pass @@ -503,7 +503,7 @@ from abc import abstractmethod, ABCMeta t = TypeVar('t') x = A() # type: I[int] a_object = A() # type: A[object] -y = a_object # type: I[int] # E: Incompatible types in assignment (expression has type A[object], variable has type I[int]) +y = a_object # type: I[int] # E: Incompatible types in assignment (expression has type "A[object]", variable has type "I[int]") class I(Generic[t]): @abstractmethod @@ -663,7 +663,7 @@ class B: pass m = map(g, [A()]) b = m # type: List[B] -a = m # type: List[A] # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) +a = m # type: List[A] # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") [builtins fixtures/list.pyi] @@ -677,8 +677,8 @@ a, b, c = None, None, None # type: (List[A], List[B], List[C]) a = a or [] a = [] or a b = b or [C()] -a = a or b # E: Incompatible types in assignment (expression has type "Union[List[A], List[B]]", variable has type List[A]) -b = b or c # E: Incompatible types in assignment (expression has type "Union[List[B], List[C]]", variable has type List[B]) +a = a or b # E: Incompatible types in assignment (expression has type "Union[List[A], List[B]]", variable has type "List[A]") +b = b or c # E: Incompatible types in assignment (expression has type "Union[List[B], List[C]]", variable has type "List[B]") class A: pass class B: pass @@ -732,7 +732,7 @@ from typing import List i = None # type: List[int] s = None # type: List[str] i = i = [] -i = s = [] # E: Incompatible types in assignment (expression has type List[str], variable has type List[int]) +i = s = [] # E: Incompatible types in assignment (expression has type "List[str]", variable has type "List[int]") [builtins fixtures/list.pyi] [case testContextForAttributeDeclaredInInit] diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 42cd312c0531..76931ad3b254 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -69,7 +69,7 @@ class B: pass import typing def f() -> None: a = g() - None(a) # E: None not callable + None(a) # E: "None" not callable a.x() def g(): pass @@ -81,7 +81,7 @@ g = None # type: Any def f(a: Any) -> None: b = g - None(b) # E: None not callable + None(b) # E: "None" not callable a.x() [out] @@ -126,7 +126,7 @@ a_s = None # type: A[str] def f() -> None: a_int = A() # type: A[int] a = a_int - a = a_s # E: Incompatible types in assignment (expression has type A[str], variable has type A[int]) + a = a_s # E: Incompatible types in assignment (expression has type "A[str]", variable has type "A[int]") a = a_i [builtins fixtures/tuple.pyi] [out] @@ -480,11 +480,11 @@ ao = None # type: A[object] ab = None # type: A[B] ac = None # type: A[C] -ab = f(ao) # E: Argument 1 to "f" has incompatible type A[object]; expected A[B] -ao = f(ab) # E: Argument 1 to "f" has incompatible type A[B]; expected A[object] -ab = f(ac) # E: Argument 1 to "f" has incompatible type A[C]; expected A[B] -ab = g(ao) # E: Argument 1 to "g" has incompatible type A[object]; expected A[B] -ao = g(ab) # E: Argument 1 to "g" has incompatible type A[B]; expected A[object] +ab = f(ao) # E: Argument 1 to "f" has incompatible type "A[object]"; expected "A[B]" +ao = f(ab) # E: Argument 1 to "f" has incompatible type "A[B]"; expected "A[object]" +ab = f(ac) # E: Argument 1 to "f" has incompatible type "A[C]"; expected "A[B]" +ab = g(ao) # E: Argument 1 to "g" has incompatible type "A[object]"; expected "A[B]" +ao = g(ab) # E: Argument 1 to "g" has incompatible type "A[B]"; expected "A[object]" ab = f(ab) ac = f(ac) @@ -648,7 +648,7 @@ def mymap(f: Callable[[t], s], a: List[t]) -> List[s]: pass l = mymap(f, [b]) l = [A()] lb = [b] -l = lb # E: Incompatible types in assignment (expression has type List[bool], variable has type List[A]) +l = lb # E: Incompatible types in assignment (expression has type "List[bool]", variable has type "List[A]") [builtins fixtures/for.pyi] [case testGenericFunctionWithTypeTypeAsCallable] @@ -676,7 +676,7 @@ f(1, 1)() # E: "int" not callable def g(x: Union[T, List[T]]) -> List[T]: pass def h(x: List[str]) -> None: pass -g('a')() # E: List[str] not callable +g('a')() # E: "List[str]" not callable # The next line is a case where there are multiple ways to satisfy a constraint # involving a Union. Either T = List[str] or T = str would turn out to be valid, @@ -684,7 +684,7 @@ g('a')() # E: List[str] not callable # to backtrack later) and defaults to T = . The result is an # awkward error message. Either a better error message, or simply accepting the # call, would be preferable here. -g(['a']) # E: Argument 1 to "g" has incompatible type List[str]; expected List[] +g(['a']) # E: Argument 1 to "g" has incompatible type "List[str]"; expected "List[]" h(g(['a'])) @@ -693,7 +693,7 @@ a = [1] b = ['b'] i(a, a, b) i(b, a, b) -i(a, b, b) # E: Argument 1 to "i" has incompatible type List[int]; expected List[str] +i(a, b, b) # E: Argument 1 to "i" has incompatible type "List[int]"; expected "List[str]" [builtins fixtures/list.pyi] [case testCallableListJoinInference] @@ -778,7 +778,7 @@ from typing import TypeVar, Union, List T = TypeVar('T') def f() -> List[T]: pass d1 = f() # type: Union[List[int], str] -d2 = f() # type: Union[int, str] # E: Incompatible types in assignment (expression has type List[], variable has type "Union[int, str]") +d2 = f() # type: Union[int, str] # E: Incompatible types in assignment (expression has type "List[]", variable has type "Union[int, str]") def g(x: T) -> List[T]: pass d3 = g(1) # type: Union[List[int], List[str]] [builtins fixtures/list.pyi] @@ -840,7 +840,7 @@ def d_aa() -> Dict[A, A]: return {} a, b = None, None # type: (A, B) d = {a:b} d = d_ab() -d = d_aa() # E: Incompatible types in assignment (expression has type Dict[A, A], variable has type Dict[A, B]) +d = d_aa() # E: Incompatible types in assignment (expression has type "Dict[A, A]", variable has type "Dict[A, B]") [builtins fixtures/dict.pyi] [case testSetLiteral] @@ -851,7 +851,7 @@ def s_s() -> Set[str]: return set() s = {a} s = {x} s = s_i() -s = s_s() # E: Incompatible types in assignment (expression has type Set[str], variable has type Set[int]) +s = s_s() # E: Incompatible types in assignment (expression has type "Set[str]", variable has type "Set[int]") [builtins fixtures/set.pyi] [case testSetWithStarExpr] @@ -1154,7 +1154,7 @@ a = None # type: List[A] o = None # type: List[object] a2 = a or [] a = a2 -a2 = o # E: Incompatible types in assignment (expression has type List[object], variable has type List[A]) +a2 = o # E: Incompatible types in assignment (expression has type "List[object]", variable has type "List[A]") class A: pass [builtins fixtures/list.pyi] @@ -1194,7 +1194,7 @@ x2 = [B(), A()] x3 = [B(), B()] a = x1 a = x2 -a = x3 # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) +a = x3 # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") [builtins fixtures/list.pyi] [case testListWithDucktypeCompatibilityAndTransitivity] @@ -1210,7 +1210,7 @@ x2 = [C(), A()] x3 = [B(), C()] a = x1 a = x2 -a = x3 # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) +a = x3 # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") [builtins fixtures/list.pyi] @@ -1256,8 +1256,8 @@ a() a, b = [], [] a.append(1) b.append('') -a() # E: List[int] not callable -b() # E: List[str] not callable +a() # E: "List[int]" not callable +b() # E: "List[str]" not callable [builtins fixtures/list.pyi] [out] @@ -1371,14 +1371,14 @@ a.add('') # E: Argument 1 to "add" of "set" has incompatible type "str"; expect [case testInferDictInitializedToEmpty] a = {} a[1] = '' -a() # E: Dict[int, str] not callable +a() # E: "Dict[int, str]" not callable [builtins fixtures/dict.pyi] [out] [case testInferDictInitializedToEmptyUsingUpdate] a = {} a.update({'': 42}) -a() # E: Dict[str, int] not callable +a() # E: "Dict[str, int]" not callable [builtins fixtures/dict.pyi] [out] @@ -1447,7 +1447,7 @@ def f() -> None: import typing def f() -> None: a = None - a.x() # E: None has no attribute "x" + a.x() # E: "None" has no attribute "x" [out] [case testGvarPartiallyInitializedToNone] @@ -1504,7 +1504,7 @@ x = None def f() -> None: x = None x = 1 -x() # E: None not callable +x() # E: "None" not callable [case testAttributePartiallyInitializedToNone] class A: @@ -1523,8 +1523,8 @@ class A: self.x = 1 self.x() [out] -main:6: error: Incompatible types in assignment (expression has type "int", variable has type None) -main:7: error: None not callable +main:6: error: Incompatible types in assignment (expression has type "int", variable has type "None") +main:7: error: "None" not callable [case testGlobalInitializedToNoneSetFromFunction] a = None @@ -1553,7 +1553,7 @@ class A: pass [builtins fixtures/for.pyi] [out] -main:5: error: None has no attribute "__iter__" +main:5: error: "None" has no attribute "__iter__" [case testPartialTypeErrorSpecialCase2] # This used to crash. @@ -1574,7 +1574,7 @@ class A: pass [builtins fixtures/for.pyi] [out] -main:4: error: None has no attribute "__iter__" +main:4: error: "None" has no attribute "__iter__" -- Multipass @@ -1680,7 +1680,7 @@ def g(d: Dict[str, int]) -> None: pass def f() -> None: x = {} x[1] = y - g(x) # E: Argument 1 to "g" has incompatible type Dict[int, str]; expected Dict[str, int] + g(x) # E: Argument 1 to "g" has incompatible type "Dict[int, str]"; expected "Dict[str, int]" x[1] = 1 # E: Incompatible types in assignment (expression has type "int", target has type "str") x[1] = '' y = '' @@ -1694,7 +1694,7 @@ def f() -> None: x = {} y x[1] = 1 - g(x) # E: Argument 1 to "g" has incompatible type Dict[int, int]; expected Dict[str, int] + g(x) # E: Argument 1 to "g" has incompatible type "Dict[int, int]"; expected "Dict[str, int]" y = '' [builtins fixtures/dict.pyi] [out] @@ -1713,7 +1713,7 @@ def f() -> None: y = o x = [] x.append(y) - x() # E: List[int] not callable + x() # E: "List[int]" not callable o = 1 [builtins fixtures/list.pyi] [out] @@ -1723,7 +1723,7 @@ def f() -> None: y = o x = {} x[''] = y - x() # E: Dict[str, int] not callable + x() # E: "Dict[str, int]" not callable o = 1 [builtins fixtures/dict.pyi] [out] @@ -1825,20 +1825,20 @@ a2.foo2() [case testUnificationEmptyListLeft] def f(): pass a = [] if f() else [0] -a() # E: List[int] not callable +a() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testUnificationEmptyListRight] def f(): pass a = [0] if f() else [] -a() # E: List[int] not callable +a() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testUnificationEmptyListLeftInContext] from typing import List def f(): pass a = [] if f() else [0] # type: List[int] -a() # E: List[int] not callable +a() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testUnificationEmptyListRightInContext] @@ -1846,37 +1846,37 @@ a() # E: List[int] not callable from typing import List def f(): pass a = [0] if f() else [] # type: List[int] -a() # E: List[int] not callable +a() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testUnificationEmptySetLeft] def f(): pass a = set() if f() else {0} -a() # E: Set[int] not callable +a() # E: "Set[int]" not callable [builtins fixtures/set.pyi] [case testUnificationEmptyDictLeft] def f(): pass a = {} if f() else {0: 0} -a() # E: Dict[int, int] not callable +a() # E: "Dict[int, int]" not callable [builtins fixtures/dict.pyi] [case testUnificationEmptyDictRight] def f(): pass a = {0: 0} if f() else {} -a() # E: Dict[int, int] not callable +a() # E: "Dict[int, int]" not callable [builtins fixtures/dict.pyi] [case testUnificationDictWithEmptyListLeft] def f(): pass a = {0: []} if f() else {0: [0]} -a() # E: Dict[int, List[int]] not callable +a() # E: "Dict[int, List[int]]" not callable [builtins fixtures/dict.pyi] [case testUnificationDictWithEmptyListRight] def f(): pass a = {0: [0]} if f() else {0: []} -a() # E: Dict[int, List[int]] not callable +a() # E: "Dict[int, List[int]]" not callable [builtins fixtures/dict.pyi] [case testMisguidedSetItem] diff --git a/test-data/unit/check-isinstance.test b/test-data/unit/check-isinstance.test index 825a5557fc63..d9a27649e4af 100644 --- a/test-data/unit/check-isinstance.test +++ b/test-data/unit/check-isinstance.test @@ -679,7 +679,7 @@ while bool(): x + 'a' break x + [1] - x + 'a' # E: Unsupported operand types for + (List[int] and "str") + x + 'a' # E: Unsupported operand types for + ("List[int]" and "str") x + [1] # E: Unsupported operand types for + (likely involving Union) [builtins fixtures/isinstancelist.pyi] @@ -1486,7 +1486,7 @@ def test_issubclass(cls: Type[Goblin]) -> None: else: reveal_type(cls) # E: Revealed type is 'Type[__main__.Goblin]' cls.level - cls.job # E: Type[Goblin] has no attribute "job" + cls.job # E: "Type[Goblin]" has no attribute "job" g = cls() g.level = 15 g.job # E: "Goblin" has no attribute "job" @@ -1511,7 +1511,7 @@ def test_issubclass(cls: Type[Mob]) -> None: if issubclass(cls, Goblin): reveal_type(cls) # E: Revealed type is 'Type[__main__.Goblin]' cls.level - cls.job # E: Type[Goblin] has no attribute "job" + cls.job # E: "Type[Goblin]" has no attribute "job" g = cls() g.level = 15 g.job # E: "Goblin" has no attribute "job" @@ -1525,8 +1525,8 @@ def test_issubclass(cls: Type[Mob]) -> None: g.job = 'Warrior' # E: Cannot assign to class variable "job" via instance else: reveal_type(cls) # E: Revealed type is 'Type[__main__.Mob]' - cls.job # E: Type[Mob] has no attribute "job" - cls.level # E: Type[Mob] has no attribute "level" + cls.job # E: "Type[Mob]" has no attribute "job" + cls.level # E: "Type[Mob]" has no attribute "level" m = cls() m.level = 15 # E: "Mob" has no attribute "level" m.job # E: "Mob" has no attribute "job" @@ -1570,7 +1570,7 @@ def test_issubclass(cls: Type[Mob]) -> None: if issubclass(cls, (Goblin, GoblinAmbusher)): reveal_type(cls) # E: Revealed type is 'Type[__main__.Goblin]' cls.level - cls.job # E: Type[Goblin] has no attribute "job" + cls.job # E: "Type[Goblin]" has no attribute "job" g = cls() g.level = 15 g.job # E: "Goblin" has no attribute "job" @@ -1584,8 +1584,8 @@ def test_issubclass(cls: Type[Mob]) -> None: ga.job = "Warrior" # E: Cannot assign to class variable "job" via instance else: reveal_type(cls) # E: Revealed type is 'Type[__main__.Mob]' - cls.job # E: Type[Mob] has no attribute "job" - cls.level # E: Type[Mob] has no attribute "level" + cls.job # E: "Type[Mob]" has no attribute "job" + cls.level # E: "Type[Mob]" has no attribute "level" m = cls() m.level = 15 # E: "Mob" has no attribute "level" m.job # E: "Mob" has no attribute "job" diff --git a/test-data/unit/check-kwargs.test b/test-data/unit/check-kwargs.test index de229c76e631..e8182b34ae8f 100644 --- a/test-data/unit/check-kwargs.test +++ b/test-data/unit/check-kwargs.test @@ -4,7 +4,7 @@ [case testTypeErrorInKeywordArgument] import typing def f(o: object) -> None: pass -f(o=None()) # E: None not callable +f(o=None()) # E: "None" not callable [case testSimpleKeywordArgument] import typing @@ -89,8 +89,8 @@ class A: pass [case testKeywordArgumentsWithDynamicallyTypedCallable] from typing import Any f = None # type: Any -f(x=f(), z=None()) # E: None not callable -f(f, zz=None()) # E: None not callable +f(x=f(), z=None()) # E: "None" not callable +f(f, zz=None()) # E: "None" not callable f(x=None) [case testKeywordArgumentWithFunctionObject] @@ -216,8 +216,8 @@ class A: pass from typing import Dict, Any def f( **kwargs: 'A') -> None: d1 = kwargs # type: Dict[str, A] - d2 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type Dict[str, A], variable has type Dict[A, Any]) - d3 = kwargs # type: Dict[Any, str] # E: Incompatible types in assignment (expression has type Dict[str, A], variable has type Dict[Any, str]) + d2 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type "Dict[str, A]", variable has type "Dict[A, Any]") + d3 = kwargs # type: Dict[Any, str] # E: Incompatible types in assignment (expression has type "Dict[str, A]", variable has type "Dict[Any, str]") class A: pass [builtins fixtures/dict.pyi] [out] @@ -227,7 +227,7 @@ from typing import Dict, Any def f(**kwargs) -> None: d1 = kwargs # type: Dict[str, A] d2 = kwargs # type: Dict[str, str] - d3 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type Dict[str, Any], variable has type Dict[A, Any]) + d3 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type "Dict[str, Any]", variable has type "Dict[A, Any]") class A: pass [builtins fixtures/dict.pyi] [out] @@ -252,8 +252,8 @@ d = None # type: Dict[str, A] f(**d) f(x=A(), **d) d2 = None # type: Dict[str, B] -f(**d2) # E: Argument 1 to "f" has incompatible type **Dict[str, B]; expected "A" -f(x=A(), **d2) # E: Argument 2 to "f" has incompatible type **Dict[str, B]; expected "A" +f(**d2) # E: Argument 1 to "f" has incompatible type **"Dict[str, B]"; expected "A" +f(x=A(), **d2) # E: Argument 2 to "f" has incompatible type **"Dict[str, B]"; expected "A" class A: pass class B: pass [builtins fixtures/dict.pyi] @@ -295,7 +295,7 @@ def f(a: 'A', b: 'B') -> None: pass d = None # type: Dict[str, Any] f(**d) d2 = None # type: Dict[str, A] -f(**d2) # E: Argument 1 to "f" has incompatible type **Dict[str, A]; expected "B" +f(**d2) # E: Argument 1 to "f" has incompatible type **"Dict[str, A]"; expected "B" class A: pass class B: pass [builtins fixtures/dict.pyi] @@ -344,12 +344,12 @@ s = ('',) f(*s) # E: Argument 1 to "f" has incompatible type *"Tuple[str]"; expected "int" a = {'': 0} -f(a) # E: Argument 1 to "f" has incompatible type Dict[str, int]; expected "int" +f(a) # E: Argument 1 to "f" has incompatible type "Dict[str, int]"; expected "int" f(**a) # okay b = {'': ''} -f(b) # E: Argument 1 to "f" has incompatible type Dict[str, str]; expected "int" -f(**b) # E: Argument 1 to "f" has incompatible type **Dict[str, str]; expected "int" +f(b) # E: Argument 1 to "f" has incompatible type "Dict[str, str]"; expected "int" +f(**b) # E: Argument 1 to "f" has incompatible type **"Dict[str, str]"; expected "int" c = {0: 0} f(**c) # E: Keywords must be strings diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test index 66050601d26f..10c6a22680d6 100644 --- a/test-data/unit/check-modules.test +++ b/test-data/unit/check-modules.test @@ -155,16 +155,16 @@ import m import typing class A: pass -m() # E: Module not callable -a = m # type: A # E: Incompatible types in assignment (expression has type Module, variable has type "A") -m + None # E: Unsupported left operand type for + (Module) +m() # E: "Module" not callable +a = m # type: A # E: Incompatible types in assignment (expression has type "Module", variable has type "A") +m + None # E: Unsupported left operand type for + ("Module") [file m.py] [builtins fixtures/module.pyi] [case testNameDefinedInDifferentModule] import m, n import typing -m.x # E: Module has no attribute "x" +m.x # E: "Module" has no attribute "x" [file m.py] y = object() [file n.py] @@ -201,7 +201,7 @@ None + '' [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testTypeCheckWithUnknownModule2] import m, nonexistent @@ -213,7 +213,7 @@ x = 1 [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") main:4: error: Incompatible types in assignment (expression has type "str", variable has type "int") [case testTypeCheckWithUnknownModule3] @@ -226,7 +226,7 @@ x = 1 [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") main:4: error: Incompatible types in assignment (expression has type "str", variable has type "int") [case testTypeCheckWithUnknownModule4] @@ -236,7 +236,7 @@ None + '' main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) main:1: error: Cannot find module named 'another' -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testTypeCheckWithUnknownModule5] import nonexistent as x @@ -244,7 +244,7 @@ None + '' [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testTypeCheckWithUnknownModuleUsingFromImport] from nonexistent import x @@ -252,7 +252,7 @@ None + '' [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testTypeCheckWithUnknownModuleUsingImportStar] from nonexistent import * @@ -260,7 +260,7 @@ None + '' [out] main:1: error: Cannot find module named 'nonexistent' main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") [case testAccessingUnknownModule] import xyz @@ -330,7 +330,7 @@ import nonexistent [out] tmp/x.py:1: error: Cannot find module named 'nonexistent' tmp/x.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:3: error: Module has no attribute "z" +main:3: error: "Module" has no attribute "z" [case testUnknownModuleImportedWithinFunction] def f(): @@ -411,14 +411,14 @@ import typing __all__ = [1, 2, 3] [builtins fixtures/module_all.pyi] [out] -main:2: error: Type of __all__ must be Sequence[str], not List[int] +main:2: error: Type of __all__ must be "Sequence[str]", not "List[int]" [case testAllMustBeSequenceStr_python2] import typing __all__ = [1, 2, 3] [builtins_py2 fixtures/module_all_python2.pyi] [out] -main:2: error: Type of __all__ must be Sequence[unicode], not List[int] +main:2: error: Type of __all__ must be "Sequence[unicode]", not "List[int]" [case testAllUnicodeSequenceOK_python2] import typing @@ -648,7 +648,7 @@ def f(x: str) -> None: pass if object(): import m else: - m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type Module) + m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Module") [file m.py] [builtins fixtures/module.pyi] [out] @@ -673,7 +673,7 @@ def f(x: str) -> None: pass None + 1 [file m/a.py] [out] -tmp/m/__init__.py:1: error: Unsupported left operand type for + (None) +tmp/m/__init__.py:1: error: Unsupported left operand type for + ("None") [case testTypeCheckNamedModule2] # cmd: mypy -m m.a @@ -681,7 +681,7 @@ tmp/m/__init__.py:1: error: Unsupported left operand type for + (None) [file m/a.py] None + 1 [out] -tmp/m/a.py:1: error: Unsupported left operand type for + (None) +tmp/m/a.py:1: error: Unsupported left operand type for + ("None") [case testTypeCheckNamedModule3] # cmd: mypy -m m @@ -689,7 +689,7 @@ tmp/m/a.py:1: error: Unsupported left operand type for + (None) None + 1 [file m/a.py] [out] -tmp/m/__init__.py:1: error: Unsupported left operand type for + (None) +tmp/m/__init__.py:1: error: Unsupported left operand type for + ("None") [case testTypeCheckNamedModule4] # cmd: mypy -m m @@ -704,7 +704,7 @@ None + '' # Not analyzed. [file m.py] None + 1 [out] -tmp/m.py:1: error: Unsupported left operand type for + (None) +tmp/m.py:1: error: Unsupported left operand type for + ("None") [case testTypeCheckNamedModuleWithImportCycle] # cmd: mypy -m m.a @@ -752,7 +752,7 @@ value = 3.2 [case testSubmoduleImportFromDoesNotAddParents] from a import b reveal_type(b.value) # E: Revealed type is 'builtins.str' -b.c.value # E: Module has no attribute "c" +b.c.value # E: "Module" has no attribute "c" a.value # E: Name 'a' is not defined [file a/__init__.py] @@ -853,7 +853,7 @@ bar = parent.unrelated.ShouldNotLoad() [builtins fixtures/module.pyi] [out] tmp/parent/child.py:8: error: Revealed type is 'parent.common.SomeClass' -tmp/parent/child.py:9: error: Module has no attribute "unrelated" +tmp/parent/child.py:9: error: "Module" has no attribute "unrelated" [case testSubmoduleMixingImportFromAndImport2] import parent.child @@ -915,7 +915,7 @@ class z: pass [out] main:2: error: Incompatible import of "x" (imported name has type "str", local name has type "int") main:2: error: Incompatible import of "y" (imported name has type Callable[[], str], local name has type Callable[[], int]) -main:2: error: Incompatible import of "z" (imported name has type Type[b.z], local name has type Type[a.z]) +main:2: error: Incompatible import of "z" (imported name has type "Type[b.z]", local name has type "Type[a.z]") -- Misc diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 81aa3f6957e6..9f803bbcc558 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -221,7 +221,7 @@ a = (1,) # E: Incompatible types in assignment (expression has type "Tuple[int] [case testNamedTupleMissingClassAttribute] import collections MyNamedTuple = collections.namedtuple('MyNamedTuple', ['spam', 'eggs']) -MyNamedTuple.x # E: Type[MyNamedTuple] has no attribute "x" +MyNamedTuple.x # E: "Type[MyNamedTuple]" has no attribute "x" [case testNamedTupleEmptyItems] @@ -286,7 +286,7 @@ from typing import NamedTuple X = NamedTuple('X', [('x', int), ('y', str)]) reveal_type(X._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' -X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any] +X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected "Iterable[Any]" -- # FIX: not a proper class method -- x = None # type: X @@ -420,7 +420,7 @@ class C: A = NamedTuple('A', [('x', int)]) def g(self): A = NamedTuple('A', [('y', int)]) -C.A # E: Type[C] has no attribute "A" +C.A # E: "Type[C]" has no attribute "A" [case testNamedTupleInFunction] from typing import NamedTuple diff --git a/test-data/unit/check-newsyntax.test b/test-data/unit/check-newsyntax.test index 9f3f87853e63..f17b324cbca2 100644 --- a/test-data/unit/check-newsyntax.test +++ b/test-data/unit/check-newsyntax.test @@ -29,7 +29,7 @@ from typing import Dict, Any d: Dict[int, str] = {} d[42] = 'ab' d[42] = 42 # E: Incompatible types in assignment (expression has type "int", target has type "str") -d['ab'] = 'ab' # E: Invalid index type "str" for Dict[int, str]; expected type "int" +d['ab'] = 'ab' # E: Invalid index type "str" for "Dict[int, str]"; expected type "int" [builtins fixtures/dict.pyi] [out] @@ -61,29 +61,29 @@ TstInstance().a = 'ab' [case testNewSyntaxWithClassVars] # flags: --strict-optional --python-version 3.6 class CCC: - a: str = None # E: Incompatible types in assignment (expression has type None, variable has type "str") + a: str = None # E: Incompatible types in assignment (expression has type "None", variable has type "str") [out] [case testNewSyntaxWithStrictOptional] # flags: --strict-optional --python-version 3.6 strict: int -strict = None # E: Incompatible types in assignment (expression has type None, variable has type "int") -strict2: int = None # E: Incompatible types in assignment (expression has type None, variable has type "int") +strict = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") +strict2: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [out] [case testNewSyntaxWithStrictOptionalFunctions] # flags: --strict-optional --python-version 3.6 def f() -> None: x: int - x = None # E: Incompatible types in assignment (expression has type None, variable has type "int") + x = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [out] [case testNewSyntaxWithStrictOptionalClasses] # flags: --strict-optional --python-version 3.6 class C: def meth(self) -> None: - x: int = None # E: Incompatible types in assignment (expression has type None, variable has type "int") - self.x: int = None # E: Incompatible types in assignment (expression has type None, variable has type "int") + x: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") + self.x: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [out] [case testNewSyntaxSpecialAssign] diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index 3cde2f99a1fb..3b3f688f1801 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -2,11 +2,11 @@ [case testImplicitNoneType] x = None -x() # E: None not callable +x() # E: "None" not callable [case testExplicitNoneType] x = None # type: None -x() # E: None not callable +x() # E: "None" not callable [case testNoneMemberOfOptional] from typing import Optional @@ -19,12 +19,12 @@ x = 0 # type: Optional[int] [case testNoneNotMemberOfType] x = None # type: int [out] -main:1: error: Incompatible types in assignment (expression has type None, variable has type "int") +main:1: error: Incompatible types in assignment (expression has type "None", variable has type "int") [case testTypeNotMemberOfNone] x = 0 # type: None [out] -main:1: error: Incompatible types in assignment (expression has type "int", variable has type None) +main:1: error: Incompatible types in assignment (expression has type "int", variable has type "None") [case testOptionalNotMemberOfType] from typing import Optional @@ -180,13 +180,13 @@ reveal_type(x) # E: Revealed type is 'Union[builtins.int, builtins.None]' [case testInferOptionalListType] x = [None] -x.append(1) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected None +x.append(1) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "None" [builtins fixtures/list.pyi] [case testInferNonOptionalListType] x = [] x.append(1) -x() # E: List[int] not callable +x() # E: "List[int]" not callable [builtins fixtures/list.pyi] [case testInferOptionalDictKeyValueTypes] @@ -194,13 +194,13 @@ x = {None: None} x["bar"] = 1 [builtins fixtures/dict.pyi] [out] -main:2: error: Invalid index type "str" for Dict[None, None]; expected type None -main:2: error: Incompatible types in assignment (expression has type "int", target has type None) +main:2: error: Invalid index type "str" for "Dict[None, None]"; expected type "None" +main:2: error: Incompatible types in assignment (expression has type "int", target has type "None") [case testInferNonOptionalDictType] x = {} x["bar"] = 1 -x() # E: Dict[str, int] not callable +x() # E: "Dict[str, int]" not callable [builtins fixtures/dict.pyi] [case testNoneClassVariable] @@ -215,7 +215,7 @@ from typing import Optional class C: x = None # type: int def __init__(self) -> None: - self.x = None # E: Incompatible types in assignment (expression has type None, variable has type "int") + self.x = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [out] [case testMultipleAssignmentNoneClassVariableInInit] @@ -223,8 +223,8 @@ from typing import Optional class C: x, y = None, None # type: int, str def __init__(self) -> None: - self.x = None # E: Incompatible types in assignment (expression has type None, variable has type "int") - self.y = None # E: Incompatible types in assignment (expression has type None, variable has type "str") + self.x = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") + self.y = None # E: Incompatible types in assignment (expression has type "None", variable has type "str") [out] [case testOverloadWithNone] diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index 69289fae18c1..4f359a3efefb 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -447,7 +447,7 @@ from foo import * from typing import overload t, a = None, None # type: (type, A) -a = A # E: Incompatible types in assignment (expression has type Type[A], variable has type "A") +a = A # E: Incompatible types in assignment (expression has type "Type[A]", variable has type "A") t = A class A: @@ -610,7 +610,7 @@ n = 1 m = 1 n = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int") m = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int") -f(list_object) # E: Argument 1 to "f" has incompatible type List[object]; expected List[int] +f(list_object) # E: Argument 1 to "f" has incompatible type "List[object]"; expected "List[int]" [builtins fixtures/list.pyi] [case testOverlappingOverloadSignatures] @@ -901,7 +901,7 @@ def f(x: int, y: List[int] = None) -> int: pass def f(x: int, y: List[str] = None) -> int: pass f(y=[1], x=0)() # E: "int" not callable f(y=[''], x=0)() # E: "int" not callable -a = f(y=[['']], x=0) # E: List item 0 has incompatible type List[str] +a = f(y=[['']], x=0) # E: List item 0 has incompatible type "List[str]" a() # E: "int" not callable [builtins fixtures/list.pyi] @@ -1117,14 +1117,14 @@ def f(x: int, y: Tuple[str, ...]) -> None: pass @overload def f(x: int, y: str) -> None: pass f(1, ('2', '3')) -f(1, (2, '3')) # E: Argument 2 to "f" has incompatible type "Tuple[int, str]"; expected Tuple[str, ...] +f(1, (2, '3')) # E: Argument 2 to "f" has incompatible type "Tuple[int, str]"; expected "Tuple[str, ...]" f(1, ('2',)) f(1, '2') -f(1, (2, 3)) # E: Argument 2 to "f" has incompatible type "Tuple[int, int]"; expected Tuple[str, ...] +f(1, (2, 3)) # E: Argument 2 to "f" has incompatible type "Tuple[int, int]"; expected "Tuple[str, ...]" x = ('2', '3') # type: Tuple[str, ...] f(1, x) y = (2, 3) # type: Tuple[int, ...] -f(1, y) # E: Argument 2 to "f" has incompatible type Tuple[int, ...]; expected Tuple[str, ...] +f(1, y) # E: Argument 2 to "f" has incompatible type "Tuple[int, ...]"; expected "Tuple[str, ...]" [builtins fixtures/tuple.pyi] [case testCallableSpecificOverload] diff --git a/test-data/unit/check-python2.test b/test-data/unit/check-python2.test index b3b899b21560..24022f4b15d8 100644 --- a/test-data/unit/check-python2.test +++ b/test-data/unit/check-python2.test @@ -34,7 +34,7 @@ class A: print >>A(), '' print >>None, '' print >>1, '' # E: "int" has no attribute "write" -print >>(None + ''), None # E: Unsupported left operand type for + (None) +print >>(None + ''), None # E: Unsupported left operand type for + ("None") [case testDivision] class A: @@ -291,7 +291,7 @@ class A(object): __metaclass__ = M y = 0 reveal_type(A.y) # E: Revealed type is 'builtins.int' -A.x # E: Type[A] has no attribute "x" +A.x # E: "Type[A]" has no attribute "x" [case testAnyAsBaseOfMetaclass] from typing import Any, Type diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test index 8c1f85b1d743..a8071d68b1e6 100644 --- a/test-data/unit/check-statements.test +++ b/test-data/unit/check-statements.test @@ -377,7 +377,7 @@ import typing assert None + None # Fail assert None [out] -main:2: error: Unsupported left operand type for + (None) +main:2: error: Unsupported left operand type for + ("None") -- Exception handling @@ -599,9 +599,9 @@ main:7: error: Incompatible redefinition (redefinition with type Callable[[], st [case testExceptWithoutType] import typing try: - -None # E: Unsupported operand type for unary - (None) + -None # E: Unsupported operand type for unary - ("None") except: - ~None # E: Unsupported operand type for ~ (None) + ~None # E: Unsupported operand type for ~ ("None") [builtins fixtures/exception.pyi] [case testRaiseWithoutArgument] @@ -1189,7 +1189,7 @@ def g() -> Iterator[List[int]]: yield [2, 3, 4] def f() -> Iterator[List[int]]: yield from g() - yield from [1, 2, 3] # E: Incompatible types in "yield from" (actual type "int", expected type List[int]) + yield from [1, 2, 3] # E: Incompatible types in "yield from" (actual type "int", expected type "List[int]") [builtins fixtures/for.pyi] [out] @@ -1429,7 +1429,7 @@ y = 1 from typing import List bs, cs = None, None # type: List[A], List[B] *bs, b = bs -*bs, c = cs # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) +*bs, c = cs # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") *ns, c = cs nc = cs diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test index 08345706f0d9..ded930ae6d7e 100644 --- a/test-data/unit/check-tuples.test +++ b/test-data/unit/check-tuples.test @@ -91,7 +91,7 @@ from typing import Tuple t1 = None # type: Tuple[A, A] t2 = None # type: tuple -t1 = t2 # E: Incompatible types in assignment (expression has type Tuple[Any, ...], variable has type "Tuple[A, A]") +t1 = t2 # E: Incompatible types in assignment (expression has type "Tuple[Any, ...]", variable has type "Tuple[A, A]") t2 = t1 class A: pass @@ -388,7 +388,7 @@ aa, bb, *cc = t # E: Need type annotation for variable from typing import List li, lo = None, None # type: List[int], List[object] a, b, *c = 1, 2 # type: int, int, List[int] -c = lo # E: Incompatible types in assignment (expression has type List[object], variable has type List[int]) +c = lo # E: Incompatible types in assignment (expression has type "List[object]", variable has type "List[int]") c = li [builtins fixtures/list.pyi] @@ -450,14 +450,14 @@ class A: pass [out] main:6: error: List item 0 has incompatible type "A" main:6: error: List item 1 has incompatible type "A" -main:9: error: Incompatible types in assignment (expression has type "A", variable has type List[A]) +main:9: error: Incompatible types in assignment (expression has type "A", variable has type "List[A]") [case testAssignmentToStarFromTupleInference] from typing import List li = None # type: List[int] la = None # type: List[A] a, *l = A(), A() -l = li # E: Incompatible types in assignment (expression has type List[int], variable has type List[A]) +l = li # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[A]") l = la class A: pass @@ -469,7 +469,7 @@ from typing import List li = None # type: List[int] la = None # type: List[A] a, *l = [A(), A()] -l = li # E: Incompatible types in assignment (expression has type List[int], variable has type List[A]) +l = li # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[A]") l = la class A: pass @@ -482,7 +482,7 @@ li = None # type: List[int] la = None # type: List[A] ta = None # type: Tuple[A, A, A] a, *l = ta -l = li # E: Incompatible types in assignment (expression has type List[int], variable has type List[A]) +l = li # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[A]") l = la class A: pass @@ -494,7 +494,7 @@ from typing import List li = None # type: List[int] la = None # type: List[A] a, *l = la -l = li # E: Incompatible types in assignment (expression has type List[int], variable has type List[A]) +l = li # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[A]") l = la class A: pass @@ -579,7 +579,7 @@ class LongTypeName: def __add__(self, x: 'LongTypeName') -> 'LongTypeName': pass [builtins fixtures/tuple.pyi] [out] -main:3: error: Unsupported operand types for + ("LongTypeName" and tuple(length 50)) +main:3: error: Unsupported operand types for + ("LongTypeName" and "tuple(length 50)") -- Tuple methods @@ -750,7 +750,7 @@ tb = () # type: Tuple[B, ...] fa(ta) fa(tb) fb(tb) -fb(ta) # E: Argument 1 to "fb" has incompatible type Tuple[A, ...]; expected Tuple[B, ...] +fb(ta) # E: Argument 1 to "fb" has incompatible type "Tuple[A, ...]"; expected "Tuple[B, ...]" [builtins fixtures/tuple.pyi] [case testSubtypingFixedAndVariableLengthTuples] @@ -766,8 +766,8 @@ fa(aa) fa(ab) fa(bb) fb(bb) -fb(ab) # E: Argument 1 to "fb" has incompatible type "Tuple[A, B]"; expected Tuple[B, ...] -fb(aa) # E: Argument 1 to "fb" has incompatible type "Tuple[A, A]"; expected Tuple[B, ...] +fb(ab) # E: Argument 1 to "fb" has incompatible type "Tuple[A, B]"; expected "Tuple[B, ...]" +fb(aa) # E: Argument 1 to "fb" has incompatible type "Tuple[A, A]"; expected "Tuple[B, ...]" [builtins fixtures/tuple.pyi] [case testSubtypingTupleIsContainer] @@ -913,7 +913,7 @@ def f(a: Tuple) -> None: pass f(()) f((1,)) f(('', '')) -f(0) # E: Argument 1 to "f" has incompatible type "int"; expected Tuple[Any, ...] +f(0) # E: Argument 1 to "f" has incompatible type "int"; expected "Tuple[Any, ...]" [builtins fixtures/tuple.pyi] [case testTupleSingleton] diff --git a/test-data/unit/check-type-checks.test b/test-data/unit/check-type-checks.test index c4905a75ef78..dc3265238794 100644 --- a/test-data/unit/check-type-checks.test +++ b/test-data/unit/check-type-checks.test @@ -107,7 +107,7 @@ def f(x: object) -> None: if isinstance(x, C): x.f(1) x.f('') - x.g() # E: C[Any] has no attribute "g" + x.g() # E: "C[Any]" has no attribute "g" x.g() # E: "object" has no attribute "g" [builtins fixtures/isinstance.pyi] [out] diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 4714ec77f3dc..16010e5b9d1a 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -283,7 +283,7 @@ from mypy_extensions import TypedDict from typing import Mapping Point = TypedDict('Point', {'x': int, 'y': int}) def as_mapping(p: Point) -> Mapping[str, str]: - return p # E: Incompatible return value type (got "Point", expected Mapping[str, str]) + return p # E: Incompatible return value type (got "Point", expected "Mapping[str, str]") [builtins fixtures/dict.pyi] [case testTypedDictAcceptsIntForFloatDuckTypes] @@ -344,9 +344,9 @@ from mypy_extensions import TypedDict from typing import Dict, MutableMapping Point = TypedDict('Point', {'x': int, 'y': int}) def as_dict(p: Point) -> Dict[str, int]: - return p # E: Incompatible return value type (got "Point", expected Dict[str, int]) + return p # E: Incompatible return value type (got "Point", expected "Dict[str, int]") def as_mutable_mapping(p: Point) -> MutableMapping[str, int]: - return p # E: Incompatible return value type (got "Point", expected MutableMapping[str, int]) + return p # E: Incompatible return value type (got "Point", expected "MutableMapping[str, int]") [builtins fixtures/dict.pyi] [case testCanConvertTypedDictToAny] @@ -639,7 +639,7 @@ class C: A = TypedDict('A', {'x': int}) def g(self): A = TypedDict('A', {'y': int}) -C.A # E: Type[C] has no attribute "A" +C.A # E: "Type[C]" has no attribute "A" [builtins fixtures/dict.pyi] [case testTypedDictInFunction] diff --git a/test-data/unit/check-typevar-values.test b/test-data/unit/check-typevar-values.test index 36df2235a209..8dc6d32a55c1 100644 --- a/test-data/unit/check-typevar-values.test +++ b/test-data/unit/check-typevar-values.test @@ -270,7 +270,7 @@ y = C(S()) x = y y = x c_int = C(1) # type: C[int] -y = c_int # E: Incompatible types in assignment (expression has type C[int], variable has type C[str]) +y = c_int # E: Incompatible types in assignment (expression has type "C[int]", variable has type "C[str]") [case testGenericTypeBodyWithTypevarValues] from typing import TypeVar, Generic diff --git a/test-data/unit/check-unreachable-code.test b/test-data/unit/check-unreachable-code.test index 75e6f88c0c35..bbd538bc07ec 100644 --- a/test-data/unit/check-unreachable-code.test +++ b/test-data/unit/check-unreachable-code.test @@ -84,7 +84,7 @@ main:6: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" import typing MYPY = 0 if MYPY: - None + 1 # E: Unsupported left operand type for + (None) + None + 1 # E: Unsupported left operand type for + ("None") else: None + '' [builtins fixtures/bool.pyi] diff --git a/test-data/unit/check-varargs.test b/test-data/unit/check-varargs.test index 566841888693..802c6c8c8b86 100644 --- a/test-data/unit/check-varargs.test +++ b/test-data/unit/check-varargs.test @@ -10,8 +10,8 @@ from typing import Tuple def f( *b: 'B') -> None: ab = None # type: Tuple[B, ...] ac = None # type: Tuple[C, ...] - b = ac # E: Incompatible types in assignment (expression has type Tuple[C, ...], variable has type Tuple[B, ...]) - ac = b # E: Incompatible types in assignment (expression has type Tuple[B, ...], variable has type Tuple[C, ...]) + b = ac # E: Incompatible types in assignment (expression has type "Tuple[C, ...]", variable has type "Tuple[B, ...]") + ac = b # E: Incompatible types in assignment (expression has type "Tuple[B, ...]", variable has type "Tuple[C, ...]") b = ab ab = b @@ -108,7 +108,7 @@ it1 = None # type: Iterable[int] it2 = None # type: Iterable[str] def f(*x: int) -> None: pass f(*it1) -f(*it2) # E: Argument 1 to "f" has incompatible type *Iterable[str]; expected "int" +f(*it2) # E: Argument 1 to "f" has incompatible type *"Iterable[str]"; expected "int" [builtins fixtures/for.pyi] [case testCallVarargsFunctionWithIterableAndPositional] @@ -208,7 +208,7 @@ class A: pass class B: pass [builtins fixtures/list.pyi] [out] -main:7: error: Argument 1 to "f" has incompatible type *List[A]; expected "B" +main:7: error: Argument 1 to "f" has incompatible type *"List[A]"; expected "B" [case testCallingWithTupleVarArgs] @@ -277,13 +277,13 @@ class A: pass class B: pass [builtins fixtures/list.pyi] [out] -main:3: error: Argument 1 to "f" has incompatible type *List[A]; expected "B" -main:4: error: Argument 2 to "f" has incompatible type *List[A]; expected "B" +main:3: error: Argument 1 to "f" has incompatible type *"List[A]"; expected "B" +main:4: error: Argument 2 to "f" has incompatible type *"List[A]"; expected "B" main:5: error: Argument 1 to "f" has incompatible type "B"; expected "A" main:6: error: Argument 2 to "f" has incompatible type "A"; expected "B" -main:7: error: Argument 3 to "f" has incompatible type *List[A]; expected "B" +main:7: error: Argument 3 to "f" has incompatible type *"List[A]"; expected "B" main:8: error: Argument 1 to "f" has incompatible type "B"; expected "A" -main:9: error: Argument 1 to "g" has incompatible type *List[B]; expected "A" +main:9: error: Argument 1 to "g" has incompatible type *"List[B]"; expected "A" [case testCallingVarArgsFunctionWithTupleVarArgs] @@ -340,7 +340,7 @@ from typing import List aa = None # type: List[A] ab = None # type: List[B] -g(*aa) # E: Argument 1 to "g" has incompatible type *List[A]; expected "B" +g(*aa) # E: Argument 1 to "g" has incompatible type *"List[A]"; expected "B" f(*aa) f(*ab) g(*ab) @@ -377,8 +377,8 @@ class B: pass [builtins fixtures/list.pyi] [out] main:3: error: Too few arguments for "f" -main:4: error: Argument 2 to "f" has incompatible type *List[A]; expected "B" -main:5: error: Argument 3 to "f" has incompatible type *List[A]; expected "B" +main:4: error: Argument 2 to "f" has incompatible type *"List[A]"; expected "B" +main:5: error: Argument 3 to "f" has incompatible type *"List[A]"; expected "B" main:6: error: Argument 1 to "f" has incompatible type *"Tuple[A, A, B]"; expected "B" [case testVarArgsAfterKeywordArgInCall1-skip] @@ -491,11 +491,11 @@ class A: pass class B: pass [builtins fixtures/list.pyi] [out] -main:6: error: Argument 1 to "f" has incompatible type *List[A]; expected "B" -main:7: error: Argument 1 to "f" has incompatible type *List[A]; expected "B" +main:6: error: Argument 1 to "f" has incompatible type *"List[A]"; expected "B" +main:7: error: Argument 1 to "f" has incompatible type *"List[A]"; expected "B" main:8: error: Argument 1 to "f" has incompatible type "B"; expected "A" -main:9: error: Argument 2 to "f" has incompatible type *List[A]; expected "B" -main:10: error: Argument 3 to "f" has incompatible type *List[A]; expected "B" +main:9: error: Argument 2 to "f" has incompatible type *"List[A]"; expected "B" +main:10: error: Argument 3 to "f" has incompatible type *"List[A]"; expected "B" main:11: error: List or tuple expected as variable arguments main:12: error: List or tuple expected as variable arguments @@ -533,8 +533,8 @@ a, aa = G().f(*[a]) # Fail aa, a = G().f(*[a]) # Fail ab, aa = G().f(*[a]) # Fail -ao, ao = G().f(*[a]) # E: Incompatible types in assignment (expression has type List[], variable has type List[object]) -aa, aa = G().f(*[a]) # E: Incompatible types in assignment (expression has type List[], variable has type List[A]) +ao, ao = G().f(*[a]) # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[object]") +aa, aa = G().f(*[a]) # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") class G(Generic[T]): def f(self, *a: S) -> Tuple[List[S], List[T]]: @@ -544,11 +544,11 @@ class A: pass class B: pass [builtins fixtures/list.pyi] [out] -main:9: error: Incompatible types in assignment (expression has type List[A], variable has type "A") -main:9: error: Incompatible types in assignment (expression has type List[], variable has type List[A]) -main:10: error: Incompatible types in assignment (expression has type List[], variable has type "A") -main:11: error: Incompatible types in assignment (expression has type List[], variable has type List[A]) -main:11: error: Argument 1 to "f" of "G" has incompatible type *List[A]; expected "B" +main:9: error: Incompatible types in assignment (expression has type "List[A]", variable has type "A") +main:9: error: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") +main:10: error: Incompatible types in assignment (expression has type "List[]", variable has type "A") +main:11: error: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") +main:11: error: Argument 1 to "f" of "G" has incompatible type *"List[A]"; expected "B" -- Comment signatures From e134f8fd1fbb064cc8e3004d70db52940c03a613 Mon Sep 17 00:00:00 2001 From: Brian Weber Date: Tue, 23 May 2017 15:57:10 -0700 Subject: [PATCH 24/27] No quotes around Module --- mypy/messages.py | 3 +++ test-data/unit/check-ignore.test | 4 ++-- test-data/unit/check-incremental.test | 6 +++--- test-data/unit/check-modules.test | 16 ++++++++-------- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index 461f1800b4a2..e5cec939882b 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -242,6 +242,9 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: None -> None callable type -> "" (empty string) """ + ret = self._format_simple(typ, verbosity) + if ret == "Module": + return ret return '"{}"'.format(self._format_simple(typ, verbosity)) def _format_simple(self, typ: Type, verbosity: int = 0) -> str: diff --git a/test-data/unit/check-ignore.test b/test-data/unit/check-ignore.test index 5f2fd773a0c1..ad183ac1fe2b 100644 --- a/test-data/unit/check-ignore.test +++ b/test-data/unit/check-ignore.test @@ -46,7 +46,7 @@ import b # type: ignore reveal_type(a.foo) # E: Revealed type is 'Any' reveal_type(b.foo) # E: Revealed type is 'builtins.int' a.bar() -b.bar() # E: "Module" has no attribute "bar" +b.bar() # E: Module has no attribute "bar" [file b.py] foo = 3 @@ -76,7 +76,7 @@ class B(A): import m m.x = object # type: ignore m.f() # type: ignore -m.y # E: "Module" has no attribute "y" +m.y # E: Module has no attribute "y" [file m.py] [builtins fixtures/module.pyi] diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 78da587098ec..23fafc24edf5 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -325,7 +325,7 @@ const = 3 [stale mod3] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: "Module" has no attribute "mod4" +tmp/mod1.py:3: error: Module has no attribute "mod4" [case testIncrementalLongBrokenCascade] import mod1 @@ -360,7 +360,7 @@ const = 3 [stale mod6] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: "Module" has no attribute "mod7" +tmp/mod1.py:3: error: Module has no attribute "mod7" [case testIncrementalNestedBrokenCascade] import mod1 @@ -386,7 +386,7 @@ const = 3 [stale mod2.mod3] [builtins fixtures/module.pyi] [out2] -tmp/mod1.py:3: error: "Module" has no attribute "mod4" +tmp/mod1.py:3: error: Module has no attribute "mod4" [case testIncrementalNestedBrokenCascadeWithType1] import mod1, mod2.mod3.mod5 diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test index 10c6a22680d6..423994ad981b 100644 --- a/test-data/unit/check-modules.test +++ b/test-data/unit/check-modules.test @@ -155,16 +155,16 @@ import m import typing class A: pass -m() # E: "Module" not callable -a = m # type: A # E: Incompatible types in assignment (expression has type "Module", variable has type "A") -m + None # E: Unsupported left operand type for + ("Module") +m() # E: Module not callable +a = m # type: A # E: Incompatible types in assignment (expression has type Module, variable has type "A") +m + None # E: Unsupported left operand type for + (Module) [file m.py] [builtins fixtures/module.pyi] [case testNameDefinedInDifferentModule] import m, n import typing -m.x # E: "Module" has no attribute "x" +m.x # E: Module has no attribute "x" [file m.py] y = object() [file n.py] @@ -330,7 +330,7 @@ import nonexistent [out] tmp/x.py:1: error: Cannot find module named 'nonexistent' tmp/x.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help) -main:3: error: "Module" has no attribute "z" +main:3: error: Module has no attribute "z" [case testUnknownModuleImportedWithinFunction] def f(): @@ -648,7 +648,7 @@ def f(x: str) -> None: pass if object(): import m else: - m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Module") + m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type Module) [file m.py] [builtins fixtures/module.pyi] [out] @@ -752,7 +752,7 @@ value = 3.2 [case testSubmoduleImportFromDoesNotAddParents] from a import b reveal_type(b.value) # E: Revealed type is 'builtins.str' -b.c.value # E: "Module" has no attribute "c" +b.c.value # E: Module has no attribute "c" a.value # E: Name 'a' is not defined [file a/__init__.py] @@ -853,7 +853,7 @@ bar = parent.unrelated.ShouldNotLoad() [builtins fixtures/module.pyi] [out] tmp/parent/child.py:8: error: Revealed type is 'parent.common.SomeClass' -tmp/parent/child.py:9: error: "Module" has no attribute "unrelated" +tmp/parent/child.py:9: error: Module has no attribute "unrelated" [case testSubmoduleMixingImportFromAndImport2] import parent.child From 60231def498f1c2cecbc71a5fb041fd283626a47 Mon Sep 17 00:00:00 2001 From: Brian Weber Date: Tue, 23 May 2017 16:53:16 -0700 Subject: [PATCH 25/27] And even more tests that need to be updated --- test-data/unit/check-functions.test | 24 ++++++++++----------- test-data/unit/check-optional.test | 4 ++-- test-data/unit/pythoneval-asyncio.test | 8 +++---- test-data/unit/pythoneval.test | 30 +++++++++++++++----------- typeshed | 2 +- 5 files changed, 36 insertions(+), 32 deletions(-) diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 3bd2de532384..be43f47b3689 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -2072,23 +2072,23 @@ def fn( from typing import Union, Dict, List def f() -> List[Union[str, int]]: x = ['a'] - return x # E: Incompatible return value type (got List[str], expected List[Union[str, int]]) \ -# N: Perhaps you need a type annotation for "x"? Suggestion: List[Union[str, int]] + return x # E: Incompatible return value type (got "List[str]", expected "List[Union[str, int]]") \ +# N: Perhaps you need a type annotation for "x"? Suggestion: "List[Union[str, int]]" def g() -> Dict[str, Union[str, int]]: x = {'a': 'a'} - return x # E: Incompatible return value type (got Dict[str, str], expected Dict[str, Union[str, int]]) \ -# N: Perhaps you need a type annotation for "x"? Suggestion: Dict[str, Union[str, int]] + return x # E: Incompatible return value type (got "Dict[str, str]", expected "Dict[str, Union[str, int]]") \ +# N: Perhaps you need a type annotation for "x"? Suggestion: "Dict[str, Union[str, int]]" def h() -> Dict[Union[str, int], str]: x = {'a': 'a'} - return x # E: Incompatible return value type (got Dict[str, str], expected Dict[Union[str, int], str]) \ -# N: Perhaps you need a type annotation for "x"? Suggestion: Dict[Union[str, int], str] + return x # E: Incompatible return value type (got "Dict[str, str]", expected "Dict[Union[str, int], str]") \ +# N: Perhaps you need a type annotation for "x"? Suggestion: "Dict[Union[str, int], str]" def i() -> List[Union[int, float]]: x: List[int] = [1] - return x # E: Incompatible return value type (got List[int], expected List[Union[int, float]]) \ -# N: Perhaps you need a type annotation for "x"? Suggestion: List[Union[int, float]] + return x # E: Incompatible return value type (got "List[int]", expected "List[Union[int, float]]") \ +# N: Perhaps you need a type annotation for "x"? Suggestion: "List[Union[int, float]]" [builtins fixtures/dict.pyi] @@ -2096,11 +2096,11 @@ def i() -> List[Union[int, float]]: from typing import Union, List def f() -> List[Union[int, float]]: x = ['a'] - return x # E: Incompatible return value type (got List[str], expected List[Union[int, float]]) + return x # E: Incompatible return value type (got "List[str]", expected "List[Union[int, float]]") def g() -> List[Union[str, int]]: x = ('a', 2) - return x # E: Incompatible return value type (got "Tuple[str, int]", expected List[Union[str, int]]) + return x # E: Incompatible return value type (got "Tuple[str, int]", expected "List[Union[str, int]]") [builtins fixtures/list.pyi] @@ -2108,7 +2108,7 @@ def g() -> List[Union[str, int]]: from typing import Union, Dict, List def f() -> Dict[str, Union[str, int]]: x = {'a': 'a', 'b': 2} - return x # E: Incompatible return value type (got Dict[str, object], expected Dict[str, Union[str, int]]) + return x # E: Incompatible return value type (got "Dict[str, object]", expected "Dict[str, Union[str, int]]") def g() -> Dict[str, Union[str, int]]: x: Dict[str, Union[str, int]] = {'a': 'a', 'b': 2} @@ -2116,7 +2116,7 @@ def g() -> Dict[str, Union[str, int]]: def h() -> List[Union[str, int]]: x = ['a', 2] - return x # E: Incompatible return value type (got List[object], expected List[Union[str, int]]) + return x # E: Incompatible return value type (got "List[object]", expected "List[Union[str, int]]") def i() -> List[Union[str, int]]: x: List[Union[str, int]] = ['a', 2] diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index 3b3f688f1801..c7920962a825 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -127,7 +127,7 @@ f(None) [case testNoInferOptionalFromDefaultNone] # flags: --no-implicit-optional -def f(x: int = None) -> None: # E: Incompatible types in assignment (expression has type None, variable has type "int") +def f(x: int = None) -> None: # E: Incompatible types in assignment (expression has type "None", variable has type "int") pass [out] @@ -140,7 +140,7 @@ f(None) [case testNoInferOptionalFromDefaultNoneComment] # flags: --no-implicit-optional -def f(x=None): # E: Incompatible types in assignment (expression has type None, variable has type "int") +def f(x=None): # E: Incompatible types in assignment (expression has type "None", variable has type "int") # type: (int) -> None pass [out] diff --git a/test-data/unit/pythoneval-asyncio.test b/test-data/unit/pythoneval-asyncio.test index 6d1690339ff7..114cd4b9cb66 100644 --- a/test-data/unit/pythoneval-asyncio.test +++ b/test-data/unit/pythoneval-asyncio.test @@ -339,7 +339,7 @@ loop.run_until_complete(future) print(future.result()) loop.close() [out] -_program.py:12: error: Argument 1 to "slow_operation" has incompatible type Future[str]; expected Future[int] +_program.py:12: error: Argument 1 to "slow_operation" has incompatible type "Future[str]"; expected "Future[int]" [case testErrorUsingDifferentFutureTypeAndSetFutureDifferentInternalType] from typing import Generator, Any @@ -359,7 +359,7 @@ print(future.result()) loop.close() [out] _program.py:8: error: Argument 1 to "set_result" of "Future" has incompatible type "str"; expected "int" -_program.py:12: error: Argument 1 to "slow_operation" has incompatible type Future[str]; expected Future[int] +_program.py:12: error: Argument 1 to "slow_operation" has incompatible type "Future[str]"; expected "Future[int]" [case testErrorSettingCallbackWithDifferentFutureType] import typing @@ -422,7 +422,7 @@ loop = asyncio.get_event_loop() loop.run_until_complete(h()) loop.close() [out] -_program.py:18: error: Incompatible return value type (got Future[Future[int]], expected Future[Future[Future[int]]]) +_program.py:18: error: Incompatible return value type (got "Future[Future[int]]", expected "Future[Future[Future[int]]]") [case testErrorOneLessFutureInReturnType] import typing @@ -456,7 +456,7 @@ loop = asyncio.get_event_loop() loop.run_until_complete(h()) loop.close() [out] -_program.py:18: error: Incompatible return value type (got Future[Future[int]], expected Future[int]) +_program.py:18: error: Incompatible return value type (got "Future[Future[int]]", expected "Future[int]") [case testErrorAssignmentDifferentType] import typing diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index be05dafe20c8..ac2461906758 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -391,7 +391,7 @@ txt(sys.stdout) bin(sys.stdout) [out] _program.py:5: error: Argument 1 to "write" of "IO" has incompatible type "bytes"; expected "str" -_program.py:10: error: Argument 1 to "bin" has incompatible type "TextIO"; expected IO[bytes] +_program.py:10: error: Argument 1 to "bin" has incompatible type "TextIO"; expected "IO[bytes]" [case testBuiltinOpen] f = open('x') @@ -399,6 +399,7 @@ f.write('x') f.write(b'x') f.foobar() [out] +<<<<<<< e134f8fd1fbb064cc8e3004d70db52940c03a613 _program.py:3: error: Argument 1 to "write" of "IO" has incompatible type "bytes"; expected "str" _program.py:4: error: IO[str] has no attribute "foobar" @@ -426,6 +427,9 @@ _testOpenReturnTypeInferenceSpecialCases.py:1: error: Too few arguments for "ope _testOpenReturnTypeInferenceSpecialCases.py:2: error: Revealed type is 'typing.IO[builtins.bytes]' _testOpenReturnTypeInferenceSpecialCases.py:3: error: Revealed type is 'typing.IO[builtins.bytes]' _testOpenReturnTypeInferenceSpecialCases.py:5: error: Revealed type is 'typing.IO[Any]' +======= +_program.py:4: error: "IO[Any]" has no attribute "foobar" +>>>>>>> And even more tests that need to be updated [case testGenericPatterns] from typing import Pattern @@ -603,7 +607,7 @@ print(tuple(a)) import typing [1] + iter([2, 3]) [out] -_program.py:2: error: Unsupported operand types for + (List[int] and Iterator[int]) +_program.py:2: error: Unsupported operand types for + ("List[int]" and "Iterator[int]") [case testInferHeterogeneousListOfIterables] from typing import Sequence @@ -792,7 +796,7 @@ x = range(3) a = list(map(str, x)) a + 1 [out] -_program.py:4: error: Unsupported operand types for + (List[str] and "int") +_program.py:4: error: Unsupported operand types for + ("List[str]" and "int") [case testNamedTuple] import typing @@ -994,7 +998,7 @@ def f(*x: int) -> None: x.append(1) f(1) [out] -_program.py:3: error: Tuple[int, ...] has no attribute "append" +_program.py:3: error: "Tuple[int, ...]" has no attribute "append" [case testExit] print('a') @@ -1075,14 +1079,14 @@ n = 4 t = ('',) * n t + 1 [out] -_program.py:3: error: Unsupported operand types for + (Tuple[str, ...] and "int") +_program.py:3: error: Unsupported operand types for + ("Tuple[str, ...]" and "int") [case testMultiplyTupleByIntegerReverse] n = 4 t = n * ('',) t + 1 [out] -_program.py:3: error: Unsupported operand types for + (Tuple[str, ...] and "int") +_program.py:3: error: Unsupported operand types for + ("Tuple[str, ...]" and "int") [case testDictWithKeywordArgs] from typing import Dict, Any, List @@ -1094,7 +1098,7 @@ d4 = dict(a=1, b='') # type: Dict[str, Any] result = dict(x=[], y=[]) # type: Dict[str, List[str]] [out] _program.py:3: error: Dict entry 1 has incompatible type "str": "str" -_program.py:5: error: Dict[str, int] has no attribute "xyz" +_program.py:5: error: "Dict[str, int]" has no attribute "xyz" [case testDefaultDict] import typing as t @@ -1122,11 +1126,11 @@ class MyDDict(t.DefaultDict[int,T], t.Generic[T]): MyDDict(dict)['0'] MyDDict(dict)[0] [out] -_program.py:6: error: Argument 1 to "defaultdict" has incompatible type Type[List[Any]]; expected Callable[[], str] -_program.py:9: error: Invalid index type "str" for defaultdict[int, str]; expected type "int" +_program.py:6: error: Argument 1 to "defaultdict" has incompatible type "Type[List[Any]]"; expected Callable[[], str] +_program.py:9: error: Invalid index type "str" for "defaultdict[int, str]"; expected type "int" _program.py:9: error: Incompatible types in assignment (expression has type "int", target has type "str") -_program.py:19: error: Dict entry 0 has incompatible type "str": List[] -_program.py:23: error: Invalid index type "str" for MyDDict[Dict[_KT, _VT]]; expected type "int" +_program.py:19: error: Dict entry 0 has incompatible type "str": "List[]" +_program.py:23: error: Invalid index type "str" for "MyDDict[Dict[_KT, _VT]]"; expected type "int" [case testNoSubcriptionOfStdlibCollections] import collections @@ -1148,7 +1152,7 @@ def f(d: collections.defaultdict[int, str]) -> None: _program.py:5: error: "defaultdict" is not subscriptable _program.py:6: error: "Counter" is not subscriptable _program.py:9: error: "defaultdict" is not subscriptable -_program.py:12: error: Invalid index type "int" for defaultdict[str, int]; expected type "str" +_program.py:12: error: Invalid index type "int" for "defaultdict[str, int]"; expected type "str" _program.py:14: error: "defaultdict" is not subscriptable, use "typing.DefaultDict" instead [case testCollectionsAliases] @@ -1176,7 +1180,7 @@ reveal_type(o6) [out] _testCollectionsAliases.py:5: error: Revealed type is 'collections.Counter[builtins.int]' -_testCollectionsAliases.py:6: error: Invalid index type "str" for Counter[int]; expected type "int" +_testCollectionsAliases.py:6: error: Invalid index type "str" for "Counter[int]"; expected type "int" _testCollectionsAliases.py:9: error: Revealed type is 'collections.ChainMap[builtins.int, builtins.str]' _testCollectionsAliases.py:12: error: Revealed type is 'collections.deque[builtins.int]' _testCollectionsAliases.py:15: error: Revealed type is 'collections.Counter[builtins.int*]' diff --git a/typeshed b/typeshed index c1b7fc70203c..c2e6a6f670f5 160000 --- a/typeshed +++ b/typeshed @@ -1 +1 @@ -Subproject commit c1b7fc70203c4b92577f1f4765e0fdb654a8886c +Subproject commit c2e6a6f670f5d75c07eb31cf2509db302825b76d From 735778e85b94335306b654e774f79ffcc97d6a37 Mon Sep 17 00:00:00 2001 From: Brian Weber Date: Tue, 23 May 2017 21:40:53 -0700 Subject: [PATCH 26/27] incorrect indentation --- mypy/messages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/messages.py b/mypy/messages.py index e5cec939882b..1ac7428a4ea9 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -244,7 +244,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: """ ret = self._format_simple(typ, verbosity) if ret == "Module": - return ret + return ret return '"{}"'.format(self._format_simple(typ, verbosity)) def _format_simple(self, typ: Type, verbosity: int = 0) -> str: From 5922be3fb1e4f23e206bd3dc0f2ee2acc85f2250 Mon Sep 17 00:00:00 2001 From: Brian Weber Date: Tue, 30 May 2017 11:41:38 -0700 Subject: [PATCH 27/27] update tests & merge conflicts --- test-data/unit/pythoneval.test | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index ac2461906758..efbe9eb7b831 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -399,9 +399,8 @@ f.write('x') f.write(b'x') f.foobar() [out] -<<<<<<< e134f8fd1fbb064cc8e3004d70db52940c03a613 _program.py:3: error: Argument 1 to "write" of "IO" has incompatible type "bytes"; expected "str" -_program.py:4: error: IO[str] has no attribute "foobar" +_program.py:4: error: "IO[str]" has no attribute "foobar" [case testOpenReturnTypeInference] reveal_type(open('x')) @@ -427,9 +426,6 @@ _testOpenReturnTypeInferenceSpecialCases.py:1: error: Too few arguments for "ope _testOpenReturnTypeInferenceSpecialCases.py:2: error: Revealed type is 'typing.IO[builtins.bytes]' _testOpenReturnTypeInferenceSpecialCases.py:3: error: Revealed type is 'typing.IO[builtins.bytes]' _testOpenReturnTypeInferenceSpecialCases.py:5: error: Revealed type is 'typing.IO[Any]' -======= -_program.py:4: error: "IO[Any]" has no attribute "foobar" ->>>>>>> And even more tests that need to be updated [case testGenericPatterns] from typing import Pattern