blob: 426a3c04869bd7a58538cf63cd34b2f16bd6e822 [file] [log] [blame]
-- Checks NewType(...)
-- Checks for basic functionality
[case testNewTypePEP484Example1]
from typing import NewType
UserId = NewType('UserId', int)
def name_by_id(user_id: UserId) -> str:
return "foo"
UserId('user') # E: Argument 1 to "UserId" has incompatible type "str"; expected "int"
name_by_id(42) # E: Argument 1 to "name_by_id" has incompatible type "int"; expected "UserId"
name_by_id(UserId(42))
id = UserId(5)
num = id + 1
reveal_type(id) # N: Revealed type is "__main__.UserId"
reveal_type(num) # N: Revealed type is "builtins.int"
[targets __main__, __main__.UserId.__init__, __main__.name_by_id]
[case testNewTypePEP484Example2]
from typing import NewType
class PacketId:
def __init__(self, major: int, minor: int) -> None:
self._major = major
self._minor = minor
TcpPacketId = NewType('TcpPacketId', PacketId)
packet = PacketId(100, 100)
tcp_packet = TcpPacketId(packet)
tcp_packet = TcpPacketId(127, 0)
[out]
main:12: error: Too many arguments for "TcpPacketId"
main:12: error: Argument 1 to "TcpPacketId" has incompatible type "int"; expected "PacketId"
[case testNewTypeWithTuples]
from typing import NewType, Tuple
TwoTuple = NewType('TwoTuple', Tuple[int, str])
a = TwoTuple((3, "a"))
b = TwoTuple(("a", 3)) # E: Argument 1 to "TwoTuple" has incompatible type "Tuple[str, int]"; expected "Tuple[int, str]"
reveal_type(a[0]) # N: Revealed type is "builtins.int"
reveal_type(a[1]) # N: Revealed type is "builtins.str"
[builtins fixtures/tuple.pyi]
[out]
[case testNewTypeWithLists]
from typing import NewType, List
UserId = NewType('UserId', int)
IdList = NewType('IdList', List[UserId])
bad1 = IdList([1]) # E: List item 0 has incompatible type "int"; expected "UserId"
foo = IdList([])
foo.append(3) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "UserId"
foo.append(UserId(3))
foo.extend([UserId(1), UserId(2), UserId(3)])
foo.extend(IdList([UserId(1), UserId(2), UserId(3)]))
bar = IdList([UserId(2)])
baz = foo + bar
reveal_type(foo) # N: Revealed type is "__main__.IdList"
reveal_type(bar) # N: Revealed type is "__main__.IdList"
reveal_type(baz) # N: Revealed type is "builtins.list[__main__.UserId]"
[builtins fixtures/list.pyi]
[out]
[case testNewTypeWithGenerics]
from typing import TypeVar, Generic, NewType, Any
T = TypeVar('T')
class Base(Generic[T]):
def __init__(self, item: T) -> None:
self.item = item
def getter(self) -> T:
return self.item
Derived1 = NewType('Derived1', Base[str])
Derived2 = NewType('Derived2', Base) # Implicit 'Any'
Derived3 = NewType('Derived3', Base[Any]) # Explicit 'Any'
Derived1(Base(1)) # E: Argument 1 to "Base" has incompatible type "int"; expected "str"
Derived1(Base('a'))
Derived2(Base(1))
Derived2(Base('a'))
Derived3(Base(1))
Derived3(Base('a'))
reveal_type(Derived1(Base('a')).getter()) # N: Revealed type is "builtins.str"
reveal_type(Derived3(Base('a')).getter()) # N: Revealed type is "Any"
[out]
[case testNewTypeWithNamedTuple]
from collections import namedtuple
from typing import NewType, NamedTuple
Vector1 = namedtuple('Vector1', ['x', 'y'])
Point1 = NewType('Point1', Vector1)
p1 = Point1(Vector1(1, 2))
reveal_type(p1.x) # N: Revealed type is "Any"
reveal_type(p1.y) # N: Revealed type is "Any"
Vector2 = NamedTuple('Vector2', [('x', int), ('y', int)])
Point2 = NewType('Point2', Vector2)
p2 = Point2(Vector2(1, 2))
reveal_type(p2.x) # N: Revealed type is "builtins.int"
reveal_type(p2.y) # N: Revealed type is "builtins.int"
class Vector3:
def __init__(self, x: int, y: int) -> None:
self.x = x
self.y = y
Point3 = NewType('Point3', Vector3)
p3 = Point3(Vector3(1, 3))
reveal_type(p3.x) # N: Revealed type is "builtins.int"
reveal_type(p3.y) # N: Revealed type is "builtins.int"
[builtins fixtures/list.pyi]
[out]
[case testNewTypeWithCasts]
from typing import NewType, cast
UserId = NewType('UserId', int)
foo = UserId(3)
foo = cast(UserId, 3)
foo = cast(UserId, "foo")
foo = cast(UserId, UserId(4))
[out]
[case testNewTypeWithTypeAliases]
from typing import NewType
Foo = int
Bar = NewType('Bar', Foo)
Bar2 = Bar
def func1(x: Foo) -> Bar:
return Bar(x)
def func2(x: int) -> Bar:
return Bar(x)
def func3(x: Bar2) -> Bar:
return x
x = Bar(42)
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
[case testNewTypeInLocalScope]
from typing import NewType
A = NewType('A', int)
a = A(3)
def func() -> None:
A = NewType('A', str)
B = NewType('B', str)
a = A(3) # E: Argument 1 to "A@6" has incompatible type "int"; expected "str"
a = A('xyz')
b = B('xyz')
class MyClass:
C = NewType('C', float)
def foo(self) -> 'MyClass.C':
return MyClass.C(3.2)
b = A(3)
c = MyClass.C(3.5)
[out]
[case testNewTypeInMultipleFiles]
import a
import b
list1 = [a.UserId(1), a.UserId(2)]
list1.append(b.UserId(3)) # E: Argument 1 to "append" of "list" has incompatible type "b.UserId"; expected "a.UserId"
[file a.py]
from typing import NewType
UserId = NewType('UserId', int)
[file b.py]
from typing import NewType
UserId = NewType('UserId', int)
[builtins fixtures/list.pyi]
[out]
[case testNewTypeWithIncremental]
import m
[file m.py]
from typing import NewType
UserId = NewType('UserId', int)
def name_by_id(user_id: UserId) -> str:
return "foo"
name_by_id(UserId(42))
id = UserId(5)
num = id + 1
[file m.py.2]
from typing import NewType
UserId = NewType('UserId', int)
def name_by_id(user_id: UserId) -> str:
return "foo"
name_by_id(UserId(42))
id = UserId(5)
num = id + 1
reveal_type(id)
reveal_type(num)
[rechecked m]
[stale]
[out1]
[out2]
tmp/m.py:13: note: Revealed type is "m.UserId"
tmp/m.py:14: note: Revealed type is "builtins.int"
-- Check misuses of NewType fail
[case testNewTypeBadInitializationFails]
from typing import NewType
a = NewType('b', int) # E: String argument 1 "b" to NewType(...) does not match variable name "a"
b = NewType('b', 3) # E: Argument 2 to NewType(...) must be a valid type
c = NewType(2, int) # E: Argument 1 to NewType(...) must be a string literal
foo = "d"
d = NewType(foo, int) # E: Argument 1 to NewType(...) must be a string literal
e = NewType(name='e', tp=int) # E: NewType(...) expects exactly two positional arguments
f = NewType('f', tp=int) # E: NewType(...) expects exactly two positional arguments
[out]
[case testNewTypeWithAnyFails]
from typing import NewType, Any
A = NewType('A', Any) # E: Argument 2 to NewType(...) must be subclassable (got "Any")
[out]
[case testNewTypeWithUnionsFails]
from typing import NewType, Union
Foo = NewType('Foo', Union[int, float]) # E: Argument 2 to NewType(...) must be subclassable (got "Union[int, float]")
[out]
[case testNewTypeWithTypeTypeFails]
from typing import NewType, Type
Foo = NewType('Foo', Type[int]) # E: Argument 2 to NewType(...) must be subclassable (got "Type[int]")
a = Foo(type(3))
[builtins fixtures/args.pyi]
[out]
[case testNewTypeWithTypeVarsFails]
from typing import NewType, TypeVar, List
T = TypeVar('T')
A = NewType('A', T)
B = NewType('B', List[T])
[builtins fixtures/list.pyi]
[out]
main:4: error: Argument 2 to NewType(...) must be subclassable (got T?)
main:4: error: Type variable "__main__.T" is unbound
main:4: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
main:4: note: (Hint: Use "T" in function signature to bind "T" inside a function)
main:5: error: Type variable "__main__.T" is unbound
main:5: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
main:5: note: (Hint: Use "T" in function signature to bind "T" inside a function)
[case testNewTypeRedefiningVariablesFails]
from typing import NewType
a = 3
def f(): a
a = NewType('a', int) # E: Cannot redefine "a" as a NewType \
# E: Name "a" already defined on line 4
b = NewType('b', int)
def g(): b
b = NewType('b', float) # E: Cannot redefine "b" as a NewType \
# E: Name "b" already defined on line 8
c = NewType('c', str) # type: str # E: Cannot declare the type of a NewType declaration
[case testNewTypeAddingExplicitTypesFails]
from typing import NewType
UserId = NewType('UserId', int)
a = 3 # type: UserId # E: Incompatible types in assignment (expression has type "int", variable has type "UserId")
[out]
[case testNewTypeTestSubclassingFails]
from typing import NewType
class A: pass
B = NewType('B', A)
class C(B): pass # E: Cannot subclass "NewType"
[out]
[case testCannotUseNewTypeWithProtocols]
from typing import Protocol, NewType
class P(Protocol):
attr: int = 0
class D:
attr: int
C = NewType('C', P) # E: NewType cannot be used with protocol classes
x: C = C(D()) # We still accept this, treating 'C' as non-protocol subclass.
reveal_type(x.attr) # N: Revealed type is "builtins.int"
x.bad_attr # E: "C" has no attribute "bad_attr"
C(1) # E: Argument 1 to "C" has incompatible type "int"; expected "P"
[out]
[case testNewTypeAny]
from typing import NewType
Any = NewType('Any', int)
Any(5)
[case testNewTypeWithIsInstanceAndIsSubclass]
from typing import NewType
T = NewType('T', int)
d: object
if isinstance(d, T): # E: Cannot use isinstance() with NewType type
reveal_type(d) # N: Revealed type is "__main__.T"
issubclass(object, T) # E: Cannot use issubclass() with NewType type
[builtins fixtures/isinstancelist.pyi]
[case testInvalidNewTypeCrash]
from typing import List, NewType, Union
N = NewType('N', XXX) # E: Argument 2 to NewType(...) must be subclassable (got "Any") \
# E: Name "XXX" is not defined
x: List[Union[N, int]]
[builtins fixtures/list.pyi]