@@ -285,7 +285,7 @@ and their own converters work out of the box. Given a mapping ``d`` and class
285
285
>>> @attr.s
286
286
... class A:
287
287
... a = attr.ib()
288
- ... b = attr.ib(converter=int )
288
+ ... b = attr.ib()
289
289
...
290
290
>>> cattr.structure({'a': 1, 'b': '2'}, A)
291
291
A(a=1, b=2)
@@ -299,7 +299,7 @@ Classes like these deconstructed into tuples can be structured using
299
299
>>> @attr.s
300
300
... class A:
301
301
... a = attr.ib()
302
- ... b = attr.ib(converter =int)
302
+ ... b = attr.ib(type =int)
303
303
...
304
304
>>> cattr.structure_attrs_fromtuple(['string', '2'], A)
305
305
A(a='string', b=2)
@@ -313,14 +313,52 @@ Loading from tuples can be made the default by creating a new ``Converter`` with
313
313
>>> @attr.s
314
314
... class A:
315
315
... a = attr.ib()
316
- ... b = attr.ib(converter =int)
316
+ ... b = attr.ib(type =int)
317
317
...
318
318
>>> converter.structure(['string', '2'], A)
319
319
A(a='string', b=2)
320
320
321
321
Structuring from tuples can also be made the default for specific classes only;
322
322
see registering custom structure hooks below.
323
323
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
+
324
362
Complex ``attrs`` classes and dataclasses
325
363
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
326
364
@@ -376,7 +414,7 @@ Here's an example involving a simple, classic (i.e. non-``attrs``) Python class.
376
414
>>> cattr.structure({'a': 1}, C)
377
415
Traceback (most recent call last):
378
416
...
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.
380
418
>>>
381
419
>>> cattr.register_structure_hook(C, lambda d, t: C(**d))
382
420
>>> cattr.structure({'a': 1}, C)
0 commit comments