An open API service indexing awesome lists of open source software.

https://github.com/aweirddev/exacting

exacting is a picky dataclass runtime utility collection, making sure all type annotations are followed.
https://github.com/aweirddev/exacting

python-data-structures python-dataclass-type-validator python-dataclasses

Last synced: 3 months ago
JSON representation

exacting is a picky dataclass runtime utility collection, making sure all type annotations are followed.

Awesome Lists containing this project

README

          

# Exacting

> *(adj.) making great demands on one's skill, attention, or other resources.*

โœ… [**Docs**](https://aweirddev.github.io/exacting) and [**PyPi**](https://pypi.org/project/exacting)

`exacting` is a picky dataclass runtime utility collection, making sure all type annotations are followed.

Essentially... **THE** go-to option for dataclasses. heh.

**๐Ÿ”‘ Key features**:

- **100% static typing.** Because I hate nothing too.
- Generally **faster** than [`pydantic`](https://pydantic.dev)!

![i aint lying about static typing](https://github.com/user-attachments/assets/875517ff-5dd5-4b63-98fa-e1218ff00627)

## Quick tour

This won't take you long :)

**๐Ÿ›๏ธ Get `exacting`**:

```haskell
pip install -U exacting
```

**๐Ÿ”ฅ Define some model**:

(Let's just say you're on Python 3.10+... good boy!)

```python
from exacting import Exact

class Actor(Exact):
name: str
portrays: str

class Show(Exact):
name: str
description: str | None
actors: list[Actor]
```

Nawh... I'm on an older version

Oh, it's definitely okay! We got you covered ๐Ÿ”ฅ๐Ÿ”ฅ

```python
from typing import List, Optional
from exacting import Exact

class Actor(Exact):
name: str
portrays: str

class Show(Exact):
name: str
description: Optional[str]
actors: List[Actor]
```


**๐Ÿ“ฆ Build 'em**:

```python
# (1) โœ… OK, exacting is happi
Show(
name="Severance",
description="great show",
actors=[
Actor(name="Adam Scott", portrays="Mark S."),
Actor(name="Britt Lower", portrays="Helly R."),
]
)

# (2) โŒ Nuh-uh, exacting is angri
Show(
name=123,
description=False,
actors=[
"Walter White",
"Jesse Pinkman"
]
)
```

๐Ÿ”ด ValidationError: During validation ofโ€ฆ

```python
ValidationError:
During validation of dataclass Show at field 'name', got:
โ€ข Expected type , got
```


Normally, when you use the parameters passed in example (2) above, the Python `dataclasses` library might as well just go with it, because they only put the additional **static typing** to the model, but not at **runtime**. Exacting makes sure that at both times, types are all enforced. It even gives you a detailed error message on where this occurs! (In a cool way)

It's worth noting that error generations are *lazy*, which means once Exacting finds out about a problem about a dataclass, it raises a `ValidationError`. This saves a lot of computation time if you have a larger model.

![praise pydantic](https://github.com/user-attachments/assets/c322bff2-2624-479d-9967-7184580b36c1)

Yeah, we also got fields! Use it like how you'd expect it. Quite literally, lol.

```python
from exacting import Exact, field

def create_ai_slop():
return "tick tock"

class Comment(Exact):
user: str = field(regex="^@.+$")
stars: int = field(minv=1, maxv=5)
body: str = field(default_factory=create_ai_slop)

# โœ… OK, exacting is HYPED
Comment(
user="@waltuh",
stars=5
)

# โŒ Hell nawh, exacting holdin' you at gunpoint
Comment(
user="ooga booga", # Regex validation '^@.+$' on str failed
stars=-1, # Expected min value of 1, got -1
body=None # Expected type , got
)
```

Woah! That's a lot of code to process. To put it simply, exacting supports:

- **Regex** validation on `str`
- **Min/max** validation on value (e.g., `int`, `float`) or length (e.g., `str`, `list`)
- **Default** values or factory! Y'know, the old `dataclasses` way, mmmMMM
- This is extra, but **custom** validation! You can make your own if you like

![praise pydantic, exactign sucks](https://github.com/user-attachments/assets/5969c54a-14d0-4023-9f80-b89ae9ea8374)

Kind of, but somehow native performance is way better than Rust. That is, exacting is *generally* faster than Pydantic on a few benchmarks. Woooosh

Anyway, thanks for sticking with us, you can [read the docs](https://aweirddev.github.io/exacting) if you'd like.