You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* union passthrough, first pass
* 3.7 has no types.NoneType
* No literals on 3.7
* More native unions work
* Fix maybe?
* Fixety fix
* docs in progress
* More native unions
* More union passthrough tests, docs
* Fix test
* Add test and more docs
* Pyyaml work, docs
* Skip testing literals on 3.7
* No literals on 3.7
* Test with Literal from typing
* Fix test
* Fix native unions
* Tweak tests on 3.8
* NewType tests
* More NewType work
* More NewTypes work
* Fix test
* Final tweaks
- Introduce the `use_class_methods` strategy. Learn more [here](https://catt.rs/en/latest/strategies.html#using-class-specific-structure-and-unstructure-methods).
- Implement the `union passthrough` strategy, enabling much richer union handling for preconfigured converters. [Learn more here](https://catt.rs/en/stable/strategies.html#union-passthrough).
13
14
- The `omit` parameter of {py:func}`cattrs.override` is now of type `bool | None` (from `bool`).
14
15
`None` is the new default and means to apply default _cattrs_ handling to the attribute, which is to omit the attribute if it's marked as `init=False`, and keep it otherwise.
15
16
- Fix {py:func}`format_exception() <cattrs.v.format_exception>` parameter working for recursive calls to {py:func}`transform_error <cattrs.transform_error>`.
Copy file name to clipboardExpand all lines: docs/strategies.md
+59Lines changed: 59 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -323,3 +323,62 @@ Nested(m=MyClass(a=43))
323
323
```{versionadded} 23.2.0
324
324
325
325
```
326
+
327
+
## Union Passthrough
328
+
329
+
_Found at {py:func}`cattrs.strategies.configure_union_passthrough`._
330
+
331
+
The _union passthrough_ strategy enables a {py:class}`Converter <cattrs.BaseConverter>` to structure unions and subunions of given types.
332
+
333
+
A very common use case for _cattrs_ is processing data created by other serialization libraries, such as _JSON_ or _msgpack_.
334
+
These libraries are able to directly produce values of unions inherent to the format.
335
+
For example, every JSON library can differentiate between numbers, booleans, strings and null values since these values are represented differently in the wire format.
336
+
This strategy enables _cattrs_ to offload the creation of these values to an underlying library and just validate the final value.
337
+
So, _cattrs_ preconfigured JSON converters can handle the following type:
338
+
339
+
-`bool | int | float | str | None`
340
+
341
+
Continuing the JSON example, this strategy also enables structuring subsets of unions of these values.
342
+
Accordingly, here are some examples of subset unions that are also supported:
343
+
344
+
-`bool | int`
345
+
-`int | str`
346
+
-`int | float | str`
347
+
348
+
The strategy also supports types including one or more [Literals](https://mypy.readthedocs.io/en/stable/literal_types.html#literal-types) of supported types. For example:
349
+
350
+
-`Literal["admin", "user"] | int`
351
+
-`Literal[True] | str | int | float`
352
+
353
+
The strategy also supports [NewTypes](https://mypy.readthedocs.io/en/stable/more_types.html#newtypes) of these types. For example:
354
+
355
+
```python
356
+
>>>from typing import NewType
357
+
358
+
>>> UserId = NewType("UserId", int)
359
+
360
+
>>> converter.loads("12", UserId)
361
+
12
362
+
```
363
+
364
+
Unions containing unsupported types can be handled if at least one union type is supported by the strategy; the supported union types will be checked before the rest (referred to as the _spillover_) is handed over to the converter again.
365
+
366
+
For example, if `A` and `B` are arbitrary _attrs_ classes, the union `Literal[10] | A | B` cannot be handled directly by a JSON converter.
367
+
However, the strategy will check if the value being structured matches `Literal[10]` (because this type _is_ supported) and, if not, will pass it back to the converter to be structured as `A | B` (where a different strategy can handle it).
368
+
369
+
The strategy is designed to run in _O(1)_ at structure time; it doesn't depend on the size of the union and the ordering of union members.
370
+
371
+
This strategy has been preapplied to the following preconfigured converters:
0 commit comments