diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index 0f748cc140e8..ec6dc71c5691 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -68,7 +68,6 @@ TupleType, Type, TypeOfAny, - TypeType, TypeVarType, UninhabitedType, UnionType, @@ -1071,44 +1070,3 @@ def evolve_function_sig_callback(ctx: mypy.plugin.FunctionSigContext) -> Callabl fallback=ctx.default_signature.fallback, name=f"{ctx.default_signature.name} of {inst_type_str}", ) - - -def fields_function_sig_callback(ctx: mypy.plugin.FunctionSigContext) -> CallableType: - """Provide the signature for `attrs.fields`.""" - if len(ctx.args) != 1 or len(ctx.args[0]) != 1: - return ctx.default_signature - - proper_type = get_proper_type(ctx.api.get_expression_type(ctx.args[0][0])) - - # fields(Any) -> Any, fields(type[Any]) -> Any - if ( - isinstance(proper_type, AnyType) - or isinstance(proper_type, TypeType) - and isinstance(proper_type.item, AnyType) - ): - return ctx.default_signature - - cls = None - arg_types = ctx.default_signature.arg_types - - if isinstance(proper_type, TypeVarType): - inner = get_proper_type(proper_type.upper_bound) - if isinstance(inner, Instance): - # We need to work arg_types to compensate for the attrs stubs. - arg_types = [proper_type] - cls = inner.type - elif isinstance(proper_type, CallableType): - cls = proper_type.type_object() - - if cls is not None and MAGIC_ATTR_NAME in cls.names: - # This is a proper attrs class. - ret_type = cls.names[MAGIC_ATTR_NAME].type - assert ret_type is not None - return ctx.default_signature.copy_modified(arg_types=arg_types, ret_type=ret_type) - - ctx.api.fail( - f'Argument 1 to "fields" has incompatible type "{format_type_bare(proper_type, ctx.api.options)}"; expected an attrs class', - ctx.context, - ) - - return ctx.default_signature diff --git a/mypy/plugins/default.py b/mypy/plugins/default.py index b60fc3873c04..b41ad98b13a6 100644 --- a/mypy/plugins/default.py +++ b/mypy/plugins/default.py @@ -57,8 +57,6 @@ def get_function_signature_hook( if fullname in ("attr.evolve", "attrs.evolve", "attr.assoc", "attrs.assoc"): return attrs.evolve_function_sig_callback - elif fullname in ("attr.fields", "attrs.fields"): - return attrs.fields_function_sig_callback elif fullname == "dataclasses.replace": return dataclasses.replace_function_sig_callback return None diff --git a/test-data/unit/check-plugin-attrs.test b/test-data/unit/check-plugin-attrs.test index 88a541c28ac2..348c8243ca8e 100644 --- a/test-data/unit/check-plugin-attrs.test +++ b/test-data/unit/check-plugin-attrs.test @@ -1556,60 +1556,6 @@ takes_attrs_cls(A(1, "")) # E: Argument 1 to "takes_attrs_cls" has incompatible takes_attrs_instance(A) # E: Argument 1 to "takes_attrs_instance" has incompatible type "Type[A]"; expected "AttrsInstance" # N: ClassVar protocol member AttrsInstance.__attrs_attrs__ can never be matched by a class object [builtins fixtures/plugin_attrs.pyi] -[case testAttrsFields] -import attr -from attrs import fields as f # Common usage. - -@attr.define -class A: - b: int - c: str - -reveal_type(f(A)) # N: Revealed type is "Tuple[attr.Attribute[builtins.int], attr.Attribute[builtins.str], fallback=__main__.A.____main___A_AttrsAttributes__]" -reveal_type(f(A)[0]) # N: Revealed type is "attr.Attribute[builtins.int]" -reveal_type(f(A).b) # N: Revealed type is "attr.Attribute[builtins.int]" -f(A).x # E: "____main___A_AttrsAttributes__" has no attribute "x" - -[builtins fixtures/plugin_attrs.pyi] - -[case testAttrsGenericFields] -from typing import TypeVar - -import attr -from attrs import fields - -@attr.define -class A: - b: int - c: str - -TA = TypeVar('TA', bound=A) - -def f(t: TA) -> None: - reveal_type(fields(t)) # N: Revealed type is "Tuple[attr.Attribute[builtins.int], attr.Attribute[builtins.str], fallback=__main__.A.____main___A_AttrsAttributes__]" - reveal_type(fields(t)[0]) # N: Revealed type is "attr.Attribute[builtins.int]" - reveal_type(fields(t).b) # N: Revealed type is "attr.Attribute[builtins.int]" - fields(t).x # E: "____main___A_AttrsAttributes__" has no attribute "x" - - -[builtins fixtures/plugin_attrs.pyi] - -[case testNonattrsFields] -# flags: --no-strict-optional -from typing import Any, cast, Type -from attrs import fields - -class A: - b: int - c: str - -fields(A) # E: Argument 1 to "fields" has incompatible type "Type[A]"; expected an attrs class -fields(None) # E: Argument 1 to "fields" has incompatible type "None"; expected an attrs class -fields(cast(Any, 42)) -fields(cast(Type[Any], 43)) - -[builtins fixtures/plugin_attrs.pyi] - [case testAttrsInitMethodAlwaysGenerates] from typing import Tuple import attr diff --git a/test-data/unit/lib-stub/attr/__init__.pyi b/test-data/unit/lib-stub/attr/__init__.pyi index 24ffc0f3f275..1a3838aa3ab1 100644 --- a/test-data/unit/lib-stub/attr/__init__.pyi +++ b/test-data/unit/lib-stub/attr/__init__.pyi @@ -247,5 +247,3 @@ def field( def evolve(inst: _T, **changes: Any) -> _T: ... def assoc(inst: _T, **changes: Any) -> _T: ... - -def fields(cls: type) -> Any: ... diff --git a/test-data/unit/lib-stub/attrs/__init__.pyi b/test-data/unit/lib-stub/attrs/__init__.pyi index a575f97da9bc..bf31274b3eb9 100644 --- a/test-data/unit/lib-stub/attrs/__init__.pyi +++ b/test-data/unit/lib-stub/attrs/__init__.pyi @@ -131,5 +131,3 @@ def field( def evolve(inst: _T, **changes: Any) -> _T: ... def assoc(inst: _T, **changes: Any) -> _T: ... - -def fields(cls: type) -> Any: ...