{"id":6455,"library":"serpent","title":"Serpent Serialization Library","description":"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.","status":"active","version":"1.42","language":"en","source_language":"en","source_url":"https://github.com/irmen/Serpent","tags":["serialization","ast","data-interchange","literal-eval","cross-language"],"install":[{"cmd":"pip install serpent","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"dumps","correct":"from serpent import dumps"},{"note":"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.","wrong":"import ast; ast.literal_eval(serialized_data)","symbol":"loads","correct":"from serpent import loads"},{"note":"Used to decode base-64 encoded byte strings back to `bytes` objects if not using the `bytes_repr` serialization option.","symbol":"tobytes","correct":"from serpent import tobytes"}],"quickstart":{"code":"from serpent import dumps, loads\n\ndata = {\n    'name': 'Serpent Example',\n    'version': 1.0,\n    'is_active': True,\n    'items': [1, 2, {'id': 'a'}]\n}\n\n# Serialize the data\nserialized_bytes = dumps(data, indent=True) # indent=True for pretty-printing\nprint(f\"Serialized data:\\n{serialized_bytes.decode('utf-8')}\")\n\n# Deserialize the data\ndeserialized_data = loads(serialized_bytes)\nprint(f\"Deserialized data: {deserialized_data}\")\nprint(f\"Is deserialized data equal to original? {data == deserialized_data}\")","lang":"python","description":"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."},"warnings":[{"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.","message":"Although 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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"When 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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"Serpent 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`.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"Support 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.","severity":"breaking","affected_versions":"<1.41"},{"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.","message":"The 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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z"}