ctor
ctor is an object tree construction and deconstruction library for python>=3.7.
It provides non-invasive way of constructing and deconstructing objects based on type annotations.
Installation:
pip install ctor
Features
- 0 dependencies
- Your classes are yours! Library does not mess with your code.
- No subclassing / metaclassing
- No special class-level field annotations
- Library does no replace/generate
__init__and/or other methods
- Works with
dataclasses,attrs,PyDanticand even pure-python classes. - Extendable if needed
- Supports
Union,Literal,Annotated, forward references, cyclic-types ... - PyCharm and other IDEs highlight constructor arguments natively without plugins
- Supports Python 3.7+
Example with python dataclasses
from dataclasses import dataclass # standard python
@dataclass
class MyClass:
name: str
value: int
# some_other_file.py
# note that this import might be in a different file
# so that your code remains untouched by serialization logic
import ctor
# Dumping
my_object = MyClass(name='hello', value=42)
data = ctor.dump(my_object)
print(data) # {'name': 'hello', 'value': 42}
# Loading
data = {'name': 'World', 'value': -42}
restored_object = ctor.load(MyClass, data)
print(restored_object) # MyClass(name='world', value=-42)
Nested objects with dataclasses
from dataclasses import dataclass # standard python
from typing import List
@dataclass
class TreeNode:
name: str
children: List['TreeNode'] # Note: forward reference making class cyclic
graph = TreeNode(name="root", children=[
TreeNode(name="A", children=[]),
TreeNode(name="B", children=[
TreeNode(name="x", children=[]),
TreeNode(name="y", children=[]),
]),
TreeNode(name="C", children=[]),
])
# Note: Even in this complex scenario, classes and data are still untouched by the library code.
import ctor
graph_data = ctor.dump(graph)
print(
graph_data) # {'name': 'root', 'children': [{'name': 'A', 'children': []}, {'name': 'B', 'children': [{'name': 'x', 'children': []}, {'name': 'y', 'children': []}]}, {'name': 'C', 'children': []}]}
Bare classes
class User:
def __init__(self, uid: int, email: str, name: str):
self.uid = uid
self.email = email
self.name = name
class Post:
def __init__(self, title: str, content: str, author: User):
self.title = title
self.content = content
self.author = author
import ctor # Import placed here just to highlight that your business-level code still does not require serialization library
data = {
'content': 'Fields can go in any order also',
'author': {
'uid': 123,
'email': 'john@doe.org',
'name': 'John Doe'
},
'title': 'Unbelievable'
}
post = ctor.load(Post, data) # post is a normal python object here
print(post.author.name) # post.user is a User
Note that this is not just Post(**data) because you need to construct User object first.
This works with objects of any depth.
Implementation described lower in the README.
Rationale
- Serialization logic should not be coupled with business logic
- Business logic should not depend on 3rd party libraries
Implementation
ctor heavily relies on typing annotations and utilizes lots of features from python typing module.
To obtain object schema ctor looks at the signature of the callable you want to construct/deconstruct.
Classes are callable, so ctor looks at __init__ method to find information about attributes and annotations, trying to specify a converter for each of the arguments.
About python 3.6 or less
typing became more or less stable only after python 3.7 (including).
API for types in 3.6 differs significantly from 3.7 onward.
It is hard to maintain two different APIs that's why I decided to stick to the newer one. However, if you feel brave enough and really need that 3.6 support you can open a PullRequest and contact me if you have any questions.
Running tests
- To test against current python version:
pytest - To tests all python versions:
tox --parallel
Metadata
Release files for ctor 0.3.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ctor-0.3.5.tar.gz | 21.8 kB | Without provenance | Details for ctor-0.3.5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ctor-0.3.5-py3-none-any.whl | Python 3 | none | any | Details for ctor-0.3.5-py3-none-any.whl |
Total release size: 36.8 kB
Release files / ctor-0.3.5.tar.gz
| Download URL | ctor-0.3.5.tar.gz |
|---|---|
| Size | 21.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
89087dee9f20530831e26ee6bad53df1f635cc58ef1f5b3ba3c53d6b71846039
|
|
BLAKE2b-256 checksum How to use checksums |
c20875d13b76284553492af23dccd67aa60071903e575afb047762c8b4765739
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.9.13
|
Release files / ctor-0.3.5-py3-none-any.whl
| Download URL | ctor-0.3.5-py3-none-any.whl |
|---|---|
| Size | 15.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3c3be89d9738adbce087f439186a326a0262c320ff3ce7445800363dec2e4b44
|
|
BLAKE2b-256 checksum How to use checksums |
ba36169b54dbc617b455f12d718b241fcf438e07bc0812c9bd92e31b99b6da48
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.9.13
|
Security for ctor 0.3.5
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.