Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython
INSTALL>
pypm install serpent

How to install serpent

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install serpent
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
Windows (64-bit)
Mac OS X (10.5+)
Linux (32-bit)
Linux (64-bit)
1.4 Available View build log
1.4 Available View build log
 
Author
License
MIT
Depended by
Imports
Lastest release
version 1.4 on Sep 20th, 2013

Serpent is a simple serialization library based on ast.literal_eval.

Because it only serializes literals and recreates the objects using ast.literal_eval(), the serialized data is safe to transport to other machines (over the network for instance) and de-serialize it there.

There is also a Java and a .NET (C#) implementation available. This allows for easy data transfer between the various ecosystems. You can get the full source distribution, a Java .jar file, and a .NET assembly dll. Download location here

API

  • ser_bytes = serpent.dumps(obj, indent=False) # serialize obj tree to bytes
  • obj = serpent.loads(ser_bytes) # deserialize bytes back into object tree
  • You can use ast.literal_eval yourself to deserialize, but serpent.deserialize works around a few corner cases. See source for details.

Serpent is more sophisticated than a simple repr() + literal_eval():

  • it serializes directly to bytes (utf-8 encoded), instead of a string, so it can immediately be saved to a file or sent over a socket
  • it encodes byte-types as base-64 instead of inefficient escaping notation that repr would use (this does mean you have to base-64 decode these strings manually on the receiving side to get your bytes back)
  • it contains a few custom serializers for several additional Python types such as uuid, datetime, array and decimal
  • it tries to serialize unrecognised types as a dict (you can control this with __getstate__ on your own types)
  • it can create a pretty-printed (indented) output for readability purposes
  • it outputs the keys of sets and dicts in alphabetical order (when pretty-printing)
  • it works around a few quirks of ast.literal_eval() on the various Python implementations

Serpent allows comments in the serialized data (because it is just Python source code). Serpent can't serialize object graphs (when an object refers to itself); it will then crash with a recursion error.

Works with Python 2.6+ (including 3.x), IronPython 2.7+, Jython 2.7+.

FAQ

  • Why not use XML? Answer: because XML.
  • Why not use JSON? Answer: because JSON is quite limited in the number of datatypes it supports, and you can't use comments in a JSON file.
  • Why not use pickle? Answer: because pickle has security problems.
  • Why not use repr()/ast.literal_eval()? See above; serpent is a superset of this and provides more convenience. Serpent provides automatic serialization mappings for types other than the builtin primitive types. repr() can't serialize these to literals that ast.literal_eval() understands.
  • Why not a binary format? Answer: because binary isn't readable.
  • But I don't care about readability. Answer: too bad, ast.literal_eval() wants a literal string.
  • But I want better performance. Answer: ok, maybe you shouldn't use serpent in this case. Find an efficient binary protocol (protobuf?)
  • Why only Python, Java and .NET, but no bindings for insert-favorite-language-here? Answer: I don't speak that language. Maybe you could port serpent yourself?
  • Where is the source? It's on Github: https://github.com/irmen/Serpent

Demo

System Message: ERROR/3 (<string>, line 47)

Unknown directive type "code".

.. code:: python

 # This demo script is written for Python 3.2+
 # -*- coding: utf-8 -*-
 from __future__ import print_function
 import ast
 import uuid
 import datetime
 import pprint
 import serpent


 class DemoClass:
     def __init__(self):
         self.i=42
         self.b=False

 data = {
     "names": ["Harry", "Sally", "Peter"],
     "big": 2**200,
     "colorset": { "red", "green" },
     "id": uuid.uuid4(),
     "timestamp": datetime.datetime.now(),
     "class": DemoClass(),
     "unicode": "€"
 }

 # serialize it
 ser = serpent.dumps(data, indent=True)
 open("data.serpent", "wb").write(ser)

 print("Serialized form:")
 print(ser.decode("utf-8"))

 # read it back
 data = serpent.load(open("data.serpent", "rb"))
 print("Data:")
 pprint.pprint(data)

 # you can also use ast.literal_eval if you like
 ser_string = open("data.serpent", "r", encoding="utf-8").read()
 data2 = ast.literal_eval(ser_string)

 assert data2==data


When you run this (with python 3.2+) it prints:

System Message: ERROR/3 (<string>, line 95)

Unknown directive type "code".

.. code:: python

 Serialized form:
 # serpent utf-8 python3.2
 {
   'big': 1606938044258990275541962092341162602522202993782792835301376,
   'class': {
     '__class__': 'DemoClass',
     'b': False,
     'i': 42
   },
   'colorset': {
     'green',
     'red'
   },
   'id': 'e461378a-201d-4844-8119-7c1570d9d186',
   'names': [
     'Harry',
     'Sally',
     'Peter'
   ],
   'timestamp': '2013-04-02T00:23:00.924000',
   'unicode': '€'
 }
 Data:
 {'big': 1606938044258990275541962092341162602522202993782792835301376,
  'class': {'__class__': 'DemoClass', 'b': False, 'i': 42},
  'colorset': {'green', 'red'},
  'id': 'e461378a-201d-4844-8119-7c1570d9d186',
  'names': ['Harry', 'Sally', 'Peter'],
  'timestamp': '2013-04-02T00:23:00.924000',
  'unicode': '€'}

Subscribe to package updates

Last updated Sep 20th, 2013

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.