Skip to content

Commit 5f5c116

Browse files
authored
init false initial work (#395)
* init false initial work * Finish up init false * Fix lint
1 parent beb3e96 commit 5f5c116

12 files changed

+423
-129
lines changed

HISTORY.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## 23.2.0 (UNRELEASED)
44

5+
- **Potentially breaking**: skip _attrs_ fields marked as `init=False` by default. This change is potentially breaking for unstructuring.
6+
See [here](https://catt.rs/en/latest/customizing.html#include_init_false) for instructions on how to restore the old behavior.
7+
([#40](https://github.com/python-attrs/cattrs/issues/40) [#395](https://github.com/python-attrs/cattrs/pull/395))
8+
- The `omit` parameter of `cattrs.override()` is now of type `bool | None` (from `bool`). `None` is the new default and means to apply default `cattrs` handling to the attribute.
59
- Fix `format_exception` parameter working for recursive calls to `transform_error`
610
([#389](https://github.com/python-attrs/cattrs/issues/389)
711
- [_attrs_ aliases](https://www.attrs.org/en/stable/init.html#private-attributes-and-aliases) are now supported, although aliased fields still map to their attribute name instead of their alias by default when un/structuring.
@@ -42,7 +46,7 @@
4246
([#319](https://github.com/python-attrs/cattrs/issues/319) [#327](https://github.com/python-attrs/cattrs/pull/327>))
4347
- `pathlib.Path` is now supported by default.
4448
([#81](https://github.com/python-attrs/cattrs/issues/81))
45-
- Add `cbor2` serialization library to the `cattr.preconf` package.
49+
- Add `cbor2` serialization library to the `cattrs.preconf` package.
4650
- Add optional dependencies for `cattrs.preconf` third-party libraries. ([#337](https://github.com/python-attrs/cattrs/pull/337))
4751
- All preconf converters now allow overriding the default `unstruct_collection_overrides` in `make_converter`.
4852
([#350](https://github.com/python-attrs/cattrs/issues/350) [#353](https://github.com/python-attrs/cattrs/pull/353))

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: clean clean-test clean-pyc clean-build docs help bench bench-cmp
1+
.PHONY: clean clean-test clean-pyc clean-build docs help bench bench-cmp test
22
.DEFAULT_GOAL := help
33
define BROWSER_PYSCRIPT
44
import os, webbrowser, sys

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ destructure them.
141141
- Custom converters for any type can be registered using `register_structure_hook`.
142142

143143
_cattrs_ comes with preconfigured converters for a number of serialization libraries, including json, msgpack, cbor2, bson, yaml and toml.
144-
For details, see the [cattr.preconf package](https://catt.rs/en/stable/preconf.html).
144+
For details, see the [cattrs.preconf package](https://catt.rs/en/stable/preconf.html).
145145

146146
## Design Decisions
147147

docs/Makefile

+2-7
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,10 @@
33

44
# You can set these variables from the command line.
55
SPHINXOPTS =
6-
SPHINXBUILD = sphinx-build
6+
SPHINXBUILD = pdm run sphinx-build
77
PAPER =
88
BUILDDIR = _build
99

10-
# User-friendly check for sphinx-build
11-
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12-
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13-
endif
14-
1510
# Internal variables.
1611
PAPEROPT_a4 = -D latex_paper_size=a4
1712
PAPEROPT_letter = -D latex_paper_size=letter
@@ -177,4 +172,4 @@ pseudoxml:
177172
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
178173

179174
apidoc:
180-
sphinx-apidoc -o . ../src/cattrs/ -f
175+
pdm run sphinx-apidoc -o . ../src/cattrs/ -f

docs/converters.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ global converter. Changes done to this global converter, such as registering new
66
structure and unstructure hooks, affect all code using the global
77
functions.
88

9-
## Global converter
9+
## Global Converter
1010

1111
A global converter is provided for convenience as `cattrs.global_converter`.
1212
The following functions implicitly use this global converter:
@@ -21,7 +21,7 @@ Changes made to the global converter will affect the behavior of these functions
2121
Larger applications are strongly encouraged to create and customize a different,
2222
private instance of {class}`cattrs.Converter`.
2323

24-
## Converter objects
24+
## Converter Objects
2525

2626
To create a private converter, simply instantiate a {class}`cattrs.Converter`.
2727
Currently, a converter contains the following state:

docs/customizing.md

+40-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ them for types using {meth}`Converter.register_structure_hook() <cattrs.BaseConv
1313
{meth}`Converter.register_unstructure_hook() <cattrs.BaseConverter.register_unstructure_hook>`. This approach is the most
1414
flexible but also requires the most amount of boilerplate.
1515

16-
## Using `cattrs.gen` generators
16+
## Using `cattrs.gen` Generators
1717

1818
_cattrs_ includes a module, {mod}`cattrs.gen`, which allows for generating and compiling specialized functions for unstructuring _attrs_ classes.
1919

@@ -25,9 +25,8 @@ Currently, the overrides only support generating dictionary un/structuring funct
2525

2626
### `omit_if_default`
2727

28-
This override can be applied on a per-class or per-attribute basis. The generated
29-
unstructuring function will skip unstructuring values that are equal to their
30-
default or factory values.
28+
This override can be applied on a per-class or per-attribute basis.
29+
The generated unstructuring function will skip unstructuring values that are equal to their default or factory values.
3130

3231
```{doctest}
3332
@@ -131,9 +130,8 @@ ExampleClass(klass=1)
131130

132131
### `omit`
133132

134-
This override can only be applied to individual attributes. Using the `omit`
135-
override will simply skip the attribute completely when generating a structuring
136-
or unstructuring function.
133+
This override can only be applied to individual attributes.
134+
Using the `omit` override will simply skip the attribute completely when generating a structuring or unstructuring function.
137135

138136
```{doctest}
139137
@@ -198,3 +196,38 @@ AliasClass(number=2)
198196
```{versionadded} 23.2.0
199197
200198
```
199+
200+
### `include_init_false`
201+
202+
By default, _attrs_ fields defined as `init=False` are skipped when un/structuring.
203+
By generating your un/structure function with `_cattrs_include_init_false=True`, all `init=False` fields will be included for un/structuring.
204+
205+
```{doctest}
206+
207+
>>> from cattrs.gen import make_dict_structure_fn
208+
>>>
209+
>>> @define
210+
... class ClassWithInitFalse:
211+
... number: int = field(default=1, init=False)
212+
>>>
213+
>>> c = cattrs.Converter()
214+
>>> hook = make_dict_structure_fn(ClassWithInitFalse, c, _cattrs_include_init_false=True)
215+
>>> c.register_structure_hook(ClassWithInitFalse, hook)
216+
>>> c.structure({"number": 2}, ClassWithInitFalse)
217+
ClassWithInitFalse(number=2)
218+
```
219+
220+
A single attribute can be included by overriding it with `omit=False`.
221+
222+
```{doctest}
223+
224+
>>> c = cattrs.Converter()
225+
>>> hook = make_dict_structure_fn(ClassWithInitFalse, c, number=override(omit=False))
226+
>>> c.register_structure_hook(ClassWithInitFalse, hook)
227+
>>> c.structure({"number": 2}, ClassWithInitFalse)
228+
ClassWithInitFalse(number=2)
229+
```
230+
231+
```{versionadded} 23.2.0
232+
233+
```

0 commit comments

Comments
 (0)