Logo ROOT  
Reference Guide
TDirectoryPyz.cxx
Go to the documentation of this file.
1 // Author: Danilo Piparo, Stefan Wunsch, Massimiliano Galli CERN 08/2018
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 "CPyCppyy.h"
13 #include "CPPInstance.h"
14 #include "PyROOTPythonize.h"
15 #include "ProxyWrappers.h"
16 #include "Utility.h"
17 #include "PyzCppHelpers.hxx"
18 #include "TClass.h"
19 #include "TDirectory.h"
20 #include "TKey.h"
21 #include "Python.h"
22 
23 using namespace CPyCppyy;
24 
25 ////////////////////////////////////////////////////////////////////////////////
26 /// \brief Implements the WriteObject method of TDirectory
27 /// This method allows to write objects into TDirectory instances with this
28 /// syntax:
29 /// ~~~{.python}
30 /// myDir.WriteObject(myObj, "myKeyName")
31 /// ~~~
33 {
34  CPPInstance *wrt = nullptr;
35  PyObject *name = nullptr;
36  PyObject *option = nullptr;
37  Int_t bufsize = 0;
38  if (!PyArg_ParseTuple(args, const_cast<char *>("O!O!|O!i:TDirectory::WriteObject"),
39  &CPPInstance_Type, &wrt,
41  &CPyCppyy_PyText_Type, &option,
42  &bufsize))
43  return nullptr;
44  auto dir = (TDirectory *)GetTClass(self)->DynamicCast(TDirectory::Class(), self->GetObject());
45  if (!dir) {
46  PyErr_SetString(PyExc_TypeError,
47  "TDirectory::WriteObject must be called with a TDirectory instance as first argument");
48  return nullptr;
49  }
50  Int_t result = 0;
51  if (option != nullptr) {
52  result = dir->WriteObjectAny(wrt->GetObject(), GetTClass(wrt), CPyCppyy_PyText_AsString(name),
53  CPyCppyy_PyText_AsString(option), bufsize);
54  } else {
55  result = dir->WriteObjectAny(wrt->GetObject(), GetTClass(wrt), CPyCppyy_PyText_AsString(name));
56  }
57  return PyInt_FromLong((Long_t)result);
58 }
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 /// \brief Implements a getter to assign to TDirectory.__getattr__
62 /// Method that is assigned to TDirectory.__getattr__. It relies on Get to
63 /// obtain the object from the TDirectory and adds on top:
64 /// - Raising an AttributeError if the object does not exist
65 /// - Caching the result of a successful get for future re-attempts.
66 /// Once cached, the same object is retrieved every time.
67 /// This pythonisation is inherited by TDirectoryFile and TFile.
69 {
70  // Injection of TDirectory.__getattr__ that raises AttributeError on failure.
71  PyObject *result = CallPyObjMethod(self, "Get", attr);
72  if (!result)
73  return result;
74 
75  if (!PyObject_IsTrue(result)) {
76  PyObject *astr = PyObject_Str(attr);
77  PyObject *stypestr = PyObject_Str(PyObject_Type(self));
78  PyErr_Format(PyExc_AttributeError, "%s object has no attribute \'%s\'", CPyCppyy_PyText_AsString(stypestr),
80  Py_DECREF(astr);
81  Py_DECREF(result);
82  return nullptr;
83  }
84 
85  // Caching behavior seems to be more clear to the user; can always override said
86  // behavior (i.e. re-read from file) with an explicit Get() call
87  PyObject_SetAttr(self, attr, result);
88  return result;
89 }
90 
91 ////////////////////////////////////////////////////////////////////////////
92 /// \brief Add attr syntax to TDirectory
93 /// \param[in] self Always null, since this is a module function.
94 /// \param[in] args Pointer to a Python tuple object containing the arguments
95 /// This allows to use TDirectory and daughters (such as TDirectoryFile and TFile)
96 /// as follows
97 /// ~~~{.python}
98 /// myfile.mydir.mysubdir.myHist.Draw()
99 /// ~~~
101 {
102  PyObject *pyclass = PyTuple_GetItem(args, 0);
103  Utility::AddToClass(pyclass, "__getattr__", (PyCFunction)TDirectoryGetAttr, METH_O);
105 }
106 
107 ////////////////////////////////////////////////////////////////////////////
108 /// \brief Add pythonisation of TDirectory::WriteObject
109 /// \param[in] self Always null, since this is a module function.
110 /// \param[in] args Pointer to a Python tuple object containing the arguments
112 {
113  PyObject *pyclass = PyTuple_GetItem(args, 0);
114  Utility::AddToClass(pyclass, "WriteObject", (PyCFunction)TDirectoryWriteObject);
116 }
CPyCppyy
Set of helper functions that are invoked from the pythonizors, on the Python side.
Definition: TPyClassGenerator.cxx:31
CPPInstance.h
TDirectoryGetAttr
PyObject * TDirectoryGetAttr(PyObject *self, PyObject *attr)
Implements a getter to assign to TDirectory.__getattr__ Method that is assigned to TDirectory....
Definition: TDirectoryPyz.cxx:68
TDirectory.h
PyROOT::AddDirectoryGetAttrPyz
PyObject * AddDirectoryGetAttrPyz(PyObject *self, PyObject *args)
Add attr syntax to TDirectory.
Definition: TDirectoryPyz.cxx:100
PyObject
_object PyObject
Definition: PyMethodBase.h:42
CallPyObjMethod
PyObject * CallPyObjMethod(PyObject *obj, const char *meth)
Set of helper functions that are invoked from the C++ implementation of pythonizations.
Definition: PyzCppHelpers.cxx:20
Utility.h
PyROOTPythonize.h
CPyCppyy::CPPInstance
Definition: CPPInstance.h:26
TClass.h
PyROOT::AddDirectoryWritePyz
PyObject * AddDirectoryWritePyz(PyObject *self, PyObject *args)
Add pythonisation of TDirectory::WriteObject.
Definition: TDirectoryPyz.cxx:111
CPyCppyy::CPPInstance::GetObject
void * GetObject()
Definition: CPPInstance.h:93
ProxyWrappers.h
GetTClass
TClass * GetTClass(const CPyCppyy::CPPInstance *pyobj)
Definition: PyzCppHelpers.cxx:44
Long_t
long Long_t
Definition: RtypesCore.h:54
CPyCppyy.h
CPyCppyy_PyText_AsString
#define CPyCppyy_PyText_AsString
Definition: CPyCppyy.h:97
CPyCppyy_PyText_Type
#define CPyCppyy_PyText_Type
Definition: CPyCppyy.h:115
TDirectoryWriteObject
PyObject * TDirectoryWriteObject(CPPInstance *self, PyObject *args)
Implements the WriteObject method of TDirectory This method allows to write objects into TDirectory i...
Definition: TDirectoryPyz.cxx:32
PyInt_FromLong
PyInt_FromLong
Definition: Converters.cxx:858
TClass::DynamicCast
void * DynamicCast(const TClass *base, void *obj, Bool_t up=kTRUE)
Cast obj of this class type up to baseclass cl if up is true.
Definition: TClass.cxx:4891
PyzCppHelpers.hxx
CPyCppyy::Utility::AddToClass
bool AddToClass(PyObject *pyclass, const char *label, PyCFunction cfunc, int flags=METH_VARARGS)
Definition: Utility.cxx:169
name
char name[80]
Definition: TGX11.cxx:110
TDirectory
Describe directory structure in memory.
Definition: TDirectory.h:40
CPyCppyy::CPPInstance_Type
PyTypeObject CPPInstance_Type
Definition: CPPInstance.cxx:745
TKey.h
Class
void Class()
Definition: Class.C:29
Py_RETURN_NONE
#define Py_RETURN_NONE
Definition: CPyCppyy.h:281
int