Skip to content

Commit c38d3ac

Browse files
committed
WIP: attrs_plugin
1 parent 0c14260 commit c38d3ac

File tree

3 files changed

+21
-27
lines changed

3 files changed

+21
-27
lines changed

mypy/plugin.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,12 @@ def add_init_argument(name: str, typ: Optional[Type], default: bool,
488488
"Non-default attributes not allowed after default attributes.",
489489
context)
490490
if not typ:
491+
if ctx.api.options.disallow_untyped_defs:
492+
# This is a compromise. If you don't have a type here then the init will be untyped.
493+
# But since the __init__ method doesn't have a line number it's difficult to point
494+
# to the correct line number. So instead we just show the error in the assignment.
495+
# Which is where you would fix the issue.
496+
ctx.api.fail(messages.NEED_ANNOTATION_FOR_VAR, context)
491497
typ = AnyType(TypeOfAny.unannotated)
492498

493499
names.append(name)
@@ -509,8 +515,6 @@ def is_class_var(expr: NameExpr) -> bool:
509515

510516
if called_function(stmt.rvalue) in attr_attrib_makers:
511517
assert isinstance(stmt.rvalue, CallExpr)
512-
if not stmt.type:
513-
stmt.type = AnyType(TypeOfAny.explicit)
514518

515519
# Is it an init=False argument?
516520
attr_init = get_argument(stmt.rvalue, "init", 5)

test-data/unit/check-attr.test

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,3 @@
1-
[case testStuffAttrS]
2-
import attr
3-
4-
a = attr.ib() # E: Need type annotation for variable
5-
b = attr.ib(7)
6-
c = attr.ib(validator=22) # E: Need type annotation for variable
7-
d = attr.ib(7, validator=22)
8-
9-
reveal_type(a) # E: Revealed type is 'Any' # E: Cannot determine type of 'a'
10-
reveal_type(b) # E: Revealed type is 'Any'
11-
reveal_type(c) # E: Revealed type is 'Any' # E: Cannot determine type of 'c'
12-
reveal_type(d) # E: Revealed type is 'builtins.int*'
13-
14-
[builtins fixtures/attr_builtins.pyi]
15-
[add-module fixtures/attr.pyi]
16-
171
[case testUntypedAttrS]
182
import attr
193
@attr.s
@@ -37,6 +21,20 @@ UnTyped(1, 2) >= UnTyped(2, 3)
3721
[builtins fixtures/attr_builtins.pyi]
3822
[add-module fixtures/attr.pyi]
3923

24+
[case testUntypedNoUntypedAttrS]
25+
# flags: --disallow-untyped-defs
26+
import attr
27+
@attr.s
28+
class UnTyped:
29+
normal = attr.ib() # E: Need type annotation for variable
30+
_private = attr.ib() # E: Need type annotation for variable
31+
def_arg = attr.ib(18) # E: Need type annotation for variable
32+
_def_kwarg = attr.ib(validator=None, default=18) # E: Need type annotation for variable
33+
34+
CLASS_VAR = 18
35+
[builtins fixtures/attr_builtins.pyi]
36+
[add-module fixtures/attr.pyi]
37+
4038
[case testTypedAttrS]
4139
import attr
4240
import typing

test-data/unit/fixtures/attr.pyi

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,10 @@ from typing import TypeVar, overload, Callable, Any
22

33
_T = TypeVar('_T')
44

5-
@overload
6-
def attr() -> Any: ...
7-
@overload
8-
def attr(default: _T, validator = ...) -> _T: ...
9-
@overload
10-
def attr(default: _T = ..., validator = ...) -> _T: ...
11-
@overload
12-
def attr(validator= ...) -> Any: ...
5+
def attr(default: Any = ..., validator: Any = ...) -> Any: ...
136

147
@overload
158
def attributes(maybe_cls: _T = ..., cmp: bool = ..., init: bool = ...) -> _T: ...
16-
179
@overload
1810
def attributes(maybe_cls: None = ..., cmp: bool = ..., init: bool = ...) -> Callable[[_T], _T]: ...
1911

0 commit comments

Comments
 (0)