1edb35d95SEugene Zelenko //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===//
22c1f46dcSZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62c1f46dcSZachary Turner //
72c1f46dcSZachary Turner //===----------------------------------------------------------------------===//
82c1f46dcSZachary Turner
9085328eeSLawrence D'Anna //
10085328eeSLawrence D'Anna // !! FIXME FIXME FIXME !!
11085328eeSLawrence D'Anna //
12085328eeSLawrence D'Anna // Python APIs nearly all can return an exception. They do this
13085328eeSLawrence D'Anna // by returning NULL, or -1, or some such value and setting
14085328eeSLawrence D'Anna // the exception state with PyErr_Set*(). Exceptions must be
15085328eeSLawrence D'Anna // handled before further python API functions are called. Failure
16085328eeSLawrence D'Anna // to do so will result in asserts on debug builds of python.
17085328eeSLawrence D'Anna // It will also sometimes, but not usually result in crashes of
18085328eeSLawrence D'Anna // release builds.
19085328eeSLawrence D'Anna //
20085328eeSLawrence D'Anna // Nearly all the code in this header does not handle python exceptions
21085328eeSLawrence D'Anna // correctly. It should all be converted to return Expected<> or
22085328eeSLawrence D'Anna // Error types to capture the exception.
23085328eeSLawrence D'Anna //
24085328eeSLawrence D'Anna // Everything in this file except functions that return Error or
25085328eeSLawrence D'Anna // Expected<> is considered deprecated and should not be
26085328eeSLawrence D'Anna // used in new code. If you need to use it, fix it first.
27085328eeSLawrence D'Anna //
28d3bd5b3dSLawrence D'Anna //
29d3bd5b3dSLawrence D'Anna // TODOs for this file
30d3bd5b3dSLawrence D'Anna //
31d3bd5b3dSLawrence D'Anna // * Make all methods safe for exceptions.
32d3bd5b3dSLawrence D'Anna //
33d3bd5b3dSLawrence D'Anna // * Eliminate method signatures that must translate exceptions into
34d3bd5b3dSLawrence D'Anna // empty objects or NULLs. Almost everything here should return
35d3bd5b3dSLawrence D'Anna // Expected<>. It should be acceptable for certain operations that
36d3bd5b3dSLawrence D'Anna // can never fail to assert instead, such as the creation of
37d3bd5b3dSLawrence D'Anna // PythonString from a string literal.
38d3bd5b3dSLawrence D'Anna //
39e9264b74SKazuaki Ishizaki // * Eliminate Reset(), and make all non-default constructors private.
40d3bd5b3dSLawrence D'Anna // Python objects should be created with Retain<> or Take<>, and they
41d3bd5b3dSLawrence D'Anna // should be assigned with operator=
42d3bd5b3dSLawrence D'Anna //
43d3bd5b3dSLawrence D'Anna // * Eliminate default constructors, make python objects always
44d3bd5b3dSLawrence D'Anna // nonnull, and use optionals where necessary.
45d3bd5b3dSLawrence D'Anna //
46d3bd5b3dSLawrence D'Anna
47085328eeSLawrence D'Anna
482c1f46dcSZachary Turner #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
492c1f46dcSZachary Turner #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
502c1f46dcSZachary Turner
5159998b7bSJonas Devlieghere #include "lldb/Host/Config.h"
5259998b7bSJonas Devlieghere
534e26cf2cSJonas Devlieghere #if LLDB_ENABLE_PYTHON
54d68983e3SPavel Labath
5541de9a97SKate Stone // LLDB Python header must be included first
5641de9a97SKate Stone #include "lldb-python.h"
5741de9a97SKate Stone
589c40264fSZachary Turner #include "lldb/Host/File.h"
59f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
602c1f46dcSZachary Turner
615a72c02bSZachary Turner #include "llvm/ADT/ArrayRef.h"
625a72c02bSZachary Turner
632c1f46dcSZachary Turner namespace lldb_private {
6404edd189SLawrence D'Anna namespace python {
65edb35d95SEugene Zelenko
66085328eeSLawrence D'Anna class PythonObject;
675a72c02bSZachary Turner class PythonBytes;
682c1f46dcSZachary Turner class PythonString;
692c1f46dcSZachary Turner class PythonList;
702c1f46dcSZachary Turner class PythonDictionary;
712c1f46dcSZachary Turner class PythonInteger;
72085328eeSLawrence D'Anna class PythonException;
732c1f46dcSZachary Turner
74bbef51ebSLawrence D'Anna class GIL {
75bbef51ebSLawrence D'Anna public:
GIL()76bbef51ebSLawrence D'Anna GIL() {
77bbef51ebSLawrence D'Anna m_state = PyGILState_Ensure();
78bbef51ebSLawrence D'Anna assert(!PyErr_Occurred());
79bbef51ebSLawrence D'Anna }
~GIL()80bbef51ebSLawrence D'Anna ~GIL() { PyGILState_Release(m_state); }
81bbef51ebSLawrence D'Anna
82bbef51ebSLawrence D'Anna protected:
83bbef51ebSLawrence D'Anna PyGILState_STATE m_state;
84bbef51ebSLawrence D'Anna };
85bbef51ebSLawrence D'Anna
86b9c1b51eSKate Stone enum class PyObjectType {
872c1f46dcSZachary Turner Unknown,
882c1f46dcSZachary Turner None,
89b81d715cSTatyana Krasnukha Boolean,
902c1f46dcSZachary Turner Integer,
912c1f46dcSZachary Turner Dictionary,
922c1f46dcSZachary Turner List,
939c40264fSZachary Turner String,
945a72c02bSZachary Turner Bytes,
95f9d6d204SZachary Turner ByteArray,
967841efbbSZachary Turner Module,
97a1405147SZachary Turner Callable,
98a1405147SZachary Turner Tuple,
999c40264fSZachary Turner File
1002c1f46dcSZachary Turner };
1012c1f46dcSZachary Turner
102b9c1b51eSKate Stone enum class PyRefType {
103f8b22f8fSZachary Turner Borrowed, // We are not given ownership of the incoming PyObject.
104f8b22f8fSZachary Turner // We cannot safely hold it without calling Py_INCREF.
105f8b22f8fSZachary Turner Owned // We have ownership of the incoming PyObject. We should
106f8b22f8fSZachary Turner // not call Py_INCREF.
107f8b22f8fSZachary Turner };
108f8b22f8fSZachary Turner
109085328eeSLawrence D'Anna
110085328eeSLawrence D'Anna // Take a reference that you already own, and turn it into
111085328eeSLawrence D'Anna // a PythonObject.
112085328eeSLawrence D'Anna //
113085328eeSLawrence D'Anna // Most python API methods will return a +1 reference
114085328eeSLawrence D'Anna // if they succeed or NULL if and only if
115085328eeSLawrence D'Anna // they set an exception. Use this to collect such return
116085328eeSLawrence D'Anna // values, after checking for NULL.
117085328eeSLawrence D'Anna //
118085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be
119085328eeSLawrence D'Anna // checked to be of the correct type.
Take(PyObject * obj)120085328eeSLawrence D'Anna template <typename T> T Take(PyObject *obj) {
121085328eeSLawrence D'Anna assert(obj);
122085328eeSLawrence D'Anna assert(!PyErr_Occurred());
123085328eeSLawrence D'Anna T thing(PyRefType::Owned, obj);
124085328eeSLawrence D'Anna assert(thing.IsValid());
1251dfb1a85SPavel Labath return thing;
126085328eeSLawrence D'Anna }
127085328eeSLawrence D'Anna
128085328eeSLawrence D'Anna // Retain a reference you have borrowed, and turn it into
129085328eeSLawrence D'Anna // a PythonObject.
130085328eeSLawrence D'Anna //
131085328eeSLawrence D'Anna // A minority of python APIs return a borrowed reference
132085328eeSLawrence D'Anna // instead of a +1. They will also return NULL if and only
133085328eeSLawrence D'Anna // if they set an exception. Use this to collect such return
134085328eeSLawrence D'Anna // values, after checking for NULL.
135085328eeSLawrence D'Anna //
136085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be
137085328eeSLawrence D'Anna // checked to be of the correct type.
Retain(PyObject * obj)138085328eeSLawrence D'Anna template <typename T> T Retain(PyObject *obj) {
139085328eeSLawrence D'Anna assert(obj);
140085328eeSLawrence D'Anna assert(!PyErr_Occurred());
141085328eeSLawrence D'Anna T thing(PyRefType::Borrowed, obj);
142085328eeSLawrence D'Anna assert(thing.IsValid());
1431dfb1a85SPavel Labath return thing;
144085328eeSLawrence D'Anna }
145085328eeSLawrence D'Anna
146722b6189SLawrence D'Anna // This class can be used like a utility function to convert from
147722b6189SLawrence D'Anna // a llvm-friendly Twine into a null-terminated const char *,
148722b6189SLawrence D'Anna // which is the form python C APIs want their strings in.
149722b6189SLawrence D'Anna //
150722b6189SLawrence D'Anna // Example:
151722b6189SLawrence D'Anna // const llvm::Twine &some_twine;
152722b6189SLawrence D'Anna // PyFoo_Bar(x, y, z, NullTerminated(some_twine));
153722b6189SLawrence D'Anna //
154722b6189SLawrence D'Anna // Why a class instead of a function? If the twine isn't already null
155722b6189SLawrence D'Anna // terminated, it will need a temporary buffer to copy the string
156722b6189SLawrence D'Anna // into. We need that buffer to stick around for the lifetime of the
157722b6189SLawrence D'Anna // statement.
158722b6189SLawrence D'Anna class NullTerminated {
159722b6189SLawrence D'Anna const char *str;
160722b6189SLawrence D'Anna llvm::SmallString<32> storage;
161722b6189SLawrence D'Anna
162722b6189SLawrence D'Anna public:
NullTerminated(const llvm::Twine & twine)163722b6189SLawrence D'Anna NullTerminated(const llvm::Twine &twine) {
164722b6189SLawrence D'Anna llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
165722b6189SLawrence D'Anna str = ref.begin();
166722b6189SLawrence D'Anna }
167722b6189SLawrence D'Anna operator const char *() { return str; }
168722b6189SLawrence D'Anna };
169722b6189SLawrence D'Anna
nullDeref()17004edd189SLawrence D'Anna inline llvm::Error nullDeref() {
17104edd189SLawrence D'Anna return llvm::createStringError(llvm::inconvertibleErrorCode(),
17204edd189SLawrence D'Anna "A NULL PyObject* was dereferenced");
17304edd189SLawrence D'Anna }
17404edd189SLawrence D'Anna
17504edd189SLawrence D'Anna inline llvm::Error exception(const char *s = nullptr) {
17604edd189SLawrence D'Anna return llvm::make_error<PythonException>(s);
17704edd189SLawrence D'Anna }
17804edd189SLawrence D'Anna
keyError()17904edd189SLawrence D'Anna inline llvm::Error keyError() {
18004edd189SLawrence D'Anna return llvm::createStringError(llvm::inconvertibleErrorCode(),
18104edd189SLawrence D'Anna "key not in dict");
18204edd189SLawrence D'Anna }
183085328eeSLawrence D'Anna
py2_const_cast(const char * s)1846a93a12aSLawrence D'Anna inline const char *py2_const_cast(const char *s) { return s; }
1856a93a12aSLawrence D'Anna
186b9c1b51eSKate Stone enum class PyInitialValue { Invalid, Empty };
187f8b22f8fSZachary Turner
188085328eeSLawrence D'Anna template <typename T, typename Enable = void> struct PythonFormat;
189085328eeSLawrence D'Anna
190085328eeSLawrence D'Anna template <> struct PythonFormat<unsigned long long> {
191085328eeSLawrence D'Anna static constexpr char format = 'K';
192085328eeSLawrence D'Anna static auto get(unsigned long long value) { return value; }
193085328eeSLawrence D'Anna };
194085328eeSLawrence D'Anna
195085328eeSLawrence D'Anna template <> struct PythonFormat<long long> {
196085328eeSLawrence D'Anna static constexpr char format = 'L';
197085328eeSLawrence D'Anna static auto get(long long value) { return value; }
198085328eeSLawrence D'Anna };
199085328eeSLawrence D'Anna
20004edd189SLawrence D'Anna template <> struct PythonFormat<PyObject *> {
20104edd189SLawrence D'Anna static constexpr char format = 'O';
20204edd189SLawrence D'Anna static auto get(PyObject *value) { return value; }
20304edd189SLawrence D'Anna };
20404edd189SLawrence D'Anna
205085328eeSLawrence D'Anna template <typename T>
206085328eeSLawrence D'Anna struct PythonFormat<
207085328eeSLawrence D'Anna T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
208085328eeSLawrence D'Anna static constexpr char format = 'O';
209085328eeSLawrence D'Anna static auto get(const T &value) { return value.get(); }
210085328eeSLawrence D'Anna };
211085328eeSLawrence D'Anna
212b9c1b51eSKate Stone class PythonObject {
2132c1f46dcSZachary Turner public:
214fd2433e1SJonas Devlieghere PythonObject() = default;
2152c1f46dcSZachary Turner
21604edd189SLawrence D'Anna PythonObject(PyRefType type, PyObject *py_obj) {
21704edd189SLawrence D'Anna m_py_obj = py_obj;
21804edd189SLawrence D'Anna // If this is a borrowed reference, we need to convert it to
21904edd189SLawrence D'Anna // an owned reference by incrementing it. If it is an owned
22004edd189SLawrence D'Anna // reference (for example the caller allocated it with PyDict_New()
22104edd189SLawrence D'Anna // then we must *not* increment it.
22204edd189SLawrence D'Anna if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
22304edd189SLawrence D'Anna Py_XINCREF(m_py_obj);
2242c1f46dcSZachary Turner }
2252c1f46dcSZachary Turner
22603819d1cSLawrence D'Anna PythonObject(const PythonObject &rhs)
22703819d1cSLawrence D'Anna : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
2282c1f46dcSZachary Turner
229085328eeSLawrence D'Anna PythonObject(PythonObject &&rhs) {
230085328eeSLawrence D'Anna m_py_obj = rhs.m_py_obj;
231085328eeSLawrence D'Anna rhs.m_py_obj = nullptr;
232085328eeSLawrence D'Anna }
233085328eeSLawrence D'Anna
234d3bd5b3dSLawrence D'Anna ~PythonObject() { Reset(); }
2352c1f46dcSZachary Turner
2366ff4af8eSPavel Labath void Reset();
237f8b22f8fSZachary Turner
238b9c1b51eSKate Stone void Dump() const {
2392c1f46dcSZachary Turner if (m_py_obj)
2402c1f46dcSZachary Turner _PyObject_Dump(m_py_obj);
2412c1f46dcSZachary Turner else
2422c1f46dcSZachary Turner puts("NULL");
2432c1f46dcSZachary Turner }
2442c1f46dcSZachary Turner
245b9c1b51eSKate Stone void Dump(Stream &strm) const;
2462c1f46dcSZachary Turner
247b9c1b51eSKate Stone PyObject *get() const { return m_py_obj; }
2482c1f46dcSZachary Turner
249b9c1b51eSKate Stone PyObject *release() {
25060c24f70SZachary Turner PyObject *result = m_py_obj;
25160c24f70SZachary Turner m_py_obj = nullptr;
25260c24f70SZachary Turner return result;
25360c24f70SZachary Turner }
25460c24f70SZachary Turner
25503819d1cSLawrence D'Anna PythonObject &operator=(PythonObject other) {
256085328eeSLawrence D'Anna Reset();
25703819d1cSLawrence D'Anna m_py_obj = std::exchange(other.m_py_obj, nullptr);
258085328eeSLawrence D'Anna return *this;
259085328eeSLawrence D'Anna }
260085328eeSLawrence D'Anna
261b9c1b51eSKate Stone PyObjectType GetObjectType() const;
2627841efbbSZachary Turner
263b9c1b51eSKate Stone PythonString Repr() const;
2647841efbbSZachary Turner
265b9c1b51eSKate Stone PythonString Str() const;
2667841efbbSZachary Turner
267b9c1b51eSKate Stone static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
268b9c1b51eSKate Stone const PythonDictionary &dict);
2697841efbbSZachary Turner
270b58fb2f4SZachary Turner template <typename T>
271b9c1b51eSKate Stone static T ResolveNameWithDictionary(llvm::StringRef name,
272b9c1b51eSKate Stone const PythonDictionary &dict) {
273b58fb2f4SZachary Turner return ResolveNameWithDictionary(name, dict).AsType<T>();
274b58fb2f4SZachary Turner }
275b58fb2f4SZachary Turner
276b9c1b51eSKate Stone PythonObject ResolveName(llvm::StringRef name) const;
2777841efbbSZachary Turner
278b9c1b51eSKate Stone template <typename T> T ResolveName(llvm::StringRef name) const {
279b58fb2f4SZachary Turner return ResolveName(name).AsType<T>();
280b58fb2f4SZachary Turner }
281b58fb2f4SZachary Turner
282b9c1b51eSKate Stone bool HasAttribute(llvm::StringRef attribute) const;
2839c40264fSZachary Turner
284b9c1b51eSKate Stone PythonObject GetAttributeValue(llvm::StringRef attribute) const;
2857d6d218eSZachary Turner
286085328eeSLawrence D'Anna bool IsNone() const { return m_py_obj == Py_None; }
287f8b22f8fSZachary Turner
288085328eeSLawrence D'Anna bool IsValid() const { return m_py_obj != nullptr; }
289f8b22f8fSZachary Turner
290085328eeSLawrence D'Anna bool IsAllocated() const { return IsValid() && !IsNone(); }
291085328eeSLawrence D'Anna
292085328eeSLawrence D'Anna explicit operator bool() const { return IsValid() && !IsNone(); }
2932c1f46dcSZachary Turner
294b9c1b51eSKate Stone template <typename T> T AsType() const {
2957d6d218eSZachary Turner if (!T::Check(m_py_obj))
2967d6d218eSZachary Turner return T();
2977d6d218eSZachary Turner return T(PyRefType::Borrowed, m_py_obj);
2987d6d218eSZachary Turner }
2997d6d218eSZachary Turner
300b9c1b51eSKate Stone StructuredData::ObjectSP CreateStructuredObject() const;
3012c1f46dcSZachary Turner
302085328eeSLawrence D'Anna template <typename... T>
303085328eeSLawrence D'Anna llvm::Expected<PythonObject> CallMethod(const char *name,
304085328eeSLawrence D'Anna const T &... t) const {
305085328eeSLawrence D'Anna const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
306085328eeSLawrence D'Anna PyObject *obj =
307c86a6acaSLawrence D'Anna PyObject_CallMethod(m_py_obj, py2_const_cast(name),
308c86a6acaSLawrence D'Anna py2_const_cast(format), PythonFormat<T>::get(t)...);
309c86a6acaSLawrence D'Anna if (!obj)
310c86a6acaSLawrence D'Anna return exception();
311c86a6acaSLawrence D'Anna return python::Take<PythonObject>(obj);
312c86a6acaSLawrence D'Anna }
313c86a6acaSLawrence D'Anna
314c86a6acaSLawrence D'Anna template <typename... T>
315c86a6acaSLawrence D'Anna llvm::Expected<PythonObject> Call(const T &... t) const {
316c86a6acaSLawrence D'Anna const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
317c86a6acaSLawrence D'Anna PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
318c86a6acaSLawrence D'Anna PythonFormat<T>::get(t)...);
319085328eeSLawrence D'Anna if (!obj)
320085328eeSLawrence D'Anna return exception();
321085328eeSLawrence D'Anna return python::Take<PythonObject>(obj);
322085328eeSLawrence D'Anna }
323085328eeSLawrence D'Anna
324722b6189SLawrence D'Anna llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
325085328eeSLawrence D'Anna if (!m_py_obj)
326085328eeSLawrence D'Anna return nullDeref();
327722b6189SLawrence D'Anna PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
328085328eeSLawrence D'Anna if (!obj)
329085328eeSLawrence D'Anna return exception();
330085328eeSLawrence D'Anna return python::Take<PythonObject>(obj);
331085328eeSLawrence D'Anna }
332085328eeSLawrence D'Anna
333085328eeSLawrence D'Anna llvm::Expected<bool> IsTrue() {
334085328eeSLawrence D'Anna if (!m_py_obj)
335085328eeSLawrence D'Anna return nullDeref();
336085328eeSLawrence D'Anna int r = PyObject_IsTrue(m_py_obj);
337085328eeSLawrence D'Anna if (r < 0)
338085328eeSLawrence D'Anna return exception();
339085328eeSLawrence D'Anna return !!r;
340085328eeSLawrence D'Anna }
341085328eeSLawrence D'Anna
34252712d3fSLawrence D'Anna llvm::Expected<long long> AsLongLong() const;
34352712d3fSLawrence D'Anna
34452712d3fSLawrence D'Anna llvm::Expected<long long> AsUnsignedLongLong() const;
34552712d3fSLawrence D'Anna
34652712d3fSLawrence D'Anna // wraps on overflow, instead of raising an error.
34752712d3fSLawrence D'Anna llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
348085328eeSLawrence D'Anna
349085328eeSLawrence D'Anna llvm::Expected<bool> IsInstance(const PythonObject &cls) {
350085328eeSLawrence D'Anna if (!m_py_obj || !cls.IsValid())
351085328eeSLawrence D'Anna return nullDeref();
352085328eeSLawrence D'Anna int r = PyObject_IsInstance(m_py_obj, cls.get());
353085328eeSLawrence D'Anna if (r < 0)
354085328eeSLawrence D'Anna return exception();
355085328eeSLawrence D'Anna return !!r;
356085328eeSLawrence D'Anna }
357085328eeSLawrence D'Anna
358085328eeSLawrence D'Anna protected:
3599494c510SJonas Devlieghere PyObject *m_py_obj = nullptr;
3602c1f46dcSZachary Turner };
3612c1f46dcSZachary Turner
362085328eeSLawrence D'Anna
363085328eeSLawrence D'Anna // This is why C++ needs monads.
364085328eeSLawrence D'Anna template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
365085328eeSLawrence D'Anna if (!obj)
366085328eeSLawrence D'Anna return obj.takeError();
367085328eeSLawrence D'Anna if (!T::Check(obj.get().get()))
368085328eeSLawrence D'Anna return llvm::createStringError(llvm::inconvertibleErrorCode(),
369085328eeSLawrence D'Anna "type error");
370085328eeSLawrence D'Anna return T(PyRefType::Borrowed, std::move(obj.get().get()));
371085328eeSLawrence D'Anna }
372085328eeSLawrence D'Anna
373085328eeSLawrence D'Anna template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
374085328eeSLawrence D'Anna
375085328eeSLawrence D'Anna template <>
376085328eeSLawrence D'Anna llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
377085328eeSLawrence D'Anna
378c86a6acaSLawrence D'Anna template <>
37952712d3fSLawrence D'Anna llvm::Expected<unsigned long long>
38052712d3fSLawrence D'Anna As<unsigned long long>(llvm::Expected<PythonObject> &&obj);
38152712d3fSLawrence D'Anna
38252712d3fSLawrence D'Anna template <>
383c86a6acaSLawrence D'Anna llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
384c86a6acaSLawrence D'Anna
385085328eeSLawrence D'Anna
386d3bd5b3dSLawrence D'Anna template <class T> class TypedPythonObject : public PythonObject {
3875a72c02bSZachary Turner public:
388722b6189SLawrence D'Anna TypedPythonObject(PyRefType type, PyObject *py_obj) {
389d3bd5b3dSLawrence D'Anna if (!py_obj)
390d3bd5b3dSLawrence D'Anna return;
391d3bd5b3dSLawrence D'Anna if (T::Check(py_obj))
39204edd189SLawrence D'Anna PythonObject::operator=(PythonObject(type, py_obj));
393d3bd5b3dSLawrence D'Anna else if (type == PyRefType::Owned)
394d3bd5b3dSLawrence D'Anna Py_DECREF(py_obj);
395d3bd5b3dSLawrence D'Anna }
396d3bd5b3dSLawrence D'Anna
397fd2433e1SJonas Devlieghere TypedPythonObject() = default;
398d3bd5b3dSLawrence D'Anna };
399d3bd5b3dSLawrence D'Anna
400d3bd5b3dSLawrence D'Anna class PythonBytes : public TypedPythonObject<PythonBytes> {
401d3bd5b3dSLawrence D'Anna public:
402d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
4035a72c02bSZachary Turner explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
4045a72c02bSZachary Turner PythonBytes(const uint8_t *bytes, size_t length);
4055a72c02bSZachary Turner
406b9c1b51eSKate Stone static bool Check(PyObject *py_obj);
4075a72c02bSZachary Turner
408b9c1b51eSKate Stone llvm::ArrayRef<uint8_t> GetBytes() const;
4095a72c02bSZachary Turner
410b9c1b51eSKate Stone size_t GetSize() const;
4115a72c02bSZachary Turner
412b9c1b51eSKate Stone void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4135a72c02bSZachary Turner
414b9c1b51eSKate Stone StructuredData::StringSP CreateStructuredString() const;
4155a72c02bSZachary Turner };
4165a72c02bSZachary Turner
417d3bd5b3dSLawrence D'Anna class PythonByteArray : public TypedPythonObject<PythonByteArray> {
418f9d6d204SZachary Turner public:
419d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
420f9d6d204SZachary Turner explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
421f9d6d204SZachary Turner PythonByteArray(const uint8_t *bytes, size_t length);
422f9d6d204SZachary Turner PythonByteArray(const PythonBytes &object);
423f9d6d204SZachary Turner
424b9c1b51eSKate Stone static bool Check(PyObject *py_obj);
425f9d6d204SZachary Turner
426b9c1b51eSKate Stone llvm::ArrayRef<uint8_t> GetBytes() const;
427f9d6d204SZachary Turner
428b9c1b51eSKate Stone size_t GetSize() const;
429f9d6d204SZachary Turner
430b9c1b51eSKate Stone void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
431f9d6d204SZachary Turner
432b9c1b51eSKate Stone StructuredData::StringSP CreateStructuredString() const;
433f9d6d204SZachary Turner };
434f9d6d204SZachary Turner
435d3bd5b3dSLawrence D'Anna class PythonString : public TypedPythonObject<PythonString> {
4362c1f46dcSZachary Turner public:
437d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
438085328eeSLawrence D'Anna static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
439085328eeSLawrence D'Anna
440d3bd5b3dSLawrence D'Anna PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
441edb35d95SEugene Zelenko
442d3bd5b3dSLawrence D'Anna explicit PythonString(llvm::StringRef string); // safe, null on error
4432c1f46dcSZachary Turner
44422c8efcdSZachary Turner static bool Check(PyObject *py_obj);
4452c1f46dcSZachary Turner
446085328eeSLawrence D'Anna llvm::StringRef GetString() const; // safe, empty string on error
447085328eeSLawrence D'Anna
448085328eeSLawrence D'Anna llvm::Expected<llvm::StringRef> AsUTF8() const;
4492c1f46dcSZachary Turner
450b9c1b51eSKate Stone size_t GetSize() const;
4512c1f46dcSZachary Turner
452085328eeSLawrence D'Anna void SetString(llvm::StringRef string); // safe, null on error
4532c1f46dcSZachary Turner
4542c1f46dcSZachary Turner StructuredData::StringSP CreateStructuredString() const;
4552c1f46dcSZachary Turner };
4562c1f46dcSZachary Turner
457d3bd5b3dSLawrence D'Anna class PythonInteger : public TypedPythonObject<PythonInteger> {
4582c1f46dcSZachary Turner public:
459d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
460edb35d95SEugene Zelenko
461d3bd5b3dSLawrence D'Anna PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
462d3bd5b3dSLawrence D'Anna
463d3bd5b3dSLawrence D'Anna explicit PythonInteger(int64_t value);
4642c1f46dcSZachary Turner
46522c8efcdSZachary Turner static bool Check(PyObject *py_obj);
4662c1f46dcSZachary Turner
467b9c1b51eSKate Stone void SetInteger(int64_t value);
4682c1f46dcSZachary Turner
4692c1f46dcSZachary Turner StructuredData::IntegerSP CreateStructuredInteger() const;
4702c1f46dcSZachary Turner };
4712c1f46dcSZachary Turner
472d3bd5b3dSLawrence D'Anna class PythonBoolean : public TypedPythonObject<PythonBoolean> {
473b81d715cSTatyana Krasnukha public:
474d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
475b81d715cSTatyana Krasnukha
476d3bd5b3dSLawrence D'Anna explicit PythonBoolean(bool value);
477b81d715cSTatyana Krasnukha
478b81d715cSTatyana Krasnukha static bool Check(PyObject *py_obj);
479b81d715cSTatyana Krasnukha
480b81d715cSTatyana Krasnukha bool GetValue() const;
481b81d715cSTatyana Krasnukha
482b81d715cSTatyana Krasnukha void SetValue(bool value);
483b81d715cSTatyana Krasnukha
484b81d715cSTatyana Krasnukha StructuredData::BooleanSP CreateStructuredBoolean() const;
485b81d715cSTatyana Krasnukha };
486b81d715cSTatyana Krasnukha
487d3bd5b3dSLawrence D'Anna class PythonList : public TypedPythonObject<PythonList> {
4882c1f46dcSZachary Turner public:
489d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
490d3bd5b3dSLawrence D'Anna
491d3bd5b3dSLawrence D'Anna PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
492d3bd5b3dSLawrence D'Anna
49387f47729SZachary Turner explicit PythonList(PyInitialValue value);
49487f47729SZachary Turner explicit PythonList(int list_size);
4952c1f46dcSZachary Turner
49622c8efcdSZachary Turner static bool Check(PyObject *py_obj);
49722c8efcdSZachary Turner
4982c1f46dcSZachary Turner uint32_t GetSize() const;
4992c1f46dcSZachary Turner
5002c1f46dcSZachary Turner PythonObject GetItemAtIndex(uint32_t index) const;
5012c1f46dcSZachary Turner
502f8b22f8fSZachary Turner void SetItemAtIndex(uint32_t index, const PythonObject &object);
5032c1f46dcSZachary Turner
504f8b22f8fSZachary Turner void AppendItem(const PythonObject &object);
5052c1f46dcSZachary Turner
5062c1f46dcSZachary Turner StructuredData::ArraySP CreateStructuredArray() const;
5072c1f46dcSZachary Turner };
5082c1f46dcSZachary Turner
509d3bd5b3dSLawrence D'Anna class PythonTuple : public TypedPythonObject<PythonTuple> {
510a1405147SZachary Turner public:
511d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
512d3bd5b3dSLawrence D'Anna
513a1405147SZachary Turner explicit PythonTuple(PyInitialValue value);
514a1405147SZachary Turner explicit PythonTuple(int tuple_size);
515a1405147SZachary Turner PythonTuple(std::initializer_list<PythonObject> objects);
516a1405147SZachary Turner PythonTuple(std::initializer_list<PyObject *> objects);
517a1405147SZachary Turner
518a1405147SZachary Turner static bool Check(PyObject *py_obj);
519a1405147SZachary Turner
520a1405147SZachary Turner uint32_t GetSize() const;
521a1405147SZachary Turner
522a1405147SZachary Turner PythonObject GetItemAtIndex(uint32_t index) const;
523a1405147SZachary Turner
524a1405147SZachary Turner void SetItemAtIndex(uint32_t index, const PythonObject &object);
525a1405147SZachary Turner
526a1405147SZachary Turner StructuredData::ArraySP CreateStructuredArray() const;
527a1405147SZachary Turner };
528a1405147SZachary Turner
529d3bd5b3dSLawrence D'Anna class PythonDictionary : public TypedPythonObject<PythonDictionary> {
5302c1f46dcSZachary Turner public:
531d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
532edb35d95SEugene Zelenko
533d3bd5b3dSLawrence D'Anna PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
534d3bd5b3dSLawrence D'Anna
535d3bd5b3dSLawrence D'Anna explicit PythonDictionary(PyInitialValue value);
5362c1f46dcSZachary Turner
53722c8efcdSZachary Turner static bool Check(PyObject *py_obj);
53822c8efcdSZachary Turner
5392c1f46dcSZachary Turner uint32_t GetSize() const;
5402c1f46dcSZachary Turner
541f8b22f8fSZachary Turner PythonList GetKeys() const;
5422c1f46dcSZachary Turner
543c86a6acaSLawrence D'Anna PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
544c86a6acaSLawrence D'Anna void SetItemForKey(const PythonObject &key,
545c86a6acaSLawrence D'Anna const PythonObject &value); // DEPRECATED
546c86a6acaSLawrence D'Anna
547c86a6acaSLawrence D'Anna llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
548722b6189SLawrence D'Anna llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
549c86a6acaSLawrence D'Anna llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
550722b6189SLawrence D'Anna llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
5512c1f46dcSZachary Turner
5522c1f46dcSZachary Turner StructuredData::DictionarySP CreateStructuredDictionary() const;
5532c1f46dcSZachary Turner };
55487f47729SZachary Turner
555d3bd5b3dSLawrence D'Anna class PythonModule : public TypedPythonObject<PythonModule> {
5567841efbbSZachary Turner public:
557d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
5587841efbbSZachary Turner
5597841efbbSZachary Turner static bool Check(PyObject *py_obj);
5607841efbbSZachary Turner
561b9c1b51eSKate Stone static PythonModule BuiltinsModule();
562a1405147SZachary Turner
563b9c1b51eSKate Stone static PythonModule MainModule();
564a1405147SZachary Turner
565b9c1b51eSKate Stone static PythonModule AddModule(llvm::StringRef module);
5667841efbbSZachary Turner
567085328eeSLawrence D'Anna // safe, returns invalid on error;
568085328eeSLawrence D'Anna static PythonModule ImportModule(llvm::StringRef name) {
569adcd0268SBenjamin Kramer std::string s = std::string(name);
570085328eeSLawrence D'Anna auto mod = Import(s.c_str());
571085328eeSLawrence D'Anna if (!mod) {
572085328eeSLawrence D'Anna llvm::consumeError(mod.takeError());
573085328eeSLawrence D'Anna return PythonModule();
574085328eeSLawrence D'Anna }
575085328eeSLawrence D'Anna return std::move(mod.get());
576085328eeSLawrence D'Anna }
577085328eeSLawrence D'Anna
578722b6189SLawrence D'Anna static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
579085328eeSLawrence D'Anna
580722b6189SLawrence D'Anna llvm::Expected<PythonObject> Get(const llvm::Twine &name);
5812419f1d5SZachary Turner
5827841efbbSZachary Turner PythonDictionary GetDictionary() const;
5837841efbbSZachary Turner };
5847841efbbSZachary Turner
585d3bd5b3dSLawrence D'Anna class PythonCallable : public TypedPythonObject<PythonCallable> {
586a1405147SZachary Turner public:
587d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
588d3bd5b3dSLawrence D'Anna
589b58fb2f4SZachary Turner struct ArgInfo {
5902386537cSLawrence D'Anna /* the largest number of positional arguments this callable
5912386537cSLawrence D'Anna * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
5922386537cSLawrence D'Anna * function and can accept an arbitrary number */
5932386537cSLawrence D'Anna unsigned max_positional_args;
5942386537cSLawrence D'Anna static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
595b58fb2f4SZachary Turner };
596b58fb2f4SZachary Turner
597b9c1b51eSKate Stone static bool Check(PyObject *py_obj);
598a1405147SZachary Turner
599c86a6acaSLawrence D'Anna llvm::Expected<ArgInfo> GetArgInfo() const;
600c86a6acaSLawrence D'Anna
601b9c1b51eSKate Stone PythonObject operator()();
602a1405147SZachary Turner
603b9c1b51eSKate Stone PythonObject operator()(std::initializer_list<PyObject *> args);
604a1405147SZachary Turner
605b9c1b51eSKate Stone PythonObject operator()(std::initializer_list<PythonObject> args);
606b58fb2f4SZachary Turner
607b58fb2f4SZachary Turner template <typename Arg, typename... Args>
608b9c1b51eSKate Stone PythonObject operator()(const Arg &arg, Args... args) {
609b58fb2f4SZachary Turner return operator()({arg, args...});
610b58fb2f4SZachary Turner }
611a1405147SZachary Turner };
612a1405147SZachary Turner
613d3bd5b3dSLawrence D'Anna class PythonFile : public TypedPythonObject<PythonFile> {
6149c40264fSZachary Turner public:
615d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject;
616edb35d95SEugene Zelenko
617d3bd5b3dSLawrence D'Anna PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
6189c40264fSZachary Turner
6199c40264fSZachary Turner static bool Check(PyObject *py_obj);
6209c40264fSZachary Turner
621d9b553ecSLawrence D'Anna static llvm::Expected<PythonFile> FromFile(File &file,
622d9b553ecSLawrence D'Anna const char *mode = nullptr);
623d9b553ecSLawrence D'Anna
624085328eeSLawrence D'Anna llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
625085328eeSLawrence D'Anna llvm::Expected<lldb::FileSP>
626085328eeSLawrence D'Anna ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
6279c40264fSZachary Turner };
6289c40264fSZachary Turner
629085328eeSLawrence D'Anna class PythonException : public llvm::ErrorInfo<PythonException> {
630085328eeSLawrence D'Anna private:
631085328eeSLawrence D'Anna PyObject *m_exception_type, *m_exception, *m_traceback;
632085328eeSLawrence D'Anna PyObject *m_repr_bytes;
633085328eeSLawrence D'Anna
634085328eeSLawrence D'Anna public:
635085328eeSLawrence D'Anna static char ID;
636085328eeSLawrence D'Anna const char *toCString() const;
637085328eeSLawrence D'Anna PythonException(const char *caller = nullptr);
638085328eeSLawrence D'Anna void Restore();
639*99166339SJonas Devlieghere ~PythonException() override;
640085328eeSLawrence D'Anna void log(llvm::raw_ostream &OS) const override;
641085328eeSLawrence D'Anna std::error_code convertToErrorCode() const override;
64204edd189SLawrence D'Anna bool Matches(PyObject *exc) const;
64304edd189SLawrence D'Anna std::string ReadBacktrace() const;
644085328eeSLawrence D'Anna };
645085328eeSLawrence D'Anna
646085328eeSLawrence D'Anna // This extracts the underlying T out of an Expected<T> and returns it.
647085328eeSLawrence D'Anna // If the Expected is an Error instead of a T, that error will be converted
648085328eeSLawrence D'Anna // into a python exception, and this will return a default-constructed T.
649085328eeSLawrence D'Anna //
650085328eeSLawrence D'Anna // This is appropriate for use right at the boundary of python calling into
651085328eeSLawrence D'Anna // C++, such as in a SWIG typemap. In such a context you should simply
652085328eeSLawrence D'Anna // check if the returned T is valid, and if it is, return a NULL back
653085328eeSLawrence D'Anna // to python. This will result in the Error being raised as an exception
654085328eeSLawrence D'Anna // from python code's point of view.
655085328eeSLawrence D'Anna //
656085328eeSLawrence D'Anna // For example:
657085328eeSLawrence D'Anna // ```
658085328eeSLawrence D'Anna // Expected<Foo *> efoop = some_cpp_function();
659085328eeSLawrence D'Anna // Foo *foop = unwrapOrSetPythonException(efoop);
660085328eeSLawrence D'Anna // if (!foop)
661085328eeSLawrence D'Anna // return NULL;
662085328eeSLawrence D'Anna // do_something(*foop);
663085328eeSLawrence D'Anna //
664085328eeSLawrence D'Anna // If the Error returned was itself created because a python exception was
665085328eeSLawrence D'Anna // raised when C++ code called into python, then the original exception
666085328eeSLawrence D'Anna // will be restored. Otherwise a simple string exception will be raised.
667085328eeSLawrence D'Anna template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
668085328eeSLawrence D'Anna if (expected)
669085328eeSLawrence D'Anna return expected.get();
670085328eeSLawrence D'Anna llvm::handleAllErrors(
671085328eeSLawrence D'Anna expected.takeError(), [](PythonException &E) { E.Restore(); },
672085328eeSLawrence D'Anna [](const llvm::ErrorInfoBase &E) {
673085328eeSLawrence D'Anna PyErr_SetString(PyExc_Exception, E.message().c_str());
674085328eeSLawrence D'Anna });
675085328eeSLawrence D'Anna return T();
676085328eeSLawrence D'Anna }
677085328eeSLawrence D'Anna
678722b6189SLawrence D'Anna // This is only here to help incrementally migrate old, exception-unsafe
679722b6189SLawrence D'Anna // code.
680722b6189SLawrence D'Anna template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
681722b6189SLawrence D'Anna if (expected)
682722b6189SLawrence D'Anna return std::move(expected.get());
683722b6189SLawrence D'Anna llvm::consumeError(expected.takeError());
684722b6189SLawrence D'Anna return T();
685722b6189SLawrence D'Anna }
686722b6189SLawrence D'Anna
68704edd189SLawrence D'Anna llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
68804edd189SLawrence D'Anna const PythonDictionary &globals,
68904edd189SLawrence D'Anna const PythonDictionary &locals);
69004edd189SLawrence D'Anna
69104edd189SLawrence D'Anna llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
69204edd189SLawrence D'Anna const PythonDictionary &globals,
69304edd189SLawrence D'Anna const PythonDictionary &locals);
69404edd189SLawrence D'Anna
69504edd189SLawrence D'Anna // Sometimes the best way to interact with a python interpreter is
69604edd189SLawrence D'Anna // to run some python code. You construct a PythonScript with
69704edd189SLawrence D'Anna // script string. The script assigns some function to `_function_`
69804edd189SLawrence D'Anna // and you get a C++ callable object that calls the python function.
69904edd189SLawrence D'Anna //
70004edd189SLawrence D'Anna // Example:
70104edd189SLawrence D'Anna //
70204edd189SLawrence D'Anna // const char script[] = R"(
70304edd189SLawrence D'Anna // def main(x, y):
70404edd189SLawrence D'Anna // ....
70504edd189SLawrence D'Anna // )";
70604edd189SLawrence D'Anna //
70704edd189SLawrence D'Anna // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
70804edd189SLawrence D'Anna // // no need to synchronize access to this global, we already have the GIL
70904edd189SLawrence D'Anna // static PythonScript foo(script)
71004edd189SLawrence D'Anna // return foo(x, y);
71104edd189SLawrence D'Anna // }
71204edd189SLawrence D'Anna class PythonScript {
71304edd189SLawrence D'Anna const char *script;
71404edd189SLawrence D'Anna PythonCallable function;
71504edd189SLawrence D'Anna
71604edd189SLawrence D'Anna llvm::Error Init();
71704edd189SLawrence D'Anna
71804edd189SLawrence D'Anna public:
71904edd189SLawrence D'Anna PythonScript(const char *script) : script(script), function() {}
72004edd189SLawrence D'Anna
72104edd189SLawrence D'Anna template <typename... Args>
72204edd189SLawrence D'Anna llvm::Expected<PythonObject> operator()(Args &&... args) {
72304edd189SLawrence D'Anna if (llvm::Error error = Init())
72404edd189SLawrence D'Anna return std::move(error);
72504edd189SLawrence D'Anna return function.Call(std::forward<Args>(args)...);
72604edd189SLawrence D'Anna }
72704edd189SLawrence D'Anna };
72804edd189SLawrence D'Anna
729c154f397SPavel Labath class StructuredPythonObject : public StructuredData::Generic {
730c154f397SPavel Labath public:
731c154f397SPavel Labath StructuredPythonObject() : StructuredData::Generic() {}
732c154f397SPavel Labath
733c154f397SPavel Labath // Take ownership of the object we received.
734c154f397SPavel Labath StructuredPythonObject(PythonObject obj)
735c154f397SPavel Labath : StructuredData::Generic(obj.release()) {}
736c154f397SPavel Labath
737c154f397SPavel Labath ~StructuredPythonObject() override {
738c154f397SPavel Labath // Hand ownership back to a (temporary) PythonObject instance and let it
739c154f397SPavel Labath // take care of releasing it.
740c154f397SPavel Labath PythonObject(PyRefType::Owned, static_cast<PyObject *>(GetValue()));
741c154f397SPavel Labath }
742c154f397SPavel Labath
743c154f397SPavel Labath bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
744c154f397SPavel Labath
745c154f397SPavel Labath void Serialize(llvm::json::OStream &s) const override;
746c154f397SPavel Labath
747c154f397SPavel Labath private:
748c154f397SPavel Labath StructuredPythonObject(const StructuredPythonObject &) = delete;
749c154f397SPavel Labath const StructuredPythonObject &
750c154f397SPavel Labath operator=(const StructuredPythonObject &) = delete;
751c154f397SPavel Labath };
752c154f397SPavel Labath
75304edd189SLawrence D'Anna } // namespace python
7542c1f46dcSZachary Turner } // namespace lldb_private
7552c1f46dcSZachary Turner
756a281b42bSZachary Turner #endif
757d68983e3SPavel Labath
758d68983e3SPavel Labath #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
759