Skip to main content

Table of Contents

Introduction

dataclass alternative with a greater emphasis on the 'class' aspect.

Extract features baozi offers

  • Inheritance
  • Immutability
  • Keyword-only arguments and random order attributes
  • Support user-defined __pre_init__ method that gets executed before class instantiation
  • Typecasting(experimental)

Installation

pip install baozi

Usage

1. Usage of plain Struct

from baozi import Struct

class Person(Struct, kw_only=True):
    age: int = 15
    name: str

p = Person(name="baozi")

pre_init hook

class B(baozi.Struct):
    name: str
    age: int

    @classmethod
    def __pre_init__(cls, **data):
        data["age"] = int(data["age"])
        return data

assert asdict(B(name="name", age="15")) == {"name": "name", "age": 15}
  • Note here that attribute with default value does not have to show before regular attributeo

  • You might place dataclass configration directly in class inheritance

  • configs will be passed to subclasses

  • config class meta by passing class arguments or defining __model_config__ field in the class

2. Usage of FrozenStruct

baozi is fully compatible with dataclasses.dataclass

from dataclass import is_dataclass
from baozi import FrozenStruct

assert is_dataclass(FrozenStruct)

FrozenStruct is equal to dataclass(frozen=True, slots=True, kw_only=True)

from baozi import FrozenStruct, field
from datetime import datetime

class Event(FrozenStruct):
    name: str
    create_at: datetime = field(default_factory=datetime.now)

>> e = Event(name="event")
>> assert isinstance(e.created_at, datetime)
>> e.created_at = datetime.now()

dataclasses.FrozenInstanceError: cannot assign to field 'created_at'

Defining FrozenStruct with mutable fields would raise error

since any mutable field would cause failure in immutability of the class

from baozi import FrozenStruct

class Mutable(FrozenStruct):
    address: list[str]

baozi.MutableFieldError

Technical Details

config override order

baozi receive config in following order:

  1. config defined explicitly using __model_config__ field defined in the class
  2. config defined in the inheritance params
  3. config defined in the parent class of current class
  4. default config of baozi, which goes like this:
init=True
repr=True
eq=True
order=False
unsafe_hash=False
frozen=False
match_args=True
kw_only=True
slots=False

Struct default: kw_only=True

FrozenStruct defaults: kw_only=True frozen=True slots=True

Rationale of existence

why wouldn't I just use dataclass?

Mostly because of the decorator approach, dataclass uses decorators for transforming a regular class into a dataclass, and when I use dataclass in production, I soon realize that:

  1. Code repetition, when there are tons of dataclasses, you are going to decorate them with @dataclass over and over again

  2. Error-prone, for non-trivial application, you often have different configuration of dataclass, like @dataclass(frozen), if you inherit from a frozen dataclass and you use regular @dataclass decorator, odds are you are going to have a bad time.

  3. It simply does not make sense to use decorator, when you decorating a class, it implies that your class would work just fine without the decorator, and that is not the case, if you get rid of the @dataclass decorator, your class won't work.

why wouldn't I just use pydantic.BaseModel?

Mostly because of You don't need validation, and you can use both.

pydantic is very powerful and strong and I use it in various projects, but there are certain scenarios where I find pydantic to be an overkill.

  1. Data are already validated in the API layer, and once the input goes through API and penetrate into my application layer, i know those data are safe, cause they are generated by my code.

  2. performance, despite how performant pydantic is, depending on complexity, it is ususally 5x to 100x times slower than a dataclass, which is essentially a regular python class. baozi is constantly faster than pydantic, especially for model with complex validation logic(since baozi does not validate by default), baozi also support usage of slots, which effciently cut about 1/3 of memory usage comparing to regular python class.

Metadata

Release files for baozi 0.0.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for baozi 0.0.6
File Size Uploaded Provenance
baozi-0.0.6.tar.gz 9.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for baozi 0.0.6
File Interpreter ABI Platform
baozi-0.0.6-py3-none-any.whl Python 3 none any Details

Total release size: 19.3 kB

Release files / baozi-0.0.6.tar.gz

Download URL baozi-0.0.6.tar.gz
Size 9.7 kB
Tags Source
SHA-256 checksum
How to use checksums
69ce249763684af8c2360ae2cee6cacfd38594ee00b025ec9b9eaf2ac8cedc8e
BLAKE2b-256 checksum
How to use checksums
e11282205a901f778120fe9e69c2f5834c7e8e94fda8a7a88c0bd7b0a06a7ad7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.0

Release files / baozi-0.0.6-py3-none-any.whl

Download URL baozi-0.0.6-py3-none-any.whl
Size 9.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
33c97422d1f3a1d3993a1c10122700e1d3225bd7d82d97bbb24b6e23018167a6
BLAKE2b-256 checksum
How to use checksums
e0501dc5b0ba297021f0bc639d60db95e6bc938706d5b8992cf433e6c25bf01c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.0

Security for baozi 0.0.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page