Registry / serialization / serpent

serpent

JSON →
library1.43pypypi✓ verified 85d ago

Serpent is a simple serialization library for Python based on `ast.literal_eval`. It serializes object trees into a safe, human-readable, UTF-8 encoded string (a valid Python literal expression), suitable for data interchange between Python, Java, and .NET. As of version 1.42, it actively maintains support for modern Python versions with a release cadence of a few months to a year.

pip install serpent
INSTALL
IMPORT
SIG · SERPENT
S
serpent
serializationpythonv1.43
Install
1.7s avg
Import
21ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.43 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.023s · 17.8MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 1.7s · import 0.019s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

dumps
from serpent import dumps
loads
from serpent import loads
import ast; ast.literal_eval(serialized_data)
While Serpent's output is compatible with `ast.literal_eval`, `serpent.loads` handles specific corner cases and custom type deserialization that `ast.literal_eval` alone would not.
tobytes
from serpent import tobytes
Used to decode base-64 encoded byte strings back to `bytes` objects if not using the `bytes_repr` serialization option.

This quickstart demonstrates basic serialization and deserialization of a Python dictionary containing various literal types. The `indent=True` option is used for human-readable output, and the data is converted to a UTF-8 string for printing.

from serpent import dumps, loads data = { 'name': 'Serpent Example', 'version': 1.0, 'is_active': True, 'items': [1, 2, {'id': 'a'}] } # Serialize the data serialized_bytes = dumps(data, indent=True) # indent=True for pretty-printing print(f"Serialized data:\n{serialized_bytes.decode('utf-8')}") # Deserialize the data deserialized_data = loads(serialized_bytes) print(f"Deserialized data: {deserialized_data}") print(f"Is deserialized data equal to original? {data == deserialized_data}")
serpent --version
Debug
Known issues
gotchaAlthough based on `ast.literal_eval` (which is safer than `eval()`), processing untrusted input with Serpent can still lead to Denial of Service (DoS) attacks, such as memory exhaustion or C stack exhaustion, by crafting malicious inputs.
fix
Do not deserialize data from untrusted sources. If you must process untrusted data, implement strict input validation and consider applying resource limits to prevent DoS attacks.
affects: All versions
gotchaWhen serializing `bytes`, `bytearray`, or `memoryview` objects, Serpent defaults to base-64 encoding. To retrieve the original `bytes` object during deserialization, you must manually decode the string using `serpent.tobytes()`. Alternatively, using the `bytes_repr=True` option during serialization (available since 1.40) will output Python's `bytes` literal representation, but this generally results in larger and slower serialization.
fix
After `loads()`, inspect string fields for base-64 encoded byte data and use `serpent.tobytes()` to convert them. Or, serialize with `dumps(obj, bytes_repr=True)` and handle the larger output.
affects: All versions
gotchaSerpent cannot serialize object graphs with circular references (where an object refers to itself, directly or indirectly). Attempting to do so will result in a `ValueError`.
fix
Ensure that the object tree you are serializing does not contain any circular references. You may need to preprocess your data structure to break such cycles.
affects: All versions
breakingSupport for Python 3.11 introduced changes to `__getstate__` behavior. Serpent versions prior to 1.41 may fail to correctly serialize custom objects implementing `__getstate__` when running on Python 3.11 or newer.
fix
Upgrade to Serpent version 1.41 or newer if you are using Python 3.11+ and rely on custom `__getstate__` implementations for your serializable objects.
affects: <1.41
gotchaThe serializer instance itself is not thread-safe. Avoid modifying the object tree being serialized while `dumps()` is running, and do not use the same `dumps()` (or a shared underlying serializer instance) across multiple threads concurrently.
fix
For concurrent serialization, create a new `dumps` call (or ensure a new serializer instance is implicitly used) for each thread, or synchronize access to the object being serialized and the serializer instance.
affects: All versions
Errors
Common errors & fixes
TypeError: Object of type <class 'set'> is not serpent serializable
The `serpent` library, based on `ast.literal_eval`, only supports a limited set of built-in Python literal types (strings, numbers, booleans, None, lists, tuples, dictionaries) for direct serialization; other types like sets or custom objects are not supported.
fix
Convert the unsupported object into a serializable type (e.g., convert a `set` to a `list`) before passing it to `serpent.dumps()`.
```python
import serpent
my_set = {1, 2, 3}
serialized_data = serpent.dumps(list(my_set))
# To deserialize back to a set:
deserialized_set = set(serpent.loads(serialized_data))
```
ValueError: malformed node or string
The input string provided to `serpent.loads()` is not a valid Python literal expression, which causes `ast.literal_eval` to fail parsing it.
fix
Ensure the input string is a well-formed Python literal expression, typically by generating it with `serpent.dumps()` or by carefully constructing it according to Python's literal syntax.
```python
import serpent
# Incorrect input (e.g., missing closing bracket or invalid syntax)
# serpent.loads("[1, 2, 3")

# Correct input
data_string = serpent.dumps([1, 2, 3])
deserialized_data = serpent.loads(data_string)
print(deserialized_data)
```
ModuleNotFoundError: No module named 'serpent'
The `serpent` library has not been installed in the Python environment where the script is being executed.
fix
Install the `serpent` package using pip.
```bash
pip install serpent
```
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position X: invalid start byte
The string passed to `serpent.loads()` contains bytes that are not valid UTF-8, but `serpent` expects and processes UTF-8 encoded data.
fix
Ensure that the data being passed to `serpent.loads()` is a string correctly decoded as UTF-8. If reading from a file, explicitly specify `encoding='utf-8'`.
```python
import serpent
# If reading from a file, ensure correct encoding:
# with open('my_data.serpent', 'r', encoding='utf-8') as f:
#     serpent_string = f.read()
#     data = serpent.loads(serpent_string)

# If you have bytes, decode them as UTF-8 before passing to loads:
encoded_bytes = b'{"key": "value"}' # Example valid UTF-8 bytes
data = serpent.loads(encoded_bytes.decode('utf-8'))
print(data)
```
Upgrade
Version history
1.43latest on PyPI · released May 30, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
12 hits · last 30 days
node
10
Amazon
1
Resources
serpent — pip install serpent · libregistry