Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pickling an enum exposed by Boost.Python

Is it possible to pickle (using cPickle) an enum that has been exposed with Boost.Python? I have successfully pickled other objects using the first method described here, but none of that seems to apply for an enum type, and the objects don't seem to be pickleable by default.

like image 339
Ray Avatar asked Jul 09 '10 17:07

Ray


1 Answers

Not as they are in the module. I am given to understand that this is SUPPOSED to be possible, but the way the enum_ statement works prevents this.

You can work around this on the python side. Somewhere (probably in a __init__.py file) do something like this:

import yourmodule

def isEnumType(o):
    return isinstance(o, type) and issubclass(o,int) and not (o is int)

def _tuple2enum(enum, value):
    enum = getattr(yourmodule, enum)
    e = enum.values.get(value,None)
    if e is None:
        e = enum(value)
    return e

def _registerEnumPicklers(): 
    from copy_reg import constructor, pickle
    def reduce_enum(e):
        enum = type(e).__name__.split('.')[-1]
        return ( _tuple2enum, ( enum, int(e) ) )
    constructor( _tuple2enum)
    for e in [ e for e in vars(yourmodule).itervalues() if isEnumType(e) ]:
        pickle(e, reduce_enum)

_registerEnumPicklers()

This will make everything pickle just fine.

like image 87
Matthew Scouten Avatar answered Oct 17 '22 16:10

Matthew Scouten