The attrs package

attrs is a package that lets you defineclasses without writing boilerplate code. Mypy can detect uses of thepackage and will generate the necessary method definitions for decoratedclasses using the type annotations it finds.Type annotations can be added as follows:

  1. import attr
  2.  
  3. @attr.s
  4. class A:
  5. one: int = attr.ib() # Variable annotation (Python 3.6+)
  6. two = attr.ib() # type: int # Type comment
  7. three = attr.ib(type=int) # type= argument

If you’re using auto_attribs=True you must use variable annotations.

  1. import attr
  2.  
  3. @attr.s(auto_attribs=True)
  4. class A:
  5. one: int
  6. two: int = 7
  7. three: int = attr.ib(8)

Typeshed has a couple of “white lie” annotations to make type checkingeasier. attr.ib() and attr.Factory actually return objects, but theannotation says these return the types that they expect to be assigned to.That enables this to work:

  1. import attr
  2. from typing import Dict
  3.  
  4. @attr.s(auto_attribs=True)
  5. class A:
  6. one: int = attr.ib(8)
  7. two: Dict[str, str] = attr.Factory(dict)
  8. bad: str = attr.ib(16) # Error: can't assign int to str

Caveats/Known Issues

  • The detection of attr classes and attributes works by function name only.This means that if you have your own helper functions that, for example,return attr.ib() mypy will not see them.

  • All boolean arguments that mypy cares about must be literal True or False.e.g the following will not work:

  1. import attr
  2. YES = True
  3. @attr.s(init=YES)
  4. class A:
  5. ...
  • Currently, converter only supports named functions. If mypy finds something else itwill complain about not understanding the argument and the type annotation ininit will be replaced by Any.

  • Validator decoratorsand default decoratorsare not type-checked against the attribute they are setting/validating.

  • Method definitions added by mypy currently overwrite any existing methoddefinitions.