blob: 3a5e68c90ed5030d305eae38edc428fed13f58df [file] [log] [blame]
[case testDataclassesBasic]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
def summary(self):
return "%s is %d years old." % (self.name, self.age)
reveal_type(Person) # N: Revealed type is 'def (name: builtins.str, age: builtins.int) -> __main__.Person'
Person('John', 32)
Person('Jonh', 21, None) # E: Too many arguments for "Person"
[builtins fixtures/list.pyi]
[case testDataclassesCustomInit]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class A:
a: int
def __init__(self, a: str) -> None:
pass
A('1')
[builtins fixtures/list.pyi]
[case testDataclassesBasicInheritance]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class Mammal:
age: int
@dataclass
class Person(Mammal):
name: str
def summary(self):
return "%s is %d years old." % (self.name, self.age)
reveal_type(Person) # N: Revealed type is 'def (age: builtins.int, name: builtins.str) -> __main__.Person'
Mammal(10)
Person(32, 'John')
Person(21, 'Jonh', None) # E: Too many arguments for "Person"
[builtins fixtures/list.pyi]
[case testDataclassesDeepInheritance]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class A:
a: int
@dataclass
class B(A):
b: int
@dataclass
class C(B):
c: int
@dataclass
class D(C):
d: int
reveal_type(A) # N: Revealed type is 'def (a: builtins.int) -> __main__.A'
reveal_type(B) # N: Revealed type is 'def (a: builtins.int, b: builtins.int) -> __main__.B'
reveal_type(C) # N: Revealed type is 'def (a: builtins.int, b: builtins.int, c: builtins.int) -> __main__.C'
reveal_type(D) # N: Revealed type is 'def (a: builtins.int, b: builtins.int, c: builtins.int, d: builtins.int) -> __main__.D'
[builtins fixtures/list.pyi]
[case testDataclassesOverriding]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class Mammal:
age: int
@dataclass
class Person(Mammal):
name: str
age: int
@dataclass
class SpecialPerson(Person):
special_factor: float
@dataclass
class ExtraSpecialPerson(SpecialPerson):
age: int
special_factor: float
name: str
reveal_type(Person) # N: Revealed type is 'def (age: builtins.int, name: builtins.str) -> __main__.Person'
reveal_type(SpecialPerson) # N: Revealed type is 'def (age: builtins.int, name: builtins.str, special_factor: builtins.float) -> __main__.SpecialPerson'
reveal_type(ExtraSpecialPerson) # N: Revealed type is 'def (age: builtins.int, name: builtins.str, special_factor: builtins.float) -> __main__.ExtraSpecialPerson'
Person(32, 'John')
Person(21, 'John', None) # E: Too many arguments for "Person"
SpecialPerson(21, 'John', 0.5)
ExtraSpecialPerson(21, 'John', 0.5)
[builtins fixtures/list.pyi]
[case testDataclassesOverridingWithDefaults]
# Issue #5681 https://github.com/python/mypy/issues/5681
# flags: --python-version 3.6
from dataclasses import dataclass
from typing import Any
@dataclass
class Base:
some_int: Any
some_str: str = 'foo'
@dataclass
class C(Base):
some_int: int
reveal_type(C) # N: Revealed type is 'def (some_int: builtins.int, some_str: builtins.str =) -> __main__.C'
[builtins fixtures/list.pyi]
[case testDataclassesFreezing]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass(frozen=True)
class Person:
name: str
john = Person('John')
john.name = 'Ben' # E: Property "name" defined in "Person" is read-only
[builtins fixtures/list.pyi]
[case testDataclassesFields]
# flags: --python-version 3.6
from dataclasses import dataclass, field
@dataclass
class Person:
name: str
age: int = field(default=0, init=False)
reveal_type(Person) # N: Revealed type is 'def (name: builtins.str) -> __main__.Person'
john = Person('John')
john.age = 'invalid' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
john.age = 24
[builtins fixtures/list.pyi]
[case testDataclassesBadInit]
# flags: --python-version 3.6
from dataclasses import dataclass, field
@dataclass
class Person:
name: str
age: int = field(init=None) # E: No overload variant of "field" matches argument type "None" \
# N: Possible overload variant: \
# N: def field(*, init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ...) -> Any \
# N: <2 more non-matching overloads not shown>
[builtins fixtures/list.pyi]
[case testDataclassesMultiInit]
# flags: --python-version 3.6
from dataclasses import dataclass, field
from typing import List
@dataclass
class Person:
name: str
age: int = field(init=False)
friend_names: List[str] = field(init=True)
enemy_names: List[str]
reveal_type(Person) # N: Revealed type is 'def (name: builtins.str, friend_names: builtins.list[builtins.str], enemy_names: builtins.list[builtins.str]) -> __main__.Person'
[builtins fixtures/list.pyi]
[case testDataclassesMultiInitDefaults]
# flags: --python-version 3.6
from dataclasses import dataclass, field
from typing import List, Optional
@dataclass
class Person:
name: str
age: int = field(init=False)
friend_names: List[str] = field(init=True)
enemy_names: List[str]
nickname: Optional[str] = None
reveal_type(Person) # N: Revealed type is 'def (name: builtins.str, friend_names: builtins.list[builtins.str], enemy_names: builtins.list[builtins.str], nickname: Union[builtins.str, None] =) -> __main__.Person'
[builtins fixtures/list.pyi]
[case testDataclassesDefaults]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class Application:
name: str = 'Unnamed'
rating: int = 0
reveal_type(Application) # N: Revealed type is 'def (name: builtins.str =, rating: builtins.int =) -> __main__.Application'
app = Application()
[builtins fixtures/list.pyi]
[case testDataclassesDefaultFactories]
# flags: --python-version 3.6
from dataclasses import dataclass, field
@dataclass
class Application:
name: str = 'Unnamed'
rating: int = field(default_factory=int)
rating_count: int = field() # E: Attributes without a default cannot follow attributes with one
[builtins fixtures/list.pyi]
[case testDataclassesDefaultFactoryTypeChecking]
# flags: --python-version 3.6
from dataclasses import dataclass, field
@dataclass
class Application:
name: str = 'Unnamed'
rating: int = field(default_factory=str) # E: Incompatible types in assignment (expression has type "str", variable has type "int")
[builtins fixtures/list.pyi]
[case testDataclassesDefaultOrdering]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class Application:
name: str = 'Unnamed'
rating: int # E: Attributes without a default cannot follow attributes with one
[builtins fixtures/list.pyi]
[case testDataclassesClassmethods]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class Application:
name: str
@classmethod
def parse(cls, request: str) -> "Application":
return cls(name='...')
app = Application.parse('')
[builtins fixtures/list.pyi]
[builtins fixtures/classmethod.pyi]
[case testDataclassesOverloadsAndClassmethods]
# flags: --python-version 3.6
from dataclasses import dataclass
from typing import overload, Union
@dataclass
class A:
a: int
b: str
@classmethod
def other(cls) -> str:
return "..."
@overload
@classmethod
def foo(cls, x: int) -> int: ...
@overload
@classmethod
def foo(cls, x: str) -> str: ...
@classmethod
def foo(cls, x: Union[int, str]) -> Union[int, str]:
reveal_type(cls) # N: Revealed type is 'Type[__main__.A]'
reveal_type(cls.other()) # N: Revealed type is 'builtins.str'
return x
reveal_type(A.foo(3)) # N: Revealed type is 'builtins.int'
reveal_type(A.foo("foo")) # N: Revealed type is 'builtins.str'
[builtins fixtures/classmethod.pyi]
[case testDataclassesClassVars]
# flags: --python-version 3.6
from dataclasses import dataclass
from typing import ClassVar
@dataclass
class Application:
name: str
COUNTER: ClassVar[int] = 0
reveal_type(Application) # N: Revealed type is 'def (name: builtins.str) -> __main__.Application'
application = Application("example")
application.COUNTER = 1 # E: Cannot assign to class variable "COUNTER" via instance
Application.COUNTER = 1
[builtins fixtures/list.pyi]
[case testDataclassEquality]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class Application:
name: str
rating: int
app1 = Application("example-1", 5)
app2 = Application("example-2", 5)
app1 == app2
app1 != app2
app1 == None # E: Unsupported operand types for == ("Application" and "None")
[builtins fixtures/list.pyi]
[case testDataclassCustomEquality]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass
class Application:
name: str
rating: int
def __eq__(self, other: 'Application') -> bool:
...
app1 = Application("example-1", 5)
app2 = Application("example-2", 5)
app1 == app2
app1 != app2 # E: Unsupported left operand type for != ("Application")
app1 == None # E: Unsupported operand types for == ("Application" and "None")
class SpecializedApplication(Application):
...
app1 == SpecializedApplication("example-3", 5)
[builtins fixtures/list.pyi]
[case testDataclassOrdering]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass(order=True)
class Application:
name: str
rating: int
app1 = Application('example-1', 5)
app2 = Application('example-2', 5)
app1 < app2
app1 > app2
app1 <= app2
app1 >= app2
app1 < 5 # E: Unsupported operand types for < ("Application" and "int")
app1 > 5 # E: Unsupported operand types for > ("Application" and "int")
app1 <= 5 # E: Unsupported operand types for <= ("Application" and "int")
app1 >= 5 # E: Unsupported operand types for >= ("Application" and "int")
class SpecializedApplication(Application):
...
app3 = SpecializedApplication('example-3', 5)
app1 < app3
app1 > app3
app1 <= app3
app1 >= app3
[builtins fixtures/list.pyi]
[case testDataclassOrderingWithoutEquality]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass(eq=False, order=True)
class Application: # E: eq must be True if order is True
...
[builtins fixtures/list.pyi]
[case testDataclassOrderingWithCustomMethods]
# flags: --python-version 3.6
from dataclasses import dataclass
@dataclass(order=True)
class Application:
def __lt__(self, other: 'Application') -> bool: # E: You may not have a custom __lt__ method when order=True
...
[builtins fixtures/list.pyi]
[case testDataclassDefaultsInheritance]
# flags: --python-version 3.6
from dataclasses import dataclass
from typing import Optional
@dataclass(order=True)
class Application:
id: Optional[int]
name: str
@dataclass
class SpecializedApplication(Application):
rating: int = 0
reveal_type(SpecializedApplication) # N: Revealed type is 'def (id: Union[builtins.int, None], name: builtins.str, rating: builtins.int =) -> __main__.SpecializedApplication'
[builtins fixtures/list.pyi]
[case testDataclassGenerics]
# flags: --python-version 3.6
from dataclasses import dataclass
from typing import Generic, List, Optional, TypeVar
T = TypeVar('T')
@dataclass
class A(Generic[T]):
x: T
y: T
z: List[T]
def foo(self) -> List[T]:
return [self.x, self.y]
def bar(self) -> T:
return self.z[0]
def problem(self) -> T:
return self.z # E: Incompatible return value type (got "List[T]", expected "T")
reveal_type(A) # N: Revealed type is 'def [T] (x: T`1, y: T`1, z: builtins.list[T`1]) -> __main__.A[T`1]'
A(1, 2, ["a", "b"]) # E: Cannot infer type argument 1 of "A"
a = A(1, 2, [1, 2])
reveal_type(a) # N: Revealed type is '__main__.A[builtins.int*]'
reveal_type(a.x) # N: Revealed type is 'builtins.int*'
reveal_type(a.y) # N: Revealed type is 'builtins.int*'
reveal_type(a.z) # N: Revealed type is 'builtins.list[builtins.int*]'
s: str = a.bar() # E: Incompatible types in assignment (expression has type "int", variable has type "str")
[builtins fixtures/list.pyi]
[case testDataclassGenericsClassmethod]
# flags: --python-version 3.6
from dataclasses import dataclass
from typing import Generic, TypeVar
T = TypeVar('T')
@dataclass
class A(Generic[T]):
x: T
@classmethod
def foo(cls) -> None:
reveal_type(cls) # N: Revealed type is 'Type[__main__.A[T`1]]'
reveal_type(cls(1)) # N: Revealed type is '__main__.A[builtins.int*]'
reveal_type(cls('wooooo')) # N: Revealed type is '__main__.A[builtins.str*]'
[builtins fixtures/classmethod.pyi]
[case testDataclassesForwardRefs]
from dataclasses import dataclass
@dataclass
class A:
b: 'B'
@dataclass
class B:
x: int
reveal_type(A) # N: Revealed type is 'def (b: __main__.B) -> __main__.A'
A(b=B(42))
A(b=42) # E: Argument "b" to "A" has incompatible type "int"; expected "B"
[builtins fixtures/list.pyi]
[case testDataclassesInitVars]
from dataclasses import InitVar, dataclass
@dataclass
class Application:
name: str
database_name: InitVar[str]
reveal_type(Application) # N: Revealed type is 'def (name: builtins.str, database_name: builtins.str) -> __main__.Application'
app = Application("example", 42) # E: Argument 2 to "Application" has incompatible type "int"; expected "str"
app = Application("example", "apps")
app.name
app.database_name # E: "Application" has no attribute "database_name"
@dataclass
class SpecializedApplication(Application):
rating: int
reveal_type(SpecializedApplication) # N: Revealed type is 'def (name: builtins.str, database_name: builtins.str, rating: builtins.int) -> __main__.SpecializedApplication'
app = SpecializedApplication("example", "apps", "five") # E: Argument 3 to "SpecializedApplication" has incompatible type "str"; expected "int"
app = SpecializedApplication("example", "apps", 5)
app.name
app.rating
app.database_name # E: "SpecializedApplication" has no attribute "database_name"
[builtins fixtures/list.pyi]
[case testDataclassesInitVarsAndDefer]
from dataclasses import InitVar, dataclass
defer: Yes
@dataclass
class Application:
name: str
database_name: InitVar[str]
reveal_type(Application) # N: Revealed type is 'def (name: builtins.str, database_name: builtins.str) -> __main__.Application'
app = Application("example", 42) # E: Argument 2 to "Application" has incompatible type "int"; expected "str"
app = Application("example", "apps")
app.name
app.database_name # E: "Application" has no attribute "database_name"
class Yes: ...
[builtins fixtures/list.pyi]
[case testDataclassesNoInitInitVarInheritance]
from dataclasses import dataclass, field, InitVar
@dataclass
class Super:
foo: InitVar = field(init=False)
@dataclass
class Sub(Super):
bar: int
sub = Sub(5)
sub.foo # E: "Sub" has no attribute "foo"
sub.bar
[builtins fixtures/bool.pyi]
[case testDataclassFactory]
from typing import Type, TypeVar
from dataclasses import dataclass
T = TypeVar('T', bound='A')
@dataclass
class A:
@classmethod
def make(cls: Type[T]) -> T:
reveal_type(cls) # N: Revealed type is 'Type[T`-1]'
reveal_type(cls()) # N: Revealed type is 'T`-1'
return cls()
[builtins fixtures/classmethod.pyi]
[case testNoComplainFieldNone]
# flags: --python-version 3.6
# flags: --no-strict-optional
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class Foo:
bar: Optional[int] = field(default=None)
[builtins fixtures/list.pyi]
[out]
[case testNoComplainFieldNoneStrict]
# flags: --python-version 3.6
# flags: --strict-optional
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class Foo:
bar: Optional[int] = field(default=None)
[builtins fixtures/list.pyi]
[out]
[case testDisallowUntypedWorksForward]
# flags: --disallow-untyped-defs
from dataclasses import dataclass
from typing import List
@dataclass
class B:
x: C
class C(List[C]):
pass
reveal_type(B) # N: Revealed type is 'def (x: __main__.C) -> __main__.B'
[builtins fixtures/list.pyi]
[case testDisallowUntypedWorksForwardBad]
# flags: --disallow-untyped-defs
from dataclasses import dataclass
@dataclass
class B:
x: Undefined # E: Name 'Undefined' is not defined
y = undefined() # E: Name 'undefined' is not defined
reveal_type(B) # N: Revealed type is 'def (x: Any) -> __main__.B'
[builtins fixtures/list.pyi]
[case testMemberExprWorksAsField]
import dataclasses
@dataclasses.dataclass
class A:
x: int = dataclasses.field(metadata={"doc": "foo"})
y: str
@dataclasses.dataclass
class B:
x: int = dataclasses.field(init=False, default=1)
y: str
@dataclasses.dataclass
class C:
x: int = dataclasses.field(default=1)
y: str = dataclasses.field(metadata={"doc": "foo"}) # E: Attributes without a default cannot follow attributes with one
[builtins fixtures/dict.pyi]
[case testDataclassOrderingDeferred]
# flags: --python-version 3.6
from dataclasses import dataclass
defer: Yes
@dataclass(order=True)
class Application:
name: str
rating: int
a = Application('', 0)
b = Application('', 0)
a < b
class Yes: ...
[builtins fixtures/list.pyi]
[case testDataclassFieldDeferred]
from dataclasses import field, dataclass
@dataclass
class C:
x: int = field(default=func())
def func() -> int: ...
C('no') # E: Argument 1 to "C" has incompatible type "str"; expected "int"
[builtins fixtures/bool.pyi]
[case testDataclassFieldDeferredFrozen]
from dataclasses import field, dataclass
@dataclass(frozen=True)
class C:
x: int = field(default=func())
def func() -> int: ...
c: C
c.x = 1 # E: Property "x" defined in "C" is read-only
[builtins fixtures/bool.pyi]
[case testTypeInDataclassDeferredStar]
import lib
[file lib.py]
from dataclasses import dataclass
MYPY = False
if MYPY: # Force deferral
from other import *
@dataclass
class C:
total: int
C() # E: Too few arguments for "C"
C('no') # E: Argument 1 to "C" has incompatible type "str"; expected "int"
[file other.py]
import lib
[builtins fixtures/bool.pyi]
[case testDeferredDataclassInitSignature]
from dataclasses import dataclass
from typing import Optional, Type
@dataclass
class C:
x: Optional[int] = None
y: Type[Deferred] = Deferred
@classmethod
def default(cls) -> C:
return cls(x=None, y=None)
class Deferred: pass
[builtins fixtures/classmethod.pyi]
[case testDeferredDataclassInitSignatureSubclass]
# flags: --strict-optional
from dataclasses import dataclass
from typing import Optional
@dataclass
class B:
x: Optional[C]
@dataclass
class C(B):
y: str
a = C(None, 'abc')
[builtins fixtures/bool.pyi]
[case testDataclassesDefaultsIncremental]
# flags: --python-version 3.6
import a
[file a.py]
from dataclasses import dataclass
from b import Person
@dataclass
class Asdf(Person):
c: str = 'test'
[file a.py.2]
from dataclasses import dataclass
from b import Person
@dataclass
class Asdf(Person):
c: str = 'test'
# asdf
[file b.py]
from dataclasses import dataclass
@dataclass
class Person:
b: int
a: str = 'test'
[builtins fixtures/list.pyi]
[case testDataclassesDefaultsMroOtherFile]
# flags: --python-version 3.6
import a
[file a.py]
from dataclasses import dataclass
from b import A1, A2
@dataclass
class Asdf(A1, A2): # E: Attributes without a default cannot follow attributes with one
pass
[file b.py]
from dataclasses import dataclass
# a bunch of blank lines to make sure the error doesn't accidentally line up...
@dataclass
class A1:
a: int
@dataclass
class A2:
b: str = 'test'
[builtins fixtures/list.pyi]
[case testDataclassesInheritingDuplicateField]
# see mypy issue #7792
from dataclasses import dataclass
@dataclass
class A: # E: Name 'x' already defined (possibly by an import)
x: int = 0
x: int = 0 # E: Name 'x' already defined on line 6
@dataclass
class B(A):
pass