Skip to content

robertchase/serializer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

69 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

serializer

a python serializer

Testing: pytest linting: pylint Code style: black License: MIT 0 dependencies!

introduction

The serializer package adds serialization, type-enforcement, and other features to a python class.

By borrowing some of the syntax used by the dataclasses package, serializer is able to leverage standard python, but with more nuanced control than that provided by a dataclass.

A dataclass is a decorator that magically adds methods to a class based on that class's fields and their annotations. By contrast, the serializer package provides a Serializable superclass that brings it's own dunder functions that provide features like: type-enforcement, attribute constraint, user-defined types, nested objects, read-only fields, optional fields with no default values, and serialization.

example

from serializer import Serializable, Optional, serialize

class Apartment(Serializable):
    floor: int
    unit: str
    balcony: bool = Optional
    is_studio: bool = False
    
class Person(Serializable):
    name: str
    address: Apartment

Here two classes are defined.

Apartment

The Apartment class has four attributes, two of which are required—an Apartment can't be created that doesn't include floor and unit. Here is an Apartment being created in code (these produce equivalent instances):

apt = Apartment(3, "A")
apt = Apartment(floor=3, unit="A")
apt = Apartment("3", unit="A", is_studio=False)

The instance can be serialized to a dict:

>> serialize(apt)
{'floor': 3, 'unit': 'A', is_studio: False}

The instance fields operate as expected:

>> apt.balcony = True
>> apt.is_studio = True
>> serialize(apt)
{'floor': 3, 'unit': 'A', 'is_studio': True, 'balcony': True}

>> apt.bathrooms = 1
UndefinedAttributeError: 'Apartment' object has no attribute 'bathrooms'

apt.floor = "three"
ValueError: invalid <int> value (three) for field 'floor': not an integer

Optional fields only appear if assigned. Fields that are not defined in the class cannot be used. Values that don't match the annotation's type are not accepted.

Person

The Person class includes a field—address—whose type is Apartment. A Serializable class can be used as an annotated type, creating a nested object. These four ways to create a new Person are equivalent:

tenant = Person(name="John Doe", address={"floor": 3, "unit": "A"})
tenant = Person("John Doe", {"floor": 3, "unit": "A"})
tenant = Person("John Doe", [3, "A"])  # a list is treated as *args
apt = Apartment(3, "A")
tenant = Person("John Doe", apt)

Serialize the tenant:

serialize(tenant)
{'name': 'John Doe', 'address': {'floor': 3, 'unit': 'A', 'is_studio': False}}

The serialized version of an object can be used to create a new object—a method which even works with nested objects:

ser = serialize(tenant)
tenant = Person(**ser)

Access the Apartment attribute in the expected way:

print(tenant.address.unit)
A

About

robust python objects

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published