Skip to content

Support for attr.has and attr.AttrsInstance #15980

Closed

Description

@koogoro

Feature
Recently, mypy added a plugin for attr.fields that tries to detect whether a type is an attr.s-decorated class, and reports an error if it isn't. However, attrs has a couple ways to check or annotate that a class is an attr.s-decorated class: attr.has and attr.AttrsInstance, neither of which seem to be supported by mypy right now.

attr.AttrsInstance is a protocol defined in the attrs internal stubs (https://github.com/python-attrs/attrs/blob/main/src/attr/__init__.pyi#L74) that represents that an object of an attr.s-decorated class. Right now, the plugin doesn't recognize attr.AttrsInstance, so it will report an error when trying to call e.g. attr.fields on a type[attr.AttrsInstance].

attr.has is a method that checks whether a class is attr.s-decorated. The plugin won't recognize this as a valid way to ensure attrs version 22.2.0 updated the internal stubs for attr.has to be a TypeGuard for type[attr.AttrsInstance]: (https://github.com/python-attrs/attrs/blob/main/src/attr/__init__.pyi#L541), so supporting attr.AttrsInstance may be sufficient when using sufficiently new stubs for attrs.

Pitch

A possible use for attr.has:

T = TypeVar('T')

def deserialize(attr_cls: type[T], value:bytes) -> T:
    assert attr.has(cls)
    fields = attr.fields(cls)
    ...

A possible use for attr.AttrsInstance:

T = TypeVar('T', bound=attr.AttrsInstance)

def deserialize(attr_cls: type[T], value: bytes) -> T:
    fields = attr.fields(attr_cls)
    ...

Activity

  1. koogoro commented on Aug 29, 2023

    @koogoro
    CollaboratorAuthor

    @hauntsaninja this is the thing that I was having trouble with with the new behavior of the plugin. I think it probably counts as a feature request because we didn't really support these before either, we just wouldn't error on them because we didn't check the types around attr.fields.

  2. added a commit that references this issue on Aug 30, 2023
    2298829
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions