Skip to content

Commit

Permalink
Clarify that annotation-only doesn't work w/ decorators (python-attrs…
Browse files Browse the repository at this point in the history
  • Loading branch information
hynek authored Feb 9, 2019
1 parent 2e2748a commit bb9b83c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 3 deletions.
3 changes: 2 additions & 1 deletion docs/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ This is when default values come into play:
C(a=42, b=[], c=[], d={})

It's important that the decorated method -- or any other method or property! -- doesn't have the same name as the attribute, otherwise it would overwrite the attribute definition.
You also cannot use type annotations to elide the :func:`attr.ib` call for ``d`` as explained in :doc:`types`.


Please note that as with function and method signatures, ``default=[]`` will *not* do what you may think it might do:
Expand Down Expand Up @@ -161,7 +162,7 @@ If the value does not pass the validator's standards, it just raises an appropri
...
ValueError: x must be smaller or equal to 42

Again, it's important that the decorated method doesn't have the same name as the attribute.
Again, it's important that the decorated method doesn't have the same name as the attribute and that you can't elide the call to :func:`attr.ib`.


Callables
Expand Down
14 changes: 12 additions & 2 deletions docs/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,19 @@ That means that on modern Python versions, the declaration part of the example f
>>> attr.fields(SomeClass).a_number.type
<class 'int'>

You can still use :func:`attr.ib` for advanced features, but you don't have to.
You will still need :func:`attr.ib` for advanced features, but not for the common cases.

Please note that these types are *only metadata* that can be queried from the class and they aren't used for anything out of the box!
One of those features are the decorator-based features like defaults.
It's important to remember that ``attrs`` doesn't do any magic behind your back.
All the decorators are implemented using an object that is returned by the call to :func:`attr.ib`.

Attributes that only carry a class annotation do not have that object so trying to call a method on it will inevitably fail.

*****

Please note that types -- however added -- are *only metadata* that can be queried from the class and they aren't used for anything out of the box!

In practice, their biggest usefulness shows in combination with mypy.


mypy
Expand Down

0 comments on commit bb9b83c

Please sign in to comment.