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
23using 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}
#define CPyCppyy_PyText_AsString
Definition: CPyCppyy.h:97
#define Py_RETURN_NONE
Definition: CPyCppyy.h:281
#define CPyCppyy_PyText_Type
Definition: CPyCppyy.h:115
void Class()
Definition: Class.C:29
PyInt_FromLong
Definition: Converters.cxx:858
_object PyObject
Definition: PyMethodBase.h:41
TClass * GetTClass(const CPyCppyy::CPPInstance *pyobj)
PyObject * CallPyObjMethod(PyObject *obj, const char *meth)
Set of helper functions that are invoked from the C++ implementation of pythonizations.
long Long_t
Definition: RtypesCore.h:52
PyObject * TDirectoryWriteObject(CPPInstance *self, PyObject *args)
Implements the WriteObject method of TDirectory This method allows to write objects into TDirectory i...
PyObject * TDirectoryGetAttr(PyObject *self, PyObject *attr)
Implements a getter to assign to TDirectory.__getattr__ Method that is assigned to TDirectory....
char name[80]
Definition: TGX11.cxx:109
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:4878
Describe directory structure in memory.
Definition: TDirectory.h:40
bool AddToClass(PyObject *pyclass, const char *label, PyCFunction cfunc, int flags=METH_VARARGS)
Definition: Utility.cxx:169
PyTypeObject CPPInstance_Type
PyObject * AddDirectoryWritePyz(PyObject *self, PyObject *args)
Add pythonisation of TDirectory::WriteObject.
PyObject * AddDirectoryGetAttrPyz(PyObject *self, PyObject *args)
Add attr syntax to TDirectory.