- case: attr_s_with_type_argument parametrized: - val: "a = attr.ib(type=int)" - val: "a: int = attr.ib()" main: | import attr @attr.s class C: {{ val }} C() # E: Missing positional argument "a" in call to "C" [call-arg] C(1) C(a=1) C(a="hi") # E: Argument "a" to "C" has incompatible type "str"; expected "int" [arg-type] - case: attr_s_with_type_annotations main: | import attr @attr.s class C: a: int = attr.ib() C() # E: Missing positional argument "a" in call to "C" [call-arg] C(1) C(a=1) C(a="hi") # E: Argument "a" to "C" has incompatible type "str"; expected "int" [arg-type] - case: testAttrsSimple main: | import attr @attr.s class A: a = attr.ib() _b = attr.ib() c = attr.ib(18) _d = attr.ib(validator=None, default=18) E = 18 def foo(self): return self.a reveal_type(A) # N: Revealed type is "def (a: Any, b: Any, c: Any =, d: Any =) -> main.A" A(1, [2]) A(1, [2], '3', 4) A(1, 2, 3, 4) A(1, [2], '3', 4, 5) # E: Too many arguments for "A" [call-arg] - case: testAttrsAnnotated regex: true main: | import attr from typing import List, ClassVar @attr.s class A: a: int = attr.ib() _b: List[int] = attr.ib() c: str = attr.ib('18') _d: int = attr.ib(validator=None, default=18) E = 7 F: ClassVar[int] = 22 reveal_type(A) # N: Revealed type is "def \(a: builtins\.int, b: builtins\.list\[builtins\.int\], c: builtins\.str =, d: builtins\.int =\) -> main\.A" A(1, [2]) A(1, [2], '3', 4) A(1, 2, 3, 4) # E: Argument 2 to "A" has incompatible type "int"; expected "[Ll]ist\[int\]" \[arg-type\] # E: Argument 3 to "A" has incompatible type "int"; expected "str" \[arg-type\] A(1, [2], '3', 4, 5) # E: Too many arguments for "A" \[call-arg\] - case: testAttrsPython2Annotations regex: true main: | import attr from typing import List, ClassVar @attr.s class A: a = attr.ib() # type: int _b = attr.ib() # type: List[int] c = attr.ib('18') # type: str _d = attr.ib(validator=None, default=18) # type: int E = 7 F: ClassVar[int] = 22 reveal_type(A) # N: Revealed type is "def \(a: builtins\.int, b: builtins\.list\[builtins\.int\], c: builtins\.str =, d: builtins\.int =\) -> main\.A" A(1, [2]) A(1, [2], '3', 4) A(1, 2, 3, 4) # E: Argument 2 to "A" has incompatible type "int"; expected "[Ll]ist\[int\]" \[arg-type\] # E: Argument 3 to "A" has incompatible type "int"; expected "str" \[arg-type\] A(1, [2], '3', 4, 5) # E: Too many arguments for "A" \[call-arg\] - case: testAttrsAutoAttribs regex: true main: | import attr from typing import List, ClassVar @attr.s(auto_attribs=True) class A: a: int _b: List[int] c: str = '18' _d: int = attr.ib(validator=None, default=18) E = 7 F: ClassVar[int] = 22 reveal_type(A) # N: Revealed type is "def \(a: builtins\.int, b: builtins.list\[builtins.int\], c: builtins\.str =, d: builtins\.int =\) -> main\.A" A(1, [2]) A(1, [2], '3', 4) A(1, 2, 3, 4) # E: Argument 2 to "A" has incompatible type "int"; expected "[Ll]ist\[int\]" \[arg-type\] # E: Argument 3 to "A" has incompatible type "int"; expected "str" \[arg-type\] A(1, [2], '3', 4, 5) # E: Too many arguments for "A" \[call-arg\] - case: testAttrsUntypedNoUntypedDefs mypy_config: | disallow_untyped_defs = True main: | import attr @attr.s class A: a = attr.ib() # E: Need type annotation for "a" [var-annotated] _b = attr.ib() # E: Need type annotation for "_b" [var-annotated] c = attr.ib(18) # E: Need type annotation for "c" [var-annotated] _d = attr.ib(validator=None, default=18) # E: Need type annotation for "_d" [var-annotated] E = 18 - case: testAttrsWrongReturnValue main: | import attr @attr.s class A: x: int = attr.ib(8) def foo(self) -> str: return self.x # E: Incompatible return value type (got "int", expected "str") [return-value] @attr.s class B: x = attr.ib(8) # type: int def foo(self) -> str: return self.x # E: Incompatible return value type (got "int", expected "str") [return-value] @attr.dataclass class C: x: int = 8 def foo(self) -> str: return self.x # E: Incompatible return value type (got "int", expected "str") [return-value] @attr.s class D: x = attr.ib(8, type=int) def foo(self) -> str: return self.x # E: Incompatible return value type (got "int", expected "str") [return-value] - case: testAttrsSeriousNames regex: true main: | from attr import attrib, attrs from typing import List @attrs(init=True) class A: a = attrib() _b: List[int] = attrib() c = attrib(18) _d = attrib(validator=None, default=18) CLASS_VAR = 18 reveal_type(A) # N: Revealed type is "def \(a: Any, b: builtins.list\[builtins.int\], c: Any =, d: Any =\) -> main\.A" A(1, [2]) A(1, [2], '3', 4) A(1, 2, 3, 4) # E: Argument 2 to "A" has incompatible type "int"; expected "[Ll]ist\[int\]" \[arg-type\] A(1, [2], '3', 4, 5) # E: Too many arguments for "A" \[call-arg\] - case: testAttrsDefaultErrors main: | import attr @attr.s class A: x = attr.ib(default=17) y = attr.ib() # E: Non-default attributes not allowed after default attributes. [misc] @attr.s(auto_attribs=True) class B: x: int = 17 y: int # E: Non-default attributes not allowed after default attributes. [misc] @attr.s(auto_attribs=True) class C: x: int = attr.ib(default=17) y: int # E: Non-default attributes not allowed after default attributes. [misc] @attr.s class D: x = attr.ib() y = attr.ib() # E: Non-default attributes not allowed after default attributes. [misc] @x.default def foo(self): return 17 - case: testAttrsNotBooleans main: | import attr x = True @attr.s(cmp=x) # E: "cmp" argument must be a True, False, or None literal [literal-required] class A: a = attr.ib(init=x) # E: "init" argument must be a True or False literal [literal-required] - case: testAttrsInitFalse main: | from attr import attrib, attrs @attrs(auto_attribs=True, init=False) class A: a: int _b: int c: int = 18 _d: int = attrib(validator=None, default=18) reveal_type(A) # N: Revealed type is "def () -> main.A" A() A(1, [2]) # E: Too many arguments for "A" [call-arg] A(1, [2], '3', 4) # E: Too many arguments for "A" [call-arg] - case: testAttrsInitAttribFalse main: | from attr import attrib, attrs @attrs class A: a = attrib(init=False) b = attrib() reveal_type(A) # N: Revealed type is "def (b: Any) -> main.A" - case: testAttrsCmpTrue regex: true main: | from attr import attrib, attrs @attrs(auto_attribs=True) class A: a: int reveal_type(A) # N: Revealed type is "def \(a: builtins.int\) -> main.A" reveal_type(A.__lt__) # N: Revealed type is "def \[_AT\] \(self: _AT`\d+, other: _AT`\d+\) -> builtins.bool" reveal_type(A.__le__) # N: Revealed type is "def \[_AT\] \(self: _AT`\d+, other: _AT`\d+\) -> builtins.bool" reveal_type(A.__gt__) # N: Revealed type is "def \[_AT\] \(self: _AT`\d+, other: _AT`\d+\) -> builtins.bool" reveal_type(A.__ge__) # N: Revealed type is "def \[_AT\] \(self: _AT`\d+, other: _AT`\d+\) -> builtins.bool" A(1) < A(2) A(1) <= A(2) A(1) > A(2) A(1) >= A(2) A(1) == A(2) A(1) != A(2) A(1) < 1 # E: Unsupported operand types for < \("A" and "int"\) \[operator\] A(1) <= 1 # E: Unsupported operand types for <= \("A" and "int"\) \[operator\] A(1) > 1 # E: Unsupported operand types for > \("A" and "int"\) \[operator\] A(1) >= 1 # E: Unsupported operand types for >= \("A" and "int"\) \[operator\] A(1) == 1 A(1) != 1 1 < A(1) # E: Unsupported operand types for < \("int" and "A"\) \[operator\] 1 <= A(1) # E: Unsupported operand types for <= \("int" and "A"\) \[operator\] 1 > A(1) # E: Unsupported operand types for > \("int" and "A"\) \[operator\] 1 >= A(1) # E: Unsupported operand types for >= \("int" and "A"\) \[operator\] 1 == A(1) 1 != A(1) - case: testAttrsEqFalse main: | from attr import attrib, attrs @attrs(auto_attribs=True, eq=False) class A: a: int reveal_type(A) # N: Revealed type is "def (a: builtins.int) -> main.A" reveal_type(A.__eq__) # N: Revealed type is "def (builtins.object, builtins.object) -> builtins.bool" reveal_type(A.__ne__) # N: Revealed type is "def (builtins.object, builtins.object) -> builtins.bool" A(1) < A(2) # E: Unsupported left operand type for < ("A") [operator] A(1) <= A(2) # E: Unsupported left operand type for <= ("A") [operator] A(1) > A(2) # E: Unsupported left operand type for > ("A") [operator] A(1) >= A(2) # E: Unsupported left operand type for >= ("A") [operator] A(1) == A(2) A(1) != A(2) A(1) < 1 # E: Unsupported operand types for > ("int" and "A") [operator] A(1) <= 1 # E: Unsupported operand types for >= ("int" and "A") [operator] A(1) > 1 # E: Unsupported operand types for < ("int" and "A") [operator] A(1) >= 1 # E: Unsupported operand types for <= ("int" and "A") [operator] A(1) == 1 A(1) != 1 1 < A(1) # E: Unsupported operand types for < ("int" and "A") [operator] 1 <= A(1) # E: Unsupported operand types for <= ("int" and "A") [operator] 1 > A(1) # E: Unsupported operand types for > ("int" and "A") [operator] 1 >= A(1) # E: Unsupported operand types for >= ("int" and "A") [operator] 1 == A(1) 1 != A(1) - case: testAttrsOrderFalse main: | from attr import attrib, attrs @attrs(auto_attribs=True, order=False) class A: a: int reveal_type(A) # N: Revealed type is "def (a: builtins.int) -> main.A" A(1) < A(2) # E: Unsupported left operand type for < ("A") [operator] A(1) <= A(2) # E: Unsupported left operand type for <= ("A") [operator] A(1) > A(2) # E: Unsupported left operand type for > ("A") [operator] A(1) >= A(2) # E: Unsupported left operand type for >= ("A") [operator] A(1) == A(2) A(1) != A(2) A(1) < 1 # E: Unsupported operand types for > ("int" and "A") [operator] A(1) <= 1 # E: Unsupported operand types for >= ("int" and "A") [operator] A(1) > 1 # E: Unsupported operand types for < ("int" and "A") [operator] A(1) >= 1 # E: Unsupported operand types for <= ("int" and "A") [operator] A(1) == 1 A(1) != 1 1 < A(1) # E: Unsupported operand types for < ("int" and "A") [operator] 1 <= A(1) # E: Unsupported operand types for <= ("int" and "A") [operator] 1 > A(1) # E: Unsupported operand types for > ("int" and "A") [operator] 1 >= A(1) # E: Unsupported operand types for >= ("int" and "A") [operator] 1 == A(1) 1 != A(1) - case: testAttrsCmpEqOrderValues main: | from attr import attrib, attrs @attrs(cmp=True) class DeprecatedTrue: ... @attrs(cmp=False) class DeprecatedFalse: ... @attrs(cmp=False, eq=True) # E: Don't mix "cmp" with "eq" and "order" [misc] class Mixed: ... @attrs(order=True, eq=False) # E: eq must be True if order is True [misc] class Confused: ... - case: testAttrsInheritance main: | import attr @attr.s class A: a: int = attr.ib() @attr.s class B: b: str = attr.ib() @attr.s class C(A, B): c: bool = attr.ib() reveal_type(C) # N: Revealed type is "def (a: builtins.int, b: builtins.str, c: builtins.bool) -> main.C" - case: testAttrsNestedInClasses main: | import attr @attr.s class C: y = attr.ib() @attr.s class D: x: int = attr.ib() reveal_type(C) # N: Revealed type is "def (y: Any) -> main.C" reveal_type(C.D) # N: Revealed type is "def (x: builtins.int) -> main.C.D" - case: testAttrsInheritanceOverride main: | import attr @attr.s class A: a: int = attr.ib() x: int = attr.ib() @attr.s class B(A): b: str = attr.ib() x: int = attr.ib(default=22) @attr.s class C(B): c: bool = attr.ib() # No error here because the x below overwrites the x above. x: int = attr.ib() reveal_type(A) # N: Revealed type is "def (a: builtins.int, x: builtins.int) -> main.A" reveal_type(B) # N: Revealed type is "def (a: builtins.int, b: builtins.str, x: builtins.int =) -> main.B" reveal_type(C) # N: Revealed type is "def (a: builtins.int, b: builtins.str, c: builtins.bool, x: builtins.int) -> main.C" - case: testAttrsTypeEquals main: | import attr @attr.s class A: a = attr.ib(type=int) b = attr.ib(18, type=int) reveal_type(A) # N: Revealed type is "def (a: builtins.int, b: builtins.int =) -> main.A" - case: testAttrsFrozen main: | import attr @attr.s(frozen=True) class A: a = attr.ib() a = A(5) a.a = 16 # E: Property "a" defined in "A" is read-only [misc] - case: testAttrsNextGenFrozen main: | from attr import frozen, field @frozen class A: a = field() a = A(5) a.a = 16 # E: Property "a" defined in "A" is read-only [misc] - case: testAttrsNextGenDetect main: | from attr import define, field @define class A: a = field() @define class B: a: int @define class C: a: int = field() b = field() @define class D: a: int b = field() reveal_type(A) # N: Revealed type is "def (a: Any) -> main.A" reveal_type(B) # N: Revealed type is "def (a: builtins.int) -> main.B" reveal_type(C) # N: Revealed type is "def (a: builtins.int, b: Any) -> main.C" reveal_type(D) # N: Revealed type is "def (b: Any) -> main.D" - case: testAttrsDataClass main: | import attr from typing import List, ClassVar @attr.dataclass class A: a: int _b: List[str] c: str = '18' _d: int = attr.ib(validator=None, default=18) E = 7 F: ClassVar[int] = 22 reveal_type(A) # N: Revealed type is "def (a: builtins.int, b: builtins.list[builtins.str], c: builtins.str =, d: builtins.int =) -> main.A" A(1, ['2']) - case: testAttrsTypeAlias main: | from typing import List import attr Alias = List[int] @attr.s(auto_attribs=True) class A: Alias2 = List[str] x: Alias y: Alias2 = attr.ib() reveal_type(A) # N: Revealed type is "def (x: builtins.list[builtins.int], y: builtins.list[builtins.str]) -> main.A" - case: testAttrsGeneric regex: true main: | from typing import TypeVar, Generic, List import attr T = TypeVar('T') @attr.s(auto_attribs=True) class A(Generic[T]): x: List[T] y: T = attr.ib() def foo(self) -> List[T]: return [self.y] def bar(self) -> T: return self.x[0] def problem(self) -> T: return self.x # E: Incompatible return value type \(got "[Ll]ist\[T\]", expected "T"\) \[return-value\] reveal_type(A) # N: Revealed type is "def \[T\] \(x: builtins\.list\[T`1\], y: T`1\) -> main.A\[T`1\]" a = A([1], 2) reveal_type(a) # N: Revealed type is "main\.A\[builtins.int\]" reveal_type(a.x) # N: Revealed type is "builtins\.list\[builtins\.int\]" reveal_type(a.y) # N: Revealed type is "builtins\.int" A(['str'], 7) # E: Cannot infer type argument 1 of "A" \[misc\] A([1], '2') # E: Cannot infer type argument 1 of "A" \[misc\] - case: testAttrsUntypedGenericInheritance main: | from typing import Generic, TypeVar import attr T = TypeVar("T") @attr.s(auto_attribs=True) class Base(Generic[T]): attr: T @attr.s(auto_attribs=True) class Sub(Base): pass sub = Sub(attr=1) reveal_type(sub) # N: Revealed type is "main.Sub" reveal_type(sub.attr) # N: Revealed type is "Any" skip: True # Need to investigate why this is broken - case: testAttrsGenericInheritance main: | from typing import Generic, TypeVar import attr S = TypeVar("S") T = TypeVar("T") @attr.s(auto_attribs=True) class Base(Generic[T]): attr: T @attr.s(auto_attribs=True) class Sub(Base[S]): pass sub_int = Sub[int](attr=1) reveal_type(sub_int) # N: Revealed type is "main.Sub[builtins.int]" reveal_type(sub_int.attr) # N: Revealed type is "builtins.int" sub_str = Sub[str](attr='ok') reveal_type(sub_str) # N: Revealed type is "main.Sub[builtins.str]" reveal_type(sub_str.attr) # N: Revealed type is "builtins.str" - case: testAttrsGenericInheritance2 main: | from typing import Generic, TypeVar import attr T1 = TypeVar("T1") T2 = TypeVar("T2") T3 = TypeVar("T3") @attr.s(auto_attribs=True) class Base(Generic[T1, T2, T3]): one: T1 two: T2 three: T3 @attr.s(auto_attribs=True) class Sub(Base[int, str, float]): pass sub = Sub(one=1, two='ok', three=3.14) reveal_type(sub) # N: Revealed type is "main.Sub" reveal_type(sub.one) # N: Revealed type is "builtins.int*" reveal_type(sub.two) # N: Revealed type is "builtins.str*" reveal_type(sub.three) # N: Revealed type is "builtins.float*" skip: True # Need to investigate why this is broken - case: testAttrsMultiGenericInheritance main: | from typing import Generic, TypeVar import attr T = TypeVar("T") @attr.s(auto_attribs=True, eq=False) class Base(Generic[T]): base_attr: T S = TypeVar("S") @attr.s(auto_attribs=True, eq=False) class Middle(Base[int], Generic[S]): middle_attr: S @attr.s(auto_attribs=True, eq=False) class Sub(Middle[str]): pass reveal_type(Sub.__init__) sub = Sub(base_attr=1, middle_attr='ok') reveal_type(sub) # N: Revealed type is "main.Sub" reveal_type(sub.base_attr) # N: Revealed type is "builtins.int*" reveal_type(sub.middle_attr) # N: Revealed type is "builtins.str*" skip: True # Need to investigate why this is broken - case: testAttrsGenericClassmethod main: | from typing import TypeVar, Generic, Optional import attr T = TypeVar('T') @attr.s(auto_attribs=True) class A(Generic[T]): x: Optional[T] @classmethod def clsmeth(cls) -> None: reveal_type(cls) # N: Revealed type is "type[main.A[T`1]]" - case: testAttrsForwardReference main: | from typing import Optional import attr @attr.s(auto_attribs=True) class A: parent: 'B' @attr.s(auto_attribs=True) class B: parent: Optional[A] reveal_type(A) # N: Revealed type is "def (parent: main.B) -> main.A" reveal_type(B) # N: Revealed type is "def (parent: Union[main.A, None]) -> main.B" A(B(None)) - case: testAttrsForwardReferenceInClass main: | from typing import Optional import attr @attr.s(auto_attribs=True) class A: parent: A.B @attr.s(auto_attribs=True) class B: parent: Optional[A] reveal_type(A) # N: Revealed type is "def (parent: main.A.B) -> main.A" reveal_type(A.B) # N: Revealed type is "def (parent: Union[main.A, None]) -> main.A.B" A(A.B(None)) - case: testAttrsImporting main: | from helper import A reveal_type(A) # N: Revealed type is "def (a: builtins.int, b: builtins.str) -> helper.A" files: - path: helper.py content: | import attr @attr.s(auto_attribs=True) class A: a: int b: str = attr.ib() - case: testAttrsOtherMethods main: | import attr @attr.s(auto_attribs=True) class A: a: int b: str = attr.ib() @classmethod def new(cls) -> A: reveal_type(cls) # N: Revealed type is "type[main.A]" return cls(6, 'hello') @classmethod def bad(cls) -> A: return cls(17) # E: Missing positional argument "b" in call to "A" [call-arg] def foo(self) -> int: return self.a reveal_type(A) # N: Revealed type is "def (a: builtins.int, b: builtins.str) -> main.A" a = A.new() reveal_type(a.foo) # N: Revealed type is "def () -> builtins.int" - case: testAttrsOtherOverloads main: | import attr from typing import overload, Union @attr.s class A: a = attr.ib() b = attr.ib(default=3) @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" - case: testAttrsDefaultDecorator main: | import attr @attr.s class C: x: int = attr.ib(default=1) y: int = attr.ib() @y.default def name_does_not_matter(self): return self.x + 1 C() - case: testAttrsValidatorDecorator main: | import attr @attr.s class C: x = attr.ib() @x.validator def check(self, attribute, value): if value > 42: raise ValueError("x must be smaller or equal to 42") C(42) C(43) - case: testAttrsLocalVariablesInClassMethod main: | import attr @attr.s(auto_attribs=True) class A: a: int b: int = attr.ib() @classmethod def new(cls, foo: int) -> A: a = foo b = a return cls(a, b) - case: testAttrsUnionForward main: | import attr from typing import Union, List @attr.s(auto_attribs=True) class A: frob: List['AOrB'] class B: pass AOrB = Union[A, B] reveal_type(A) # N: Revealed type is "def (frob: builtins.list[Union[main.A, main.B]]) -> main.A" reveal_type(B) # N: Revealed type is "def () -> main.B" A([B()]) - case: testAttrsUsingConverter main: | import attr import helper def converter2(s:int) -> str: return 'hello' @attr.s class C: x: str = attr.ib(converter=helper.converter) y: str = attr.ib(converter=converter2) # Because of the converter the __init__ takes an int, but the variable is a str. reveal_type(C) # N: Revealed type is "def (x: builtins.int, y: builtins.int) -> main.C" reveal_type(C(15, 16).x) # N: Revealed type is "builtins.str" files: - path: helper.py content: | def converter(s:int) -> str: return 'hello' - case: testAttrsUsingBadConverter skip: sys.version_info[:2] < (3, 10) main: | import attr from typing import overload @overload def bad_overloaded_converter(x: int, y: int) -> int: ... @overload def bad_overloaded_converter(x: str, y: str) -> str: ... def bad_overloaded_converter(x, y=7): return x def bad_converter() -> str: return '' @attr.dataclass class A: bad: str = attr.ib(converter=bad_converter) bad_overloaded: int = attr.ib(converter=bad_overloaded_converter) reveal_type(A) out: | main:15: error: Cannot determine __init__ type from converter [misc] main:15: error: Argument "converter" has incompatible type "Callable[[], str]"; expected "Callable[[Any], Any] | Converter[Any, Never] | None" [arg-type] main:16: error: Cannot determine __init__ type from converter [misc] main:16: error: Argument "converter" has incompatible type overloaded function; expected "Callable[[Any], Any] | Converter[Any, Never] | None" [arg-type] main:17: note: Revealed type is "def (bad: Any, bad_overloaded: Any) -> main.A" - case: testAttrsUsingBadConverterReprocess skip: sys.version_info[:2] < (3, 10) main: | import attr from typing import overload forward: 'A' @overload def bad_overloaded_converter(x: int, y: int) -> int: ... @overload def bad_overloaded_converter(x: str, y: str) -> str: ... def bad_overloaded_converter(x, y=7): return x def bad_converter() -> str: return '' @attr.dataclass class A: bad: str = attr.ib(converter=bad_converter) bad_overloaded: int = attr.ib(converter=bad_overloaded_converter) reveal_type(A) out: | main:16: error: Cannot determine __init__ type from converter [misc] main:16: error: Argument "converter" has incompatible type "Callable[[], str]"; expected "Callable[[Any], Any] | Converter[Any, Never] | None" [arg-type] main:17: error: Cannot determine __init__ type from converter [misc] main:17: error: Argument "converter" has incompatible type overloaded function; expected "Callable[[Any], Any] | Converter[Any, Never] | None" [arg-type] main:18: note: Revealed type is "def (bad: Any, bad_overloaded: Any) -> main.A" - case: testAttrsUsingUnsupportedConverter main: | import attr class Thing: def do_it(self, int) -> str: return "" thing = Thing() def factory(default: int): return 1 @attr.s class C: x: str = attr.ib(converter=thing.do_it) # E: Unsupported converter, only named functions, types and lambdas are currently supported [misc] y: str = attr.ib(converter=lambda x: x) z: str = attr.ib(converter=factory(8)) # E: Unsupported converter, only named functions, types and lambdas are currently supported [misc] reveal_type(C) # N: Revealed type is "def (x: Any, y: Any, z: Any) -> main.C" - case: testAttrsUsingConverterAndSubclass main: | import attr def converter(s:int) -> str: return 'hello' @attr.s class C: x: str = attr.ib(converter=converter) @attr.s class A(C): pass # Because of the convert the __init__ takes an int, but the variable is a str. reveal_type(A) # N: Revealed type is "def (x: builtins.int) -> main.A" reveal_type(A(15).x) # N: Revealed type is "builtins.str" - case: testAttrsUsingConverterWithTypes main: | from typing import overload import attr @attr.dataclass class A: x: str @attr.s class C: x: complex = attr.ib(converter=complex) y: int = attr.ib(converter=int) z: A = attr.ib(converter=A) o = C("1", "2", "3") o = C(1, 2, "3") - case: testThreeArgConverterTypes main: | from typing import Any from attrs import AttrsInstance, Attribute, Converter def my_converter(value: Any) -> str: """A converter that only takes the value.""" return str(value) def my_converter_with_self(value: Any, self: AttrsInstance) -> str: """This converter takes the value and the self.""" return str(value) def my_converter_with_field(value: Any, field: Attribute) -> str: """This converter takes the value and the field.""" return str(value) reveal_type(Converter(my_converter)) Converter(my_converter_with_self) Converter(my_converter_with_field) reveal_type(Converter(my_converter_with_self, takes_self=True)) Converter(my_converter, takes_self=True) Converter(my_converter_with_field, takes_self=True) reveal_type(Converter(my_converter_with_field, takes_field=True)) Converter(my_converter, takes_field=True) Converter(my_converter_with_self, takes_field=True) out: | main:17: note: Revealed type is "attr.Converter[Any, builtins.str]" main:18: error: Argument 1 to "Converter" has incompatible type "Callable[[Any, AttrsInstance], str]"; expected "Callable[[Any], str]" [arg-type] main:19: error: Argument 1 to "Converter" has incompatible type "Callable[[Any, Attribute[Any]], str]"; expected "Callable[[Any], str]" [arg-type] main:21: note: Revealed type is "attr.Converter[Any, builtins.str]" main:22: error: No overload variant of "Converter" matches argument types "Callable[[Any], str]", "bool" [call-overload] main:22: note: Possible overload variants: main:22: note: def [In, Out] Converter(self, converter: Callable[[In], Out]) -> Converter[In, Out] main:22: note: def [In, Out] Converter(self, converter: Callable[[In, AttrsInstance, Attribute[Any]], Out], *, takes_self: Literal[True], takes_field: Literal[True]) -> Converter[In, Out] main:22: note: def [In, Out] Converter(self, converter: Callable[[In, Attribute[Any]], Out], *, takes_field: Literal[True]) -> Converter[In, Out] main:22: note: def [In, Out] Converter(self, converter: Callable[[In, AttrsInstance], Out], *, takes_self: Literal[True]) -> Converter[In, Out] main:23: error: No overload variant of "Converter" matches argument types "Callable[[Any, Attribute[Any]], str]", "bool" [call-overload] main:23: note: Possible overload variants: main:23: note: def [In, Out] Converter(self, converter: Callable[[In], Out]) -> Converter[In, Out] main:23: note: def [In, Out] Converter(self, converter: Callable[[In, AttrsInstance, Attribute[Any]], Out], *, takes_self: Literal[True], takes_field: Literal[True]) -> Converter[In, Out] main:23: note: def [In, Out] Converter(self, converter: Callable[[In, Attribute[Any]], Out], *, takes_field: Literal[True]) -> Converter[In, Out] main:23: note: def [In, Out] Converter(self, converter: Callable[[In, AttrsInstance], Out], *, takes_self: Literal[True]) -> Converter[In, Out] main:25: note: Revealed type is "attr.Converter[Any, builtins.str]" main:26: error: No overload variant of "Converter" matches argument types "Callable[[Any], str]", "bool" [call-overload] main:26: note: Possible overload variants: main:26: note: def [In, Out] Converter(self, converter: Callable[[In], Out]) -> Converter[In, Out] main:26: note: def [In, Out] Converter(self, converter: Callable[[In, AttrsInstance, Attribute[Any]], Out], *, takes_self: Literal[True], takes_field: Literal[True]) -> Converter[In, Out] main:26: note: def [In, Out] Converter(self, converter: Callable[[In, Attribute[Any]], Out], *, takes_field: Literal[True]) -> Converter[In, Out] main:26: note: def [In, Out] Converter(self, converter: Callable[[In, AttrsInstance], Out], *, takes_self: Literal[True]) -> Converter[In, Out] main:27: error: No overload variant of "Converter" matches argument types "Callable[[Any, AttrsInstance], str]", "bool" [call-overload] main:27: note: Possible overload variants: main:27: note: def [In, Out] Converter(self, converter: Callable[[In], Out]) -> Converter[In, Out] main:27: note: def [In, Out] Converter(self, converter: Callable[[In, AttrsInstance, Attribute[Any]], Out], *, takes_self: Literal[True], takes_field: Literal[True]) -> Converter[In, Out] main:27: note: def [In, Out] Converter(self, converter: Callable[[In, Attribute[Any]], Out], *, takes_field: Literal[True]) -> Converter[In, Out] main:27: note: def [In, Out] Converter(self, converter: Callable[[In, AttrsInstance], Out], *, takes_self: Literal[True]) -> Converter[In, Out] - case: testAttrsCmpWithSubclasses regex: true main: | import attr @attr.s class A: pass @attr.s class B: pass @attr.s class C(A, B): pass @attr.s class D(A): pass reveal_type(A.__lt__) # N: Revealed type is "def \[_AT\] \(self: _AT`\d+, other: _AT`\d+\) -> builtins.bool" reveal_type(B.__lt__) # N: Revealed type is "def \[_AT\] \(self: _AT`\d+, other: _AT`\d+\) -> builtins.bool" reveal_type(C.__lt__) # N: Revealed type is "def \[_AT\] \(self: _AT`\d+, other: _AT`\d+\) -> builtins.bool" reveal_type(D.__lt__) # N: Revealed type is "def \[_AT\] \(self: _AT`\d+, other: _AT`\d+\) -> builtins.bool" A() < A() B() < B() A() < B() # E: Unsupported operand types for < \("A" and "B"\) \[operator\] C() > A() C() > B() C() > C() C() > D() # E: Unsupported operand types for > \("C" and "D"\) \[operator\] D() >= A() D() >= B() # E: Unsupported operand types for >= \("D" and "B"\) \[operator\] D() >= C() # E: Unsupported operand types for >= \("D" and "C"\) \[operator\] D() >= D() A() <= 1 # E: Unsupported operand types for <= \("A" and "int"\) \[operator\] B() <= 1 # E: Unsupported operand types for <= \("B" and "int"\) \[operator\] C() <= 1 # E: Unsupported operand types for <= \("C" and "int"\) \[operator\] D() <= 1 # E: Unsupported operand types for <= \("D" and "int"\) \[operator\] - case: testAttrsComplexSuperclass main: | import attr @attr.s class C: x: int = attr.ib(default=1) y: int = attr.ib() @y.default def name_does_not_matter(self): return self.x + 1 @attr.s class A(C): z: int = attr.ib(default=18) reveal_type(C) # N: Revealed type is "def (x: builtins.int =, y: builtins.int =) -> main.C" reveal_type(A) # N: Revealed type is "def (x: builtins.int =, y: builtins.int =, z: builtins.int =) -> main.A" - case: testAttrsMultiAssign main: | import attr @attr.s class A: x, y, z = attr.ib(), attr.ib(type=int), attr.ib(default=17) reveal_type(A) # N: Revealed type is "def (x: Any, y: builtins.int, z: Any =) -> main.A" - case: testAttrsMultiAssign2 main: | import attr @attr.s class A: x = y = z = attr.ib() # E: Too many names for one attribute [misc] - case: testAttrsPrivateInit main: | import attr @attr.s class C: _x = attr.ib(init=False, default=42) C() C(_x=42) # E: Unexpected keyword argument "_x" for "C" [call-arg] - case: testAttrsAutoMustBeAll main: | import attr @attr.s(auto_attribs=True) class A: a: int b = 17 # The following forms are not allowed with auto_attribs=True c = attr.ib() # E: Need type annotation for "c" [var-annotated] d, e = attr.ib(), attr.ib() # E: Need type annotation for "d" [var-annotated] # E: Need type annotation for "e" [var-annotated] f = g = attr.ib() # E: Need type annotation for "f" [var-annotated] # E: Need type annotation for "g" [var-annotated] - case: testAttrsRepeatedName main: | import attr @attr.s class A: a = attr.ib(default=8) b = attr.ib() a = attr.ib() reveal_type(A) # N: Revealed type is "def (b: Any, a: Any) -> main.A" @attr.s class B: a: int = attr.ib(default=8) b: int = attr.ib() a: int = attr.ib() # E: Name "a" already defined on line 10 [no-redef] reveal_type(B) # N: Revealed type is "def (b: builtins.int, a: builtins.int) -> main.B" @attr.s(auto_attribs=True) class C: a: int = 8 b: int a: int = attr.ib() # E: Name "a" already defined on line 16 [no-redef] reveal_type(C) # N: Revealed type is "def (a: builtins.int, b: builtins.int) -> main.C" - case: testAttrsFrozenSubclass main: | import attr @attr.dataclass class NonFrozenBase: a: int @attr.dataclass(frozen=True) class FrozenBase: a: int @attr.dataclass(frozen=True) class FrozenNonFrozen(NonFrozenBase): b: int @attr.dataclass(frozen=True) class FrozenFrozen(FrozenBase): b: int @attr.dataclass class NonFrozenFrozen(FrozenBase): b: int # Make sure these are untouched non_frozen_base = NonFrozenBase(1) non_frozen_base.a = 17 frozen_base = FrozenBase(1) frozen_base.a = 17 # E: Property "a" defined in "FrozenBase" is read-only [misc] a = FrozenNonFrozen(1, 2) a.a = 17 # E: Property "a" defined in "FrozenNonFrozen" is read-only [misc] a.b = 17 # E: Property "b" defined in "FrozenNonFrozen" is read-only [misc] b = FrozenFrozen(1, 2) b.a = 17 # E: Property "a" defined in "FrozenFrozen" is read-only [misc] b.b = 17 # E: Property "b" defined in "FrozenFrozen" is read-only [misc] c = NonFrozenFrozen(1, 2) c.a = 17 # E: Property "a" defined in "NonFrozenFrozen" is read-only [misc] c.b = 17 # E: Property "b" defined in "NonFrozenFrozen" is read-only [misc] - case: testAttrsCallableAttributes main: | from typing import Callable import attr def blah(a: int, b: int) -> bool: return True @attr.s(auto_attribs=True) class F: _cb: Callable[[int, int], bool] = blah def foo(self) -> bool: return self._cb(5, 6) @attr.s class G: _cb: Callable[[int, int], bool] = attr.ib(blah) def foo(self) -> bool: return self._cb(5, 6) @attr.s(auto_attribs=True, frozen=True) class FFrozen(F): def bar(self) -> bool: return self._cb(5, 6) - case: testAttrsWithFactory main: | from typing import List import attr def my_factory() -> int: return 7 @attr.s class A: x: List[int] = attr.ib(factory=list) y: int = attr.ib(factory=my_factory) A() - case: testAttrsFactoryAndDefault main: | import attr @attr.s class A: x: int = attr.ib(factory=int, default=7) # E: Can't pass both "default" and "factory". [misc] - case: testAttrsFactoryBadReturn regex: true main: | import attr def my_factory() -> int: return 7 @attr.s class A: x: int = attr.ib(factory=list) # E: Incompatible types in assignment \(expression has type "[Ll]ist\[.*\]", variable has type "int"\) \[assignment\] y: str = attr.ib(factory=my_factory) # E: Incompatible types in assignment \(expression has type "int", variable has type "str"\) \[assignment\] - case: testAttrsDefaultAndInit main: | import attr @attr.s class C: a = attr.ib(init=False, default=42) b = attr.ib() # Ok because previous attribute is init=False c = attr.ib(default=44) d = attr.ib(init=False) # Ok because this attribute is init=False e = attr.ib() # E: Non-default attributes not allowed after default attributes. [misc] - case: testAttrsOptionalConverter main: | # flags: --strict-optional import attr from attr.converters import optional from typing import Optional def converter(s:int) -> str: return 'hello' @attr.s class A: y: Optional[int] = attr.ib(converter=optional(int)) z: Optional[str] = attr.ib(converter=optional(converter)) A(None, None) - case: testAttrsTypeVarNoCollision main: | from typing import TypeVar, Generic import attr T = TypeVar("T", bytes, str) # Make sure the generated __le__ (and friends) don't use T for their arguments. @attr.s(auto_attribs=True) class A(Generic[T]): v: T - case: testAttrsKwOnlyAttrib main: | import attr @attr.s class A: a = attr.ib(kw_only=True) A() # E: Missing named argument "a" for "A" [call-arg] A(15) # E: Too many positional arguments for "A" [misc] A(a=15) - case: testAttrsKwOnlyClass main: | import attr @attr.s(kw_only=True, auto_attribs=True) class A: a: int b: bool A() # E: Missing named argument "a" for "A" [call-arg] # E: Missing named argument "b" for "A" [call-arg] A(b=True, a=15) - case: testAttrsKwOnlyClassNoInit main: | import attr @attr.s(kw_only=True) class B: a = attr.ib(init=False) b = attr.ib() B(b=True) - case: testAttrsKwOnlyWithDefault main: | import attr @attr.s class C: a = attr.ib(0) b = attr.ib(kw_only=True) c = attr.ib(16, kw_only=True) C(b=17) - case: testAttrsKwOnlyClassWithMixedDefaults main: | import attr @attr.s(kw_only=True) class D: a = attr.ib(10) b = attr.ib() c = attr.ib(15) D(b=17) - case: testAttrsKwOnlySubclass main: | import attr @attr.s class A2: a = attr.ib(default=0) @attr.s class B2(A2): b = attr.ib(kw_only=True) B2(b=1) - case: testAttrsNonKwOnlyAfterKwOnly main: | import attr @attr.s(kw_only=True) class A: a = attr.ib(default=0) @attr.s class B(A): b = attr.ib() @attr.s class C: a = attr.ib(kw_only=True) b = attr.ib(15) - case: testAttrsDisallowUntypedWorksForward main: | # flags: --disallow-untyped-defs import attr from typing import List @attr.s class B: x: C = attr.ib() class C(List[C]): pass reveal_type(B) # N: Revealed type is "def (x: main.C) -> main.B" - case: testDisallowUntypedWorksForwardBad mypy_config: disallow_untyped_defs = True main: | import attr @attr.s class B: x = attr.ib() # E: Need type annotation for "x" [var-annotated] reveal_type(B) # N: Revealed type is "def (x: Any) -> main.B" - case: testAttrsDefaultDecoratorDeferred main: | defer: Yes import attr @attr.s class C: x: int = attr.ib(default=1) y: int = attr.ib() @y.default def inc(self): return self.x + 1 class Yes: ... - case: testAttrsValidatorDecoratorDeferred main: | defer: Yes import attr @attr.s class C: x = attr.ib() @x.validator def check(self, attribute, value): if value > 42: raise ValueError("x must be smaller or equal to 42") C(42) C(43) class Yes: ... - case: testTypeInAttrUndefined main: | import attr @attr.s class C: total = attr.ib(type=Bad) # E: Name "Bad" is not defined [name-defined] - case: testTypeInAttrForwardInRuntime main: | import attr @attr.s class C: total = attr.ib(type=Forward) reveal_type(C.total) # N: Revealed type is "main.Forward" C('no') # E: Argument 1 to "C" has incompatible type "str"; expected "Forward" [arg-type] class Forward: ... - case: testDefaultInAttrForward main: | import attr @attr.s class C: total = attr.ib(default=func()) def func() -> int: return 5 C() C(1) C(1, 2) # E: Too many arguments for "C" [call-arg] - case: testTypeInAttrUndefinedFrozen main: | import attr @attr.s(frozen=True) class C: total = attr.ib(type=Bad) # E: Name "Bad" is not defined [name-defined] C(0).total = 1 # E: Property "total" defined in "C" is read-only [misc] - case: testTypeInAttrDeferredStar main: | import lib files: - path: lib.py content: | import attr MYPY = False if MYPY: # Force deferral from other import * @attr.s class C: total = attr.ib(type=int) C() # E: Missing positional argument "total" in call to "C" [call-arg] C('no') # E: Argument 1 to "C" has incompatible type "str"; expected "int" [arg-type] - path: other.py content: | import lib - case: testAttrsDefaultsMroOtherFile main: | import a files: - path: a.py content: | import attr from b import A1, A2 @attr.s class Asdf(A1, A2): # E: Non-default attributes not allowed after default attributes. [misc] pass - path: b.py content: | import attr @attr.s class A1: a: str = attr.ib('test') @attr.s class A2: b: int = attr.ib() - case: testAttrsInheritanceNoAnnotation main: | import attr @attr.s class A: foo = attr.ib() # type: int x = 0 @attr.s class B(A): foo = x reveal_type(B) # N: Revealed type is "def (foo: builtins.int) -> main.B" - case: testFields regex: true main: | from attrs import define, fields @define class A: a: int b: str reveal_type(fields(A)) # N: Revealed type is "[Tt]uple\[attr.Attribute\[builtins.int\], attr.Attribute\[builtins.str\], fallback=main.A.__main_A_AttrsAttributes__\]" - case: testFieldsError regex: true main: | from attrs import fields class A: a: int b: str fields(A) # E: Argument 1 to "fields" has incompatible type "[Tt]ype\[A\]"; expected "[Tt]ype\[AttrsInstance\]" \[arg-type\] - case: testAsDict main: | from attrs import asdict, define @define class A: a: int asdict(A(1)) - case: testAsDictError main: | from attrs import asdict class A: a: int asdict(A()) # E: Argument 1 to "asdict" has incompatible type "A"; expected "AttrsInstance" [arg-type] - case: testHasTypeGuard main: | from attrs import define, has @define class A: pass reveal_type(A) # N: Revealed type is "def () -> main.A" if has(A): reveal_type(A) # N: Revealed type is "type[attr.AttrsInstance]"