Skip to content

Commit

Permalink
feature: Support Pydantic V2 (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
antonagestam authored Jun 20, 2023
1 parent 9e544ae commit b1e3b4c
Show file tree
Hide file tree
Showing 10 changed files with 1,487 additions and 55 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ trim_trailing_whitespace = True

[*.py]
charset = utf-8
max_line_length = 88

[*.{yml,yaml,md,toml}]
indent_size = 2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
cache: pip
cache-dependency-path: setup.cfg
check-latest: true
- run: pip install -e '.[test]'
- run: pip install -e '.[test,pydantic]'
- run: coverage run -m pytest
- run: |
coverage report
Expand Down
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ repos:
- types-setuptools==65.3.0
- phantom-types==0.17.1
- abcattrs==0.3.2
- typing-extensions==4.3.0
- typing-extensions==4.6.3
- hypothesis==6.54.4
- immutables==0.19.0
- pydantic==2.0b3
- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v2.7.1"
hooks:
Expand Down
78 changes: 76 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
<a href=https://pypi.org/project/immoney/><img src=https://img.shields.io/pypi/pyversions/immoney.svg?color=informational&label=Python alt="Python versions"></a>
</p>

### Installation

```shell
$ pip install --require-venv immoney
```

### Design goals

There are a few core design aspects of this library that each eliminate entire classes
Expand Down Expand Up @@ -135,5 +141,73 @@ Traceback (most recent call last):
KeyError: 'foo'
```

For custom currency implementations, `immoney.registry.CurrencyCollector` can be used to
construct a custom registry.
#### Custom currency registries

The library ships with a sensible set of default currencies, however, you might want to
use a custom registry for two reasons:

- You want to use non-default currencies.
- You only want to allow a subset of the default currencies.

To achieve this, you can construct a custom set of types. It's recommended to use a
custom abstract base class for this, this way things will also play nice with the
Pydantic integration.

```python
import abc
from typing import Final
from immoney.registry import CurrencyCollector
from immoney.currencies import Currency

__currencies = CurrencyCollector()


class SpaceCurrency(Currency, abc.ABC):
...


class MoonCoinType(SpaceCurrency):
subunit = 100_000
code = "MCN"


MCN: Final = MoonCoinType()
__currencies.add(MCN)


class JupiterDollarType(SpaceCurrency):
subunit = 100
code = "JCN"


JCN: Final = JupiterDollarType()
__currencies.add(JCN)

custom_registry: Final = __currencies.finalize()
```

#### Pydantic V2 support

Install a compatible Pydantic version by supplying the `[pydantic]` extra.

```shell
$ pip install --require-venv immoney[pydantic]
```

The `Currency`, `Money`, `SubunitFraction` and `Overdraft` entities can all be used as
Pydantic model fields.

```pycon
>>> from pydantic import BaseModel
>>> from immoney import Money
>>> from immoney.currencies import USD
>>> class Model(BaseModel, frozen=True):
... money: Money
>>> print(instance.model_dump_json(indent=2))
{
"money": {
"subunits": 25000,
"currency": "USD"
}
}
```
8 changes: 6 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ package_dir =
packages = find:
python_requires = >=3.10
install_requires =
phantom-types>=0.16.0
typing-extensions>=4.2.0
phantom-types>=2.1.0
typing-extensions>=4.6.3
abcattrs>=0.3.2
immutables>=0.19.0

Expand All @@ -39,6 +39,9 @@ where = src
immoney = py.typed

[options.extras_require]
pydantic =
pydantic>=2.0b3

test =
pytest
coverage
Expand Down Expand Up @@ -101,3 +104,4 @@ exclude_lines =
pragma: no cover
# ignore non-implementations
^\s*\.\.\.
^\s*if TYPE_CHECKING:$
Loading

0 comments on commit b1e3b4c

Please sign in to comment.