Skip to content

Commit f37a24a

Browse files
committed
Document prefer_attrib_converters
1 parent 08a3bd0 commit f37a24a

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

Diff for: docs/structuring.rst

+42-4
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ and their own converters work out of the box. Given a mapping ``d`` and class
285285
>>> @attr.s
286286
... class A:
287287
... a = attr.ib()
288-
... b = attr.ib(converter=int)
288+
... b = attr.ib()
289289
...
290290
>>> cattr.structure({'a': 1, 'b': '2'}, A)
291291
A(a=1, b=2)
@@ -299,7 +299,7 @@ Classes like these deconstructed into tuples can be structured using
299299
>>> @attr.s
300300
... class A:
301301
... a = attr.ib()
302-
... b = attr.ib(converter=int)
302+
... b = attr.ib(type=int)
303303
...
304304
>>> cattr.structure_attrs_fromtuple(['string', '2'], A)
305305
A(a='string', b=2)
@@ -313,14 +313,52 @@ Loading from tuples can be made the default by creating a new ``Converter`` with
313313
>>> @attr.s
314314
... class A:
315315
... a = attr.ib()
316-
... b = attr.ib(converter=int)
316+
... b = attr.ib(type=int)
317317
...
318318
>>> converter.structure(['string', '2'], A)
319319
A(a='string', b=2)
320320
321321
Structuring from tuples can also be made the default for specific classes only;
322322
see registering custom structure hooks below.
323323
324+
325+
Using attribute types and converters
326+
------------------------------------
327+
328+
By default, calling "structure" will use hooks registered using ``cattr.register_structure_hook``,
329+
to convert values to the attribute type, and fallback to invoking any converters registered on
330+
attributes with ``attrib``.
331+
332+
.. doctest::
333+
334+
>>> from ipaddress import IPv4Address, ip_address
335+
>>> converter = cattr.Converter()
336+
337+
# Note: register_structure_hook has not been called, so this will fallback to 'ip_address'
338+
>>> @attr.s
339+
... class A:
340+
... a = attr.ib(type=IPv4Address, converter=ip_address)
341+
342+
>>> converter.structure({'a': '127.0.0.1'}, A)
343+
A(a=IPv4Address('127.0.0.1'))
344+
345+
Priority is still given to hooks registered with ``cattr.register_structure_hook``, but this priority
346+
can be inverted by setting ``prefer_attrib_converters`` to ``True``.
347+
348+
.. doctest::
349+
350+
>>> converter = cattr.Converter(prefer_attrib_converters=True)
351+
352+
>>> converter.register_structure_hook(int, lambda v, t: int(v))
353+
354+
>>> @attr.s
355+
... class A:
356+
... a = attr.ib(type=int, converter=lambda v: int(v) + 5)
357+
358+
>>> converter.structure({'a': '10'}, A)
359+
A(a=15)
360+
361+
324362
Complex ``attrs`` classes and dataclasses
325363
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
326364
@@ -376,7 +414,7 @@ Here's an example involving a simple, classic (i.e. non-``attrs``) Python class.
376414
>>> cattr.structure({'a': 1}, C)
377415
Traceback (most recent call last):
378416
...
379-
ValueError: Unsupported type: <class '__main__.C'>. Register a structure hook for it.
417+
StructureHandlerNotFoundError: Unsupported type: <class '__main__.C'>. Register a structure hook for it.
380418
>>>
381419
>>> cattr.register_structure_hook(C, lambda d, t: C(**d))
382420
>>> cattr.structure({'a': 1}, C)

0 commit comments

Comments
 (0)