Extending

Each attrs-decorated class has a __attrs_attrs__ class attribute. It is a tuple of attr.Attribute carrying meta-data about each attribute.

So it is fairly simple to build your own decorators on top of attrs:

>>> import attr
>>> def print_attrs(cls):
...     print(cls.__attrs_attrs__)
>>> @print_attrs
... @attr.s
... class C(object):
...     a = attr.ib()
(Attribute(name='a', default=NOTHING, validator=None, repr=True, cmp=True, hash=True, init=True, convert=None),)

Warning

The attr.s() decorator must be applied first because it puts __attrs_attrs__ in place! That means that is has to come after your decorator because:

@a
@b
def f():
   pass

is just syntactic sugar for:

def original_f():
   pass

f = a(b(original_f))