Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CPPInstancePyz.cxx
Go to the documentation of this file.
1// Author: Massimiliano Galli CERN 07/2019
2// Original PyROOT code by Wim Lavrijsen, LBL
3
4/*************************************************************************
5 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "PythonLimitedAPI.h"
13
14// Bindings
15#include "CPyCppyy/API.h"
16
17#include "PyROOTPythonize.h"
18#include "TBufferFile.h"
19
20namespace PyROOT {
21extern PyObject *gRootModule;
22}
23
24////////////////////////////////////////////////////////////////////////////
25/// \brief Deserialize pickled objects
26/// \param[in] self Always null, since this is a module function.
27/// \param[in] args Pointer to a Python tuple object containing the arguments
28/// received from Python.
29///
30/// Helper function that deserializes pickled objects. It needs to be
31/// included in the extension module API because otherwise it is not
32/// callable from Python. This is important because it will be Python
33/// itself calling it when trying to expand a serialized object.
35{
36 PyObject *pybuf = 0, *pyname = 0;
37 if (!PyArg_ParseTuple(args, "O!O!:__expand__", &PyBytes_Type, &pybuf, &PyBytes_Type, &pyname))
38 return 0;
39 const char *clname = PyBytes_AsString(pyname);
40 // TBuffer and its derived classes can't write themselves, but can be created
41 // directly from the buffer, so handle them in a special case
42 void *newObj = 0;
43 if (strcmp(clname, "TBufferFile") == 0) {
46 newObj = buf;
47 } else {
48 // use the PyString macro's to by-pass error checking; do not adopt the buffer,
49 // as the local TBufferFile can go out of scope (there is no copying)
51 newObj = buf.ReadObjectAny(0);
52 }
54 return result;
55}
56
57/// PyROOT object proxy pickle support
58/// Turn the object proxy instance into a character stream and return for
59/// pickle, together with the callable object that can restore the stream
60/// into the object proxy instance.
62{
63 // keep a borrowed reference around to the callable function for expanding;
64 // because it is borrowed, it means that there can be no pickling during the
65 // shutdown of the libPyROOT module
67
68 // TBuffer and its derived classes can't write themselves, but can be created
69 // directly from the buffer, so handle them in a special case
70 TBufferFile *buff = nullptr;
71 std::string className = CPyCppyy::Instance_GetScopedFinalName(self);
72 if (className == "TBufferFile") {
74 } else {
75 if (className.find("__cppyy_internal::Dispatcher") == 0) {
77 "generic streaming of Python objects whose class derives from a C++ class is not supported. "
78 "Please refer to the Python pickle documentation for instructions on how to define "
79 "a custom __reduce__ method for the derived Python class");
80 return 0;
81 }
82 // no cast is needed, but WriteObject taking a TClass argument is protected,
83 // so use WriteObjectAny()
85 s_buff.Reset();
86 // to delete
87 if (s_buff.WriteObjectAny(CPyCppyy::Instance_AsVoidPtr(self), TClass::GetClass(className.c_str())) != 1) {
88 PyErr_Format(PyExc_IOError, "could not stream object of type %s",
89 className.c_str());
90 return 0;
91 }
92 buff = &s_buff;
93 }
94 // use a string for the serialized result, as a python buffer will not copy
95 // the buffer contents; use a string for the class name, used when casting
96 // on reading back in (see CPPInstanceExpand defined above)
98 PyTuple_SetItem(res2, 0, PyBytes_FromStringAndSize(buff->Buffer(), buff->Length()));
99 PyTuple_SetItem(res2, 1, PyBytes_FromString(className.c_str()));
100
105
106 return result;
107}
108
109////////////////////////////////////////////////////////////////////////////
110/// \brief Set __reduce__ attribute for CPPInstance objects
111/// \param[in] self Always null, since this is a module function.
112/// \param[in] args Pointer to a Python tuple object containing the arguments
113/// received from Python.
114///
115/// The C++ function op_reduce defined above is wrapped in a Python method
116/// so that it can be injected in CPPInstance
PyObject * op_reduce(PyObject *self, PyObject *)
PyROOT object proxy pickle support Turn the object proxy instance into a character stream and return ...
#define PyBytes_FromString
Definition CPyCppyy.h:69
#define PyBytes_Size
Definition CPyCppyy.h:67
#define PyBytes_FromStringAndSize
Definition CPyCppyy.h:70
#define PyBytes_AsString
Definition CPyCppyy.h:64
#define Py_RETURN_NONE
Definition CPyCppyy.h:268
#define PyBytes_Type
Definition CPyCppyy.h:72
_object PyObject
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
Definition TBufferFile.h:47
void WriteFastArray(const Bool_t *b, Long64_t n) override
Write array of n bools into the I/O buffer.
void * ReadObjectAny(const TClass *cast) override
Read object from I/O buffer.
@ kWrite
Definition TBuffer.h:73
@ kRead
Definition TBuffer.h:73
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2979
CPYCPPYY_EXTERN PyObject * Instance_FromVoidPtr(void *addr, const std::string &classname, bool python_owns=false)
Definition API.cxx:133
CPYCPPYY_EXTERN void Instance_SetReduceMethod(PyCFunction reduceMethod)
Definition API.cxx:270
CPYCPPYY_EXTERN std::string Instance_GetScopedFinalName(PyObject *pyobject)
Definition API.cxx:106
CPYCPPYY_EXTERN void * Instance_AsVoidPtr(PyObject *pyobject)
Definition API.cxx:118
PyObject * AddCPPInstancePickling(PyObject *self, PyObject *args)
Set reduce attribute for CPPInstance objects.
PyObject * CPPInstanceExpand(PyObject *self, PyObject *args)
Deserialize pickled objects.
PyObject * gRootModule