Skip to content

Documentation for attr support #4632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 26, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions docs/source/additional_features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,78 @@ including the following:
- inheritance between generic classes
- compatibility and subtyping of generic types, including covariance of generic types
- ``super()``


.. _attrs_package:

The attrs package
*****************

`attrs <https://www.attrs.org/en/stable>`_ is a package that lets you define
classes without writing boilerplate code. Mypy can detect uses of the
package and will generate the necessary method definitions for decorated
classes using the type annotations it finds.
Type annotations can be added as follows:

.. code-block:: python

import attr
@attr.s
class A:
one: int = attr.ib() # Variable annotation (Python 3.6+)
two = attr.ib() # type: int # Type comment
three = attr.ib(type=int) # type= argument

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

.. code-block:: python

import attr
@attr.s(auto_attribs=True)
class A:
one: int
two: int = 7
three: int = attr.ib(8)

Typeshed has a couple of "white lie" annotations to make type checking
easier. ``attr.ib`` and ``attr.Factory`` actually return objects, but the
annotation says these return the types that they expect to be assigned to.
That enables this to work:

.. code-block:: python

import attr
from typing import Dict
@attr.s(auto_attribs=True)
one: int = attr.ib(8)
two: Dict[str, str] = attr.Factory(dict)
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:

.. code-block:: python

import attr
YES = True
@attr.s(init=YES)
class A:
...

* Currently, ``converter`` only supports named functions. If mypy finds something else it
will complain about not understanding the argument and the type annotation in
``__init__`` will be replaced by ``Any``.

* `Validator decorators <http://www.attrs.org/en/stable/examples.html#decorator>`_
and `default decorators <http://www.attrs.org/en/stable/examples.html#defaults>`_
are not type-checked against the attribute they are setting/validating.

* Method definitions added by mypy currently overwrite any existing method
definitions.