attrs 17.1.0
Hynek Schlawack
hs at ox.cx
Tue May 16 14:23:31 EDT 2017
Hi everyone,
fresh for PyCon US 2017, the attrs team is relieved to present you the much-delayed attrs 17.1.0!
Full changes: http://www.attrs.org/en/stable/changelog.html
***
First the bad news: until 17.1.0, attrs’ logic regarding when to create a __hash__ method was in conflict with Python’s specification. If you use instances as dict keys or put them into sets, you have to either make them frozen explicitly by passing `frozen=True` or implicitly by pinky-swearing to not mutate them and force the creation of __hash__ using `hash=True`.
*Please* double check before upgrading!
We’re honestly sorry but didn’t see any better way to handle this. But mind you: hashing mutable objects is a bug so the breakage you’ll encounter may very well be the surfacing of latent, sneaky bugs.
***
Now the good news!
This release took very long (we promise improvement!) which led to the accumulation of a lot of great new features. A few highlights:
# Decorators for validators
>>> @attr.s
... class C(object):
... x = attr.ib()
... @x.validator
... def check(self, attribute, value):
... if value > 42:
... raise ValueError("y must be smaller or equal to 42")
>>> C(42)
C(x=42)
>>> C(43)
Traceback (most recent call last):
...
ValueError: x must be smaller or equal to 42
# Decorators for defaults & self in factories
One of the most requested features: you can base the default of an attribute on a preceding attribute:
>>> @attr.s
... class C(object):
... x = attr.ib(default=1)
... y = attr.ib(default=attr.Factory(lambda self: self.x + 1, takes_self=True))
... z = attr.ib()
... @z.default
... def name_does_not_matter(self):
... return self.x + 1
>>> C()
C(x=1, y=2, z=3)
# New Validators: in_() & and_()
in_() allows to check whether a value is part of an enum or any container:
>>> import enum
>>> class State(enum.Enum):
... ON = "on"
... OFF = "off"
>>> @attr.s
... class C(object):
... state = attr.ib(validator=attr.validators.in_(State))
... val = attr.ib(validator=attr.validators.in_([1, 2, 3]))
>>> C(State.ON, 1)
C(state=<State.ON: 'on'>, val=1)
>>> C("on", 1)
Traceback (most recent call last):
...
ValueError: 'state' must be in <enum 'State'> (got 'on')
>>> C(State.ON, 4)
Traceback (most recent call last):
...
ValueError: 'val' must be in [1, 2, 3] (got 4)
and_() allows you to compose multiple validators to one. As syntactic sugar, you can also just pass a list to `validator=`. Therefore the following lines are equivalent:
x = attr.ib(validator=attr.validators.and_(v1, v2, v3))
x = attr.ib(validator=[v1, v2, v3])
For the attrs team
Hynek
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP
URL: <http://mail.python.org/pipermail/python-announce-list/attachments/20170516/6cd53930/attachment.sig>
More information about the Python-announce-list
mailing list