Skip to content

Commit

Permalink
Implement NoneType structuring.
Browse files Browse the repository at this point in the history
This is useful to have for custom structure hooks of union types
that are also optional.
  • Loading branch information
PIG208 committed Aug 4, 2023
1 parent d1b106a commit e8c141d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
2 changes: 2 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
([#398](https://github.com/python-attrs/cattrs/issues/398) [#399](https://github.com/python-attrs/cattrs/pull/399))
- Broaden loads' type definition for the preconf orjson converter.
([#400](https://github.com/python-attrs/cattrs/pull/400))
- Implement structuring for `NoneType`.
([#408](https://github.com/python-attrs/cattrs/pull/408))

## 23.1.2 (2023-06-02)

Expand Down
14 changes: 14 additions & 0 deletions docs/structuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,20 @@ In case the conversion isn't possible, the resulting exception is propagated out

```

### `NoneType`

[`NoneType`](https://docs.python.org/3/library/types.html#types.NoneType) is
the type of `None`. Prior to Python 3.10, `NoneType` is just `type(None)`.

```python
>>> cattrs.structure(None, NoneType)
>>> cattrs.structure(1, NoneType)
Traceback (most recent call last):
...
ValueError: 1 is not None
```


## Collections and Other Generics

### Optionals
Expand Down
7 changes: 7 additions & 0 deletions src/cattrs/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ def __init__(
(float, self._structure_call),
(Enum, self._structure_call),
(Path, self._structure_call),
(NoneType, self._structure_nonetype),
]
)

Expand Down Expand Up @@ -445,6 +446,12 @@ def _structure_call(obj: Any, cl: Type[T]) -> Any:
"""
return cl(obj)

@staticmethod
def _structure_nonetype(val, cl):
if val is not None:
raise ValueError(f"{val} is not None")
return val

@staticmethod
def _structure_simple_literal(val, type):
if val not in type.__args__:
Expand Down
7 changes: 7 additions & 0 deletions tests/test_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,10 @@ class B:
A("foo"),
B("bar"),
]


def test_structuring_nonetype():
converter = BaseConverter()

assert converter.structure(None, NoneType) is None
converter.structure(1, NoneType)

0 comments on commit e8c141d

Please sign in to comment.