Skip to content
Snippets Groups Projects
Commit 4df6f340 authored by Wim Lavrijsen's avatar Wim Lavrijsen
Browse files

basic pickling support

git-svn-id: http://root.cern.ch/svn/root/trunk@23239 27541ba8-7e3a-0410-8455-c3a389f83636
parent be74d7d9
Branches
Tags
No related merge requests found
......@@ -14,6 +14,7 @@
#include "Converters.h"
#include "MemoryRegulator.h"
#include "Adapters.h"
#include "Utility.h"
// ROOT
#include "TClass.h"
......@@ -30,6 +31,8 @@
#include "TBranch.h"
#include "TLeaf.h"
#include "TBufferFile.h"
// CINT
#include "Api.h"
......@@ -40,6 +43,9 @@
#include <utility>
//- data _______________________________________________________________________
R__EXTERN PyObject* gRootModule;
namespace {
// for convenience
......@@ -236,6 +242,33 @@ namespace {
return CallPyObjMethod( self, "IsEqual", obj );
}
//____________________________________________________________________________
PyObject* TObjectReduce( PyObject*, PyObject* args )
{
// Turn the TObject derived into a character stream and return for pickle,
// together with the callable object that can restore the stream into a
// TObject derived instance.
ObjectProxy* self = 0;
if ( ! PyArg_ParseTuple( args,
const_cast< char* >( "O!:__reduce__" ), &ObjectProxy_Type, &self ) )
return 0;
TBufferFile buf( TBuffer::kWrite );
buf.WriteObject( (TObject*)self->GetObject() );
// use a string for the serialized result, as a python buffer will not copy
// the buffer contents
PyObject* res2 = PyTuple_New( 1 );
PyTuple_SET_ITEM( res2, 0, PyString_FromStringAndSize( buf.Buffer(), buf.Length() ) );
PyObject* result = PyTuple_New( 2 );
PyTuple_SET_ITEM( result, 0,
PyObject_GetAttrString( gRootModule, const_cast< char* >( "_TObject__expand__" ) ) );
PyTuple_SET_ITEM( result, 1, res2 );
return result;
}
//- TClass behaviour -----------------------------------------------------------
PyObject* TClassStaticCast( PyObject*, PyObject* args )
......@@ -1627,6 +1660,10 @@ Bool_t PyROOT::Pythonize( PyObject* pyclass, const std::string& name )
Utility::AddToClass( pyclass, "__cmp__", (PyCFunction) TObjectCompare );
Utility::AddToClass( pyclass, "__eq__", (PyCFunction) TObjectIsEqual );
// enable pickling
Utility::AddToClass( pyclass, "__reduce__", (PyCFunction) TObjectReduce );
Utility::AddToClass( pyclass, "__expand__", (PyCFunction) TObjectReduce );
return kTRUE;
}
......
......@@ -23,6 +23,8 @@
#include "TClass.h"
#include "TObject.h"
#include "TBufferFile.h"
// Standard
#include <string>
......@@ -309,6 +311,23 @@ namespace {
return BindObject_( 0, PyTuple_GET_ITEM( args, 0 ) );
}
//____________________________________________________________________________
PyObject* TObjectExpand( PyObject*, PyObject* args )
{
// This method and is a helper for pickling for TObject derived classes.
PyObject* pybuf = 0;
if ( ! PyArg_ParseTuple( args,
const_cast< char* >( "O!:__expand__" ), &PyString_Type, &pybuf ) )
return 0;
// use the PyString macro's to by-pass error checking; do not copy the buffer
// as the TBufferFile is local to this function only
TBufferFile buf( TBuffer::kRead,
PyString_GET_SIZE( pybuf ), PyString_AS_STRING( pybuf ), kFALSE );
TObject* result = buf.ReadObject( 0 );
return BindRootObject( result, result->IsA() );
}
//____________________________________________________________________________
PyObject* SetMemoryPolicy( PyObject*, PyObject* args )
{
......@@ -380,6 +399,8 @@ static PyMethodDef gPyROOTMethods[] = {
METH_VARARGS, (char*) "Create an object of given type, from given address" },
{ (char*) "MakeNullPointer", (PyCFunction)MakeNullPointer,
METH_VARARGS, (char*) "Create a NULL pointer of the given type" },
{ (char*) "_TObject__expand__", (PyCFunction)TObjectExpand,
METH_VARARGS, (char*) "Helper method for pickling" },
{ (char*) "SetMemoryPolicy", (PyCFunction)SetMemoryPolicy,
METH_VARARGS, (char*) "Determines object ownership model" },
{ (char*) "SetSignalPolicy", (PyCFunction)SetSignalPolicy,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment