From d0adb05b5f1884f09e9454643abe549dda303469 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Fri, 23 Feb 2018 18:15:07 +0000 Subject: [PATCH] Revert "Better support for converter in attrs plugin. (#4607)" This reverts commit f384df8a56b319a50d60ae31ba8159c2ae3ababe. --- mypy/plugin.py | 14 +- mypy/plugins/attrs.py | 30 ++--- test-data/unit/check-attr.test | 15 --- test-data/unit/check-incremental.test | 177 -------------------------- 4 files changed, 12 insertions(+), 224 deletions(-) diff --git a/mypy/plugin.py b/mypy/plugin.py index ba356ef43ff2..3e1e2bea3011 100644 --- a/mypy/plugin.py +++ b/mypy/plugin.py @@ -2,12 +2,12 @@ from abc import abstractmethod from functools import partial -from typing import Callable, List, Tuple, Optional, NamedTuple, TypeVar, Dict +from typing import Callable, List, Tuple, Optional, NamedTuple, TypeVar import mypy.plugins.attrs from mypy.nodes import ( Expression, StrExpr, IntExpr, UnaryExpr, Context, DictExpr, ClassDef, - TypeInfo, SymbolTableNode, MypyFile + TypeInfo, SymbolTableNode ) from mypy.tvar_scope import TypeVarScope from mypy.types import ( @@ -61,7 +61,6 @@ def named_generic_type(self, name: str, args: List[Type]) -> Instance: class SemanticAnalyzerPluginInterface: """Interface for accessing semantic analyzer functionality in plugins.""" - modules = None # type: Dict[str, MypyFile] options = None # type: Options msg = None # type: MessageBuilder @@ -94,15 +93,6 @@ def class_type(self, info: TypeInfo) -> Type: def lookup_fully_qualified(self, name: str) -> SymbolTableNode: raise NotImplementedError - @abstractmethod - def lookup_fully_qualified_or_none(self, name: str) -> Optional[SymbolTableNode]: - raise NotImplementedError - - @abstractmethod - def lookup_qualified(self, name: str, ctx: Context, - suppress_errors: bool = False) -> Optional[SymbolTableNode]: - raise NotImplementedError - # A context for a function hook that infers the return type of a function with # a special signature. diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index f2385f87de0f..5ba4cd2c236b 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -4,7 +4,6 @@ import mypy.plugin # To avoid circular imports. from mypy.exprtotype import expr_to_unanalyzed_type, TypeTranslationError -from mypy.fixup import lookup_qualified_stnode from mypy.nodes import ( Context, Argument, Var, ARG_OPT, ARG_POS, TypeInfo, AssignmentStmt, TupleExpr, ListExpr, NameExpr, CallExpr, RefExpr, FuncBase, @@ -55,21 +54,14 @@ def argument(self, ctx: 'mypy.plugin.ClassDefContext') -> Argument: if self.converter_name: # When a converter is set the init_type is overriden by the first argument # of the converter method. - converter = lookup_qualified_stnode(ctx.api.modules, self.converter_name, True) - if not converter: - # The converter may be a local variable. Check there too. - converter = ctx.api.lookup_qualified(self.converter_name, self.info, True) - + converter = ctx.api.lookup_fully_qualified(self.converter_name) if (converter and converter.type and isinstance(converter.type, CallableType) and converter.type.arg_types): init_type = converter.type.arg_types[0] else: - init_type = AnyType(TypeOfAny.from_error) - elif self.converter_name == '': - # This means we had a converter but it's not of a type we can infer. - init_type = AnyType(TypeOfAny.from_error) + init_type = None if init_type is None: if ctx.api.options.disallow_untyped_defs: @@ -325,16 +317,14 @@ def _attribute_from_attrib_maker(ctx: 'mypy.plugin.ClassDefContext', def _get_converter_name(converter: Optional[Expression]) -> Optional[str]: """Return the full name of the converter if it exists and is a simple function.""" # TODO: Support complex converters, e.g. lambdas, calls, etc. - if converter: - if (isinstance(converter, RefExpr) - and converter.node - and isinstance(converter.node, FuncBase) - and converter.node.type - and isinstance(converter.node.type, CallableType) - and converter.node.type.arg_types): - return converter.node.fullname() - # Signal that we have an unsupported converter. - return '' + if (converter + and isinstance(converter, RefExpr) + and converter.node + and isinstance(converter.node, FuncBase) + and converter.node.type + and isinstance(converter.node.type, CallableType) + and converter.node.type.arg_types): + return converter.node.fullname() return None diff --git a/test-data/unit/check-attr.test b/test-data/unit/check-attr.test index c0547b28920f..7062115876ec 100644 --- a/test-data/unit/check-attr.test +++ b/test-data/unit/check-attr.test @@ -532,21 +532,6 @@ class C: [builtins fixtures/list.pyi] -[case testAttrsUsingUnsupportedConverter] -import attr -class Thing: - def do_it(self, int) -> str: - ... -thing = Thing() -def factory(default: int): - ... -@attr.s -class C: - x: str = attr.ib(converter=thing.do_it) - y: str = attr.ib(converter=lambda x: x) - z: str = attr.ib(converter=factory(8)) -reveal_type(C) # E: Revealed type is 'def (x: Any, y: Any, z: Any) -> __main__.C' -[builtins fixtures/list.pyi] [case testAttrsUsingConverterAndSubclass] import attr diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 20ab89ef35c0..dc94a64402da 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -3745,183 +3745,6 @@ class C(A, B): [out1] [out2] -[case testAttrsIncrementalConverterInSubmodule] -from a.a import A -reveal_type(A) -[file a/__init__.py] -[file a/a.py] -from typing import Optional -def converter(s:Optional[int]) -> int: - ... - -import attr -@attr.s -class A: - x: int = attr.ib(converter=converter) - -[builtins fixtures/list.pyi] -[out1] -main:2: error: Revealed type is 'def (x: Union[builtins.int, builtins.None]) -> a.a.A' -[out2] -main:2: error: Revealed type is 'def (x: Union[builtins.int, builtins.None]) -> a.a.A' - -[case testAttrsIncrementalConverterManyStyles] -from base import Base -reveal_type(Base) -from subclass import A, B -reveal_type(A) -reveal_type(B) -from submodule.base import SubBase -reveal_type(SubBase) -from submodule.subclass import AA, BB -reveal_type(AA) -reveal_type(BB) -from submodule.subsubclass import SubAA, SubBB -reveal_type(SubAA) -reveal_type(SubBB) - -[file foo.py] -from typing import Optional -def maybe_int(x: Optional[int]) -> int: - ... -[file bar.py] -from typing import Optional -def maybe_bool(x: Optional[bool]) -> bool: - ... -[file base.py] -from typing import Optional -import attr -import bar -from foo import maybe_int -def maybe_str(x: Optional[str]) -> str: - ... -@attr.s -class Base: - x: int = attr.ib(converter=maybe_int) - y: str = attr.ib(converter=maybe_str) - z: bool = attr.ib(converter=bar.maybe_bool) -[file subclass.py] -from typing import Optional -import attr -from base import Base -@attr.s -class A(Base): pass - -import bar -from foo import maybe_int -def maybe_str(x: Optional[str]) -> str: - ... -@attr.s -class B(Base): - xx: int = attr.ib(converter=maybe_int) - yy: str = attr.ib(converter=maybe_str) - zz: bool = attr.ib(converter=bar.maybe_bool) - -[file submodule/__init__.py] -[file submodule/base.py] -from typing import Optional -import attr -import bar -from foo import maybe_int -def maybe_str(x: Optional[str]) -> str: - ... -@attr.s -class SubBase: - x: int = attr.ib(converter=maybe_int) - y: str = attr.ib(converter=maybe_str) - z: bool = attr.ib(converter=bar.maybe_bool) - -[file submodule/subclass.py] -from typing import Optional -import attr -from base import Base -@attr.s -class AA(Base): pass - -import bar -from foo import maybe_int -def maybe_str(x: Optional[str]) -> str: - ... -@attr.s -class BB(Base): - xx: int = attr.ib(converter=maybe_int) - yy: str = attr.ib(converter=maybe_str) - zz: bool = attr.ib(converter=bar.maybe_bool) - -[file submodule/subsubclass.py] -from typing import Optional -import attr -from .base import SubBase -@attr.s -class SubAA(SubBase): pass - -import bar -from foo import maybe_int -def maybe_str(x: Optional[str]) -> str: - ... -@attr.s -class SubBB(SubBase): - xx: int = attr.ib(converter=maybe_int) - yy: str = attr.ib(converter=maybe_str) - zz: bool = attr.ib(converter=bar.maybe_bool) -[builtins fixtures/list.pyi] -[out1] -main:2: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> base.Base' -main:4: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> subclass.A' -main:5: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None], xx: Union[builtins.int, builtins.None], yy: Union[builtins.str, builtins.None], zz: Union[builtins.bool, builtins.None]) -> subclass.B' -main:7: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> submodule.base.SubBase' -main:9: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> submodule.subclass.AA' -main:10: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None], xx: Union[builtins.int, builtins.None], yy: Union[builtins.str, builtins.None], zz: Union[builtins.bool, builtins.None]) -> submodule.subclass.BB' -main:12: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> submodule.subsubclass.SubAA' -main:13: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None], xx: Union[builtins.int, builtins.None], yy: Union[builtins.str, builtins.None], zz: Union[builtins.bool, builtins.None]) -> submodule.subsubclass.SubBB' -[out2] -main:2: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> base.Base' -main:4: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> subclass.A' -main:5: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None], xx: Union[builtins.int, builtins.None], yy: Union[builtins.str, builtins.None], zz: Union[builtins.bool, builtins.None]) -> subclass.B' -main:7: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> submodule.base.SubBase' -main:9: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> submodule.subclass.AA' -main:10: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None], xx: Union[builtins.int, builtins.None], yy: Union[builtins.str, builtins.None], zz: Union[builtins.bool, builtins.None]) -> submodule.subclass.BB' -main:12: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None]) -> submodule.subsubclass.SubAA' -main:13: error: Revealed type is 'def (x: Union[builtins.int, builtins.None], y: Union[builtins.str, builtins.None], z: Union[builtins.bool, builtins.None], xx: Union[builtins.int, builtins.None], yy: Union[builtins.str, builtins.None], zz: Union[builtins.bool, builtins.None]) -> submodule.subsubclass.SubBB' - -[case testAttrsIncrementalConverterInFunction] -import attr -def foo() -> None: - def foo(x: str) -> int: - ... - @attr.s - class A: - x: int = attr.ib(converter=foo) - reveal_type(A) -[builtins fixtures/list.pyi] -[out1] -main:8: error: Revealed type is 'def (x: str?) -> __main__.A@5' -[out2] -main:8: error: Revealed type is 'def (x: str?) -> __main__.A@5' - -[case testAttrsIncrementalConverterInSubmoduleForwardRef] -from a.a import A -reveal_type(A) -[file a/__init__.py] -[file a/a.py] -from typing import List -def converter(s:F) -> int: - ... - -import attr -@attr.s -class A: - x: int = attr.ib(converter=converter) - -F = List[int] - -[builtins fixtures/list.pyi] -[out1] -main:2: error: Revealed type is 'def (x: builtins.list[builtins.int]) -> a.a.A' -[out2] -main:2: error: Revealed type is 'def (x: builtins.list[builtins.int]) -> a.a.A' - - [case testAttrsIncrementalThreeRuns] from a import A A(5)