ATLAS Offline Software
Loading...
Searching...
No Matches
Utility.cxx
Go to the documentation of this file.
1// This file's extension implies that it's C, but it's really -*- C++ -*-.
2/*
3 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
4*/
11
12
13// Called from python, so only excuted single-threaded (GIL).
16
17
18#include "Utility.h"
19#include "TInterpreter.h"
20#include <sstream>
21
22
23namespace RootUtils {
24
25
26int GetBuffer( PyObject* pyobject, char tc, int size, void*& buf, Bool_t check )
27{
28// Retrieve a linear buffer pointer from the given pyobject.
29
30// special case: don't handle character strings here (yes, they're buffers, but not quite)
31 if ( PyBytes_Check( pyobject ) )
32 return 0;
33
34// attempt to retrieve pointer to buffer interface
35 PyBufferProcs* bufprocs = Py_TYPE(pyobject)->tp_as_buffer;
36
37 PySequenceMethods* seqmeths = Py_TYPE(pyobject)->tp_as_sequence;
38 if ( seqmeths != 0 && bufprocs != 0
39 && bufprocs->bf_getbuffer != 0
40 ) {
41
42 // get the buffer
43 Py_buffer bufinfo;
44 (*(bufprocs->bf_getbuffer))( pyobject, &bufinfo, PyBUF_WRITABLE );
45 buf = (char*)bufinfo.buf;
46 Py_ssize_t buflen = bufinfo.len;
47
48 if ( buf && check == kTRUE ) {
49 // determine buffer compatibility (use "buf" as a status flag)
50 PyObject* pytc = PyObject_GetAttrString( pyobject, "typecode");
51 if ( pytc != 0 ) { // for array objects
52 const char* s = PyUnicode_AsUTF8AndSize( pytc, nullptr );
53 if ( s && s[0] != tc )
54 buf = 0; // no match
55 Py_DECREF( pytc );
56 } else if ( seqmeths->sq_length &&
57 (int)(buflen / (*(seqmeths->sq_length))( pyobject )) == size ) {
58 // this is a gamble ... may or may not be ok, but that's for the user
59 PyErr_Clear();
60 } else if ( buflen == size ) {
61 // also a gamble, but at least 1 item will fit into the buffer, so very likely ok ...
62 PyErr_Clear();
63 } else {
64 buf = 0; // not compatible
65
66 // clarify error message
67 PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
68 PyErr_Fetch( &pytype, &pyvalue, &pytrace );
69 const char* s = PyUnicode_AsUTF8AndSize( pyvalue, nullptr );
70 if (!s) s = "(null)";
71 PyObject* pyvalue2 = PyUnicode_FromFormat(
72 (char*)"%s and given element size (%ld) do not match needed (%d)",
73 s,
74 seqmeths->sq_length ? (Long_t)(buflen / (*(seqmeths->sq_length))( pyobject )) : (Long_t)buflen,
75 size );
76 Py_DECREF( pyvalue );
77 PyErr_Restore( pytype, pyvalue2, pytrace );
78 }
79 }
80
81 return buflen;
82 }
83
84 return 0;
85}
86
87
88//- public functions ---------------------------------------------------------
90{
91 return PyImport_ImportModule ("ROOT");
92}
93
94
96{
97 static PyObject* const rootModule = getRootModule();
98 Py_INCREF (rootModule);
99 return rootModule;
100}
101
102
103TClass* objectIsA (PyObject* obj)
104{
105 TClass* cls = nullptr;
106 PyObject* attr = PyObject_GetAttrString ((PyObject*)Py_TYPE(obj), "__cpp_name__");
107 if (attr) {
108 PyObject* buf = PyUnicode_AsASCIIString (attr);
109 if (buf) {
110 char* s = PyBytes_AsString (buf);
111 if (*s == '<') ++s;
112 if (strncmp (s, "ROOT.", 5) == 0)
113 s += 5;
114 if (strncmp (s, "cppyy.gbl.", 10) == 0)
115 s += 10;
116 cls = TClass::GetClass (s);
117 Py_DECREF(buf);
118 }
119 Py_DECREF(attr);
120 }
121 PyErr_Clear();
122 return cls;
123}
124
125
127{
128 PyObject* root = rootModule();
129 PyObject* ret = PyObject_GetAttrString (root, "SetOwnership");
130 Py_DECREF (root);
131 return ret;
132}
133
135{
136 static PyObject* const func = getSetOwnershipFunc();
137 Py_INCREF (func);
138 return func;
139}
140
141bool setOwnership (PyObject* obj, bool flag)
142{
143 PyObject* func = setOwnershipFunc();
144 PyObject* ret = PyObject_CallFunction (func, const_cast<char*>("OI"),
145 obj,
146 static_cast<unsigned int>(flag));
147 Py_DECREF (func);
148 if (ret) {
149 Py_DECREF (ret);
150 return true;
151 }
152 return false;
153}
154
155
156} // namespace RootUtils
_object PyObject
static Double_t tc
Utility code originally from pyroot.
Define macros for attributes used to control the static checker.
#define ATLAS_NO_CHECK_FILE_THREAD_SAFETY
PyObject * getRootModule()
Definition Utility.cxx:89
bool setOwnership(PyObject *obj, bool flag)
Definition Utility.cxx:141
PyObject * rootModule()
Definition Utility.cxx:95
int GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, Bool_t check)
Definition Utility.cxx:26
PyObject * setOwnershipFunc()
Definition Utility.cxx:134
PyObject * getSetOwnershipFunc()
Definition Utility.cxx:126
TClass * objectIsA(PyObject *obj)
Definition Utility.cxx:103