1e81d9d49SDimitry Andric //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===//
2e81d9d49SDimitry Andric //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e81d9d49SDimitry Andric //
7e81d9d49SDimitry Andric //===----------------------------------------------------------------------===//
8e81d9d49SDimitry Andric
9ead24645SDimitry Andric //
10ead24645SDimitry Andric // !! FIXME FIXME FIXME !!
11ead24645SDimitry Andric //
12ead24645SDimitry Andric // Python APIs nearly all can return an exception. They do this
13ead24645SDimitry Andric // by returning NULL, or -1, or some such value and setting
14ead24645SDimitry Andric // the exception state with PyErr_Set*(). Exceptions must be
15ead24645SDimitry Andric // handled before further python API functions are called. Failure
16ead24645SDimitry Andric // to do so will result in asserts on debug builds of python.
17ead24645SDimitry Andric // It will also sometimes, but not usually result in crashes of
18ead24645SDimitry Andric // release builds.
19ead24645SDimitry Andric //
20ead24645SDimitry Andric // Nearly all the code in this header does not handle python exceptions
21ead24645SDimitry Andric // correctly. It should all be converted to return Expected<> or
22ead24645SDimitry Andric // Error types to capture the exception.
23ead24645SDimitry Andric //
24ead24645SDimitry Andric // Everything in this file except functions that return Error or
25ead24645SDimitry Andric // Expected<> is considered deprecated and should not be
26ead24645SDimitry Andric // used in new code. If you need to use it, fix it first.
27ead24645SDimitry Andric //
28ead24645SDimitry Andric //
29ead24645SDimitry Andric // TODOs for this file
30ead24645SDimitry Andric //
31ead24645SDimitry Andric // * Make all methods safe for exceptions.
32ead24645SDimitry Andric //
33ead24645SDimitry Andric // * Eliminate method signatures that must translate exceptions into
34ead24645SDimitry Andric // empty objects or NULLs. Almost everything here should return
35ead24645SDimitry Andric // Expected<>. It should be acceptable for certain operations that
36ead24645SDimitry Andric // can never fail to assert instead, such as the creation of
37ead24645SDimitry Andric // PythonString from a string literal.
38ead24645SDimitry Andric //
39cfca06d7SDimitry Andric // * Eliminate Reset(), and make all non-default constructors private.
40ead24645SDimitry Andric // Python objects should be created with Retain<> or Take<>, and they
41ead24645SDimitry Andric // should be assigned with operator=
42ead24645SDimitry Andric //
43ead24645SDimitry Andric // * Eliminate default constructors, make python objects always
44ead24645SDimitry Andric // nonnull, and use optionals where necessary.
45ead24645SDimitry Andric //
46ead24645SDimitry Andric
47ead24645SDimitry Andric
48e81d9d49SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
49e81d9d49SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
50e81d9d49SDimitry Andric
51706b4fc4SDimitry Andric #include "lldb/Host/Config.h"
52706b4fc4SDimitry Andric
53706b4fc4SDimitry Andric #if LLDB_ENABLE_PYTHON
54e81d9d49SDimitry Andric
5514f1b3e8SDimitry Andric // LLDB Python header must be included first
5614f1b3e8SDimitry Andric #include "lldb-python.h"
5714f1b3e8SDimitry Andric
58e81d9d49SDimitry Andric #include "lldb/Host/File.h"
591b306c26SDimitry Andric #include "lldb/Utility/StructuredData.h"
60e81d9d49SDimitry Andric
617fed546dSDimitry Andric #include "llvm/ADT/ArrayRef.h"
627fed546dSDimitry Andric
63e81d9d49SDimitry Andric namespace lldb_private {
64ead24645SDimitry Andric namespace python {
65e81d9d49SDimitry Andric
66ead24645SDimitry Andric class PythonObject;
677fed546dSDimitry Andric class PythonBytes;
68e81d9d49SDimitry Andric class PythonString;
69e81d9d49SDimitry Andric class PythonList;
70e81d9d49SDimitry Andric class PythonDictionary;
71e81d9d49SDimitry Andric class PythonInteger;
72ead24645SDimitry Andric class PythonException;
73e81d9d49SDimitry Andric
74c0981da4SDimitry Andric class GIL {
75c0981da4SDimitry Andric public:
GIL()76c0981da4SDimitry Andric GIL() {
77c0981da4SDimitry Andric m_state = PyGILState_Ensure();
78c0981da4SDimitry Andric assert(!PyErr_Occurred());
79c0981da4SDimitry Andric }
~GIL()80c0981da4SDimitry Andric ~GIL() { PyGILState_Release(m_state); }
81c0981da4SDimitry Andric
82c0981da4SDimitry Andric protected:
83c0981da4SDimitry Andric PyGILState_STATE m_state;
84c0981da4SDimitry Andric };
85c0981da4SDimitry Andric
8614f1b3e8SDimitry Andric enum class PyObjectType {
87e81d9d49SDimitry Andric Unknown,
88e81d9d49SDimitry Andric None,
895f29bb8aSDimitry Andric Boolean,
90e81d9d49SDimitry Andric Integer,
91e81d9d49SDimitry Andric Dictionary,
92e81d9d49SDimitry Andric List,
93e81d9d49SDimitry Andric String,
947fed546dSDimitry Andric Bytes,
95f3fbd1c0SDimitry Andric ByteArray,
96e81d9d49SDimitry Andric Module,
97e81d9d49SDimitry Andric Callable,
98e81d9d49SDimitry Andric Tuple,
99e81d9d49SDimitry Andric File
100e81d9d49SDimitry Andric };
101e81d9d49SDimitry Andric
10214f1b3e8SDimitry Andric enum class PyRefType {
103e81d9d49SDimitry Andric Borrowed, // We are not given ownership of the incoming PyObject.
104e81d9d49SDimitry Andric // We cannot safely hold it without calling Py_INCREF.
105e81d9d49SDimitry Andric Owned // We have ownership of the incoming PyObject. We should
106e81d9d49SDimitry Andric // not call Py_INCREF.
107e81d9d49SDimitry Andric };
108e81d9d49SDimitry Andric
109ead24645SDimitry Andric
110ead24645SDimitry Andric // Take a reference that you already own, and turn it into
111ead24645SDimitry Andric // a PythonObject.
112ead24645SDimitry Andric //
113ead24645SDimitry Andric // Most python API methods will return a +1 reference
114ead24645SDimitry Andric // if they succeed or NULL if and only if
115ead24645SDimitry Andric // they set an exception. Use this to collect such return
116ead24645SDimitry Andric // values, after checking for NULL.
117ead24645SDimitry Andric //
118ead24645SDimitry Andric // If T is not just PythonObject, then obj must be already be
119ead24645SDimitry Andric // checked to be of the correct type.
Take(PyObject * obj)120ead24645SDimitry Andric template <typename T> T Take(PyObject *obj) {
121ead24645SDimitry Andric assert(obj);
122ead24645SDimitry Andric assert(!PyErr_Occurred());
123ead24645SDimitry Andric T thing(PyRefType::Owned, obj);
124ead24645SDimitry Andric assert(thing.IsValid());
125706b4fc4SDimitry Andric return thing;
126ead24645SDimitry Andric }
127ead24645SDimitry Andric
128ead24645SDimitry Andric // Retain a reference you have borrowed, and turn it into
129ead24645SDimitry Andric // a PythonObject.
130ead24645SDimitry Andric //
131ead24645SDimitry Andric // A minority of python APIs return a borrowed reference
132ead24645SDimitry Andric // instead of a +1. They will also return NULL if and only
133ead24645SDimitry Andric // if they set an exception. Use this to collect such return
134ead24645SDimitry Andric // values, after checking for NULL.
135ead24645SDimitry Andric //
136ead24645SDimitry Andric // If T is not just PythonObject, then obj must be already be
137ead24645SDimitry Andric // checked to be of the correct type.
Retain(PyObject * obj)138ead24645SDimitry Andric template <typename T> T Retain(PyObject *obj) {
139ead24645SDimitry Andric assert(obj);
140ead24645SDimitry Andric assert(!PyErr_Occurred());
141ead24645SDimitry Andric T thing(PyRefType::Borrowed, obj);
142ead24645SDimitry Andric assert(thing.IsValid());
143706b4fc4SDimitry Andric return thing;
144ead24645SDimitry Andric }
145ead24645SDimitry Andric
146ead24645SDimitry Andric // This class can be used like a utility function to convert from
147ead24645SDimitry Andric // a llvm-friendly Twine into a null-terminated const char *,
148ead24645SDimitry Andric // which is the form python C APIs want their strings in.
149ead24645SDimitry Andric //
150ead24645SDimitry Andric // Example:
151ead24645SDimitry Andric // const llvm::Twine &some_twine;
152ead24645SDimitry Andric // PyFoo_Bar(x, y, z, NullTerminated(some_twine));
153ead24645SDimitry Andric //
154ead24645SDimitry Andric // Why a class instead of a function? If the twine isn't already null
155ead24645SDimitry Andric // terminated, it will need a temporary buffer to copy the string
156ead24645SDimitry Andric // into. We need that buffer to stick around for the lifetime of the
157ead24645SDimitry Andric // statement.
158ead24645SDimitry Andric class NullTerminated {
159ead24645SDimitry Andric const char *str;
160ead24645SDimitry Andric llvm::SmallString<32> storage;
161ead24645SDimitry Andric
162ead24645SDimitry Andric public:
NullTerminated(const llvm::Twine & twine)163ead24645SDimitry Andric NullTerminated(const llvm::Twine &twine) {
164ead24645SDimitry Andric llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
165ead24645SDimitry Andric str = ref.begin();
166ead24645SDimitry Andric }
167ead24645SDimitry Andric operator const char *() { return str; }
168ead24645SDimitry Andric };
169ead24645SDimitry Andric
nullDeref()170ead24645SDimitry Andric inline llvm::Error nullDeref() {
171ead24645SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),
172ead24645SDimitry Andric "A NULL PyObject* was dereferenced");
173ead24645SDimitry Andric }
174ead24645SDimitry Andric
175ead24645SDimitry Andric inline llvm::Error exception(const char *s = nullptr) {
176ead24645SDimitry Andric return llvm::make_error<PythonException>(s);
177ead24645SDimitry Andric }
178ead24645SDimitry Andric
keyError()179ead24645SDimitry Andric inline llvm::Error keyError() {
180ead24645SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),
181ead24645SDimitry Andric "key not in dict");
182ead24645SDimitry Andric }
183ead24645SDimitry Andric
py2_const_cast(const char * s)184706b4fc4SDimitry Andric inline const char *py2_const_cast(const char *s) { return s; }
185706b4fc4SDimitry Andric
18614f1b3e8SDimitry Andric enum class PyInitialValue { Invalid, Empty };
187e81d9d49SDimitry Andric
188e3b55780SDimitry Andric // DOC: https://docs.python.org/3/c-api/arg.html#building-values
189ead24645SDimitry Andric template <typename T, typename Enable = void> struct PythonFormat;
190ead24645SDimitry Andric
191e3b55780SDimitry Andric template <typename T, char F> struct PassthroughFormat {
192e3b55780SDimitry Andric static constexpr char format = F;
getPassthroughFormat193e3b55780SDimitry Andric static constexpr T get(T t) { return t; }
194ead24645SDimitry Andric };
195ead24645SDimitry Andric
196e3b55780SDimitry Andric template <> struct PythonFormat<char *> : PassthroughFormat<char *, 's'> {};
197ac9a064cSDimitry Andric template <> struct PythonFormat<const char *> :
198ac9a064cSDimitry Andric PassthroughFormat<const char *, 's'> {};
199e3b55780SDimitry Andric template <> struct PythonFormat<char> : PassthroughFormat<char, 'b'> {};
200e3b55780SDimitry Andric template <>
201e3b55780SDimitry Andric struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {};
202e3b55780SDimitry Andric template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {};
203e3b55780SDimitry Andric template <>
204e3b55780SDimitry Andric struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {};
205e3b55780SDimitry Andric template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {};
2067fa27ce4SDimitry Andric template <> struct PythonFormat<bool> : PassthroughFormat<bool, 'p'> {};
207e3b55780SDimitry Andric template <>
208e3b55780SDimitry Andric struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {};
209e3b55780SDimitry Andric template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {};
210e3b55780SDimitry Andric template <>
211e3b55780SDimitry Andric struct PythonFormat<unsigned long> : PassthroughFormat<unsigned long, 'k'> {};
212e3b55780SDimitry Andric template <>
213e3b55780SDimitry Andric struct PythonFormat<long long> : PassthroughFormat<long long, 'L'> {};
214e3b55780SDimitry Andric template <>
215e3b55780SDimitry Andric struct PythonFormat<unsigned long long>
216e3b55780SDimitry Andric : PassthroughFormat<unsigned long long, 'K'> {};
217e3b55780SDimitry Andric template <>
218e3b55780SDimitry Andric struct PythonFormat<PyObject *> : PassthroughFormat<PyObject *, 'O'> {};
219ead24645SDimitry Andric
220ead24645SDimitry Andric template <typename T>
221ead24645SDimitry Andric struct PythonFormat<
222ead24645SDimitry Andric T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
223ead24645SDimitry Andric static constexpr char format = 'O';
224ead24645SDimitry Andric static auto get(const T &value) { return value.get(); }
225ead24645SDimitry Andric };
226ead24645SDimitry Andric
22714f1b3e8SDimitry Andric class PythonObject {
228e81d9d49SDimitry Andric public:
229344a3780SDimitry Andric PythonObject() = default;
230e81d9d49SDimitry Andric
231ead24645SDimitry Andric PythonObject(PyRefType type, PyObject *py_obj) {
232e81d9d49SDimitry Andric m_py_obj = py_obj;
233e81d9d49SDimitry Andric // If this is a borrowed reference, we need to convert it to
234e81d9d49SDimitry Andric // an owned reference by incrementing it. If it is an owned
235e81d9d49SDimitry Andric // reference (for example the caller allocated it with PyDict_New()
236e81d9d49SDimitry Andric // then we must *not* increment it.
237ead24645SDimitry Andric if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
238e81d9d49SDimitry Andric Py_XINCREF(m_py_obj);
239e81d9d49SDimitry Andric }
240e81d9d49SDimitry Andric
241ead24645SDimitry Andric PythonObject(const PythonObject &rhs)
242ead24645SDimitry Andric : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
243ead24645SDimitry Andric
244ead24645SDimitry Andric PythonObject(PythonObject &&rhs) {
245ead24645SDimitry Andric m_py_obj = rhs.m_py_obj;
246ead24645SDimitry Andric rhs.m_py_obj = nullptr;
247ead24645SDimitry Andric }
248ead24645SDimitry Andric
249ead24645SDimitry Andric ~PythonObject() { Reset(); }
250ead24645SDimitry Andric
2516f8fc217SDimitry Andric void Reset();
252ead24645SDimitry Andric
25314f1b3e8SDimitry Andric void Dump() const {
254e81d9d49SDimitry Andric if (m_py_obj)
255e81d9d49SDimitry Andric _PyObject_Dump(m_py_obj);
256e81d9d49SDimitry Andric else
257e81d9d49SDimitry Andric puts("NULL");
258e81d9d49SDimitry Andric }
259e81d9d49SDimitry Andric
26014f1b3e8SDimitry Andric void Dump(Stream &strm) const;
261e81d9d49SDimitry Andric
26214f1b3e8SDimitry Andric PyObject *get() const { return m_py_obj; }
263e81d9d49SDimitry Andric
26414f1b3e8SDimitry Andric PyObject *release() {
265e81d9d49SDimitry Andric PyObject *result = m_py_obj;
266e81d9d49SDimitry Andric m_py_obj = nullptr;
267e81d9d49SDimitry Andric return result;
268e81d9d49SDimitry Andric }
269e81d9d49SDimitry Andric
270ead24645SDimitry Andric PythonObject &operator=(PythonObject other) {
271ead24645SDimitry Andric Reset();
272ead24645SDimitry Andric m_py_obj = std::exchange(other.m_py_obj, nullptr);
273e81d9d49SDimitry Andric return *this;
274e81d9d49SDimitry Andric }
275e81d9d49SDimitry Andric
27614f1b3e8SDimitry Andric PyObjectType GetObjectType() const;
277e81d9d49SDimitry Andric
27814f1b3e8SDimitry Andric PythonString Repr() const;
279e81d9d49SDimitry Andric
28014f1b3e8SDimitry Andric PythonString Str() const;
281e81d9d49SDimitry Andric
28214f1b3e8SDimitry Andric static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
28314f1b3e8SDimitry Andric const PythonDictionary &dict);
284e81d9d49SDimitry Andric
285e81d9d49SDimitry Andric template <typename T>
28614f1b3e8SDimitry Andric static T ResolveNameWithDictionary(llvm::StringRef name,
28714f1b3e8SDimitry Andric const PythonDictionary &dict) {
288e81d9d49SDimitry Andric return ResolveNameWithDictionary(name, dict).AsType<T>();
289e81d9d49SDimitry Andric }
290e81d9d49SDimitry Andric
29114f1b3e8SDimitry Andric PythonObject ResolveName(llvm::StringRef name) const;
292e81d9d49SDimitry Andric
29314f1b3e8SDimitry Andric template <typename T> T ResolveName(llvm::StringRef name) const {
294e81d9d49SDimitry Andric return ResolveName(name).AsType<T>();
295e81d9d49SDimitry Andric }
296e81d9d49SDimitry Andric
29714f1b3e8SDimitry Andric bool HasAttribute(llvm::StringRef attribute) const;
298e81d9d49SDimitry Andric
29914f1b3e8SDimitry Andric PythonObject GetAttributeValue(llvm::StringRef attribute) const;
300e81d9d49SDimitry Andric
301ead24645SDimitry Andric bool IsNone() const { return m_py_obj == Py_None; }
302e81d9d49SDimitry Andric
303ead24645SDimitry Andric bool IsValid() const { return m_py_obj != nullptr; }
304e81d9d49SDimitry Andric
305ead24645SDimitry Andric bool IsAllocated() const { return IsValid() && !IsNone(); }
306ead24645SDimitry Andric
307ead24645SDimitry Andric explicit operator bool() const { return IsValid() && !IsNone(); }
308e81d9d49SDimitry Andric
30914f1b3e8SDimitry Andric template <typename T> T AsType() const {
310e81d9d49SDimitry Andric if (!T::Check(m_py_obj))
311e81d9d49SDimitry Andric return T();
312e81d9d49SDimitry Andric return T(PyRefType::Borrowed, m_py_obj);
313e81d9d49SDimitry Andric }
314e81d9d49SDimitry Andric
31514f1b3e8SDimitry Andric StructuredData::ObjectSP CreateStructuredObject() const;
316e81d9d49SDimitry Andric
317ead24645SDimitry Andric template <typename... T>
318ead24645SDimitry Andric llvm::Expected<PythonObject> CallMethod(const char *name,
319ead24645SDimitry Andric const T &... t) const {
320ead24645SDimitry Andric const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
321ead24645SDimitry Andric PyObject *obj =
322ead24645SDimitry Andric PyObject_CallMethod(m_py_obj, py2_const_cast(name),
323ead24645SDimitry Andric py2_const_cast(format), PythonFormat<T>::get(t)...);
324ead24645SDimitry Andric if (!obj)
325ead24645SDimitry Andric return exception();
326ead24645SDimitry Andric return python::Take<PythonObject>(obj);
327ead24645SDimitry Andric }
328ead24645SDimitry Andric
329ead24645SDimitry Andric template <typename... T>
330ead24645SDimitry Andric llvm::Expected<PythonObject> Call(const T &... t) const {
331ead24645SDimitry Andric const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
332ead24645SDimitry Andric PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
333ead24645SDimitry Andric PythonFormat<T>::get(t)...);
334ead24645SDimitry Andric if (!obj)
335ead24645SDimitry Andric return exception();
336ead24645SDimitry Andric return python::Take<PythonObject>(obj);
337ead24645SDimitry Andric }
338ead24645SDimitry Andric
339ead24645SDimitry Andric llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
340ead24645SDimitry Andric if (!m_py_obj)
341ead24645SDimitry Andric return nullDeref();
342ead24645SDimitry Andric PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
343ead24645SDimitry Andric if (!obj)
344ead24645SDimitry Andric return exception();
345ead24645SDimitry Andric return python::Take<PythonObject>(obj);
346ead24645SDimitry Andric }
347ead24645SDimitry Andric
3487fa27ce4SDimitry Andric llvm::Expected<PythonObject> GetType() const {
3497fa27ce4SDimitry Andric if (!m_py_obj)
3507fa27ce4SDimitry Andric return nullDeref();
3517fa27ce4SDimitry Andric PyObject *obj = PyObject_Type(m_py_obj);
3527fa27ce4SDimitry Andric if (!obj)
3537fa27ce4SDimitry Andric return exception();
3547fa27ce4SDimitry Andric return python::Take<PythonObject>(obj);
3557fa27ce4SDimitry Andric }
3567fa27ce4SDimitry Andric
357ead24645SDimitry Andric llvm::Expected<bool> IsTrue() {
358ead24645SDimitry Andric if (!m_py_obj)
359ead24645SDimitry Andric return nullDeref();
360ead24645SDimitry Andric int r = PyObject_IsTrue(m_py_obj);
361ead24645SDimitry Andric if (r < 0)
362ead24645SDimitry Andric return exception();
363ead24645SDimitry Andric return !!r;
364ead24645SDimitry Andric }
365ead24645SDimitry Andric
366cfca06d7SDimitry Andric llvm::Expected<long long> AsLongLong() const;
367cfca06d7SDimitry Andric
3687fa27ce4SDimitry Andric llvm::Expected<unsigned long long> AsUnsignedLongLong() const;
369cfca06d7SDimitry Andric
370cfca06d7SDimitry Andric // wraps on overflow, instead of raising an error.
371cfca06d7SDimitry Andric llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
372ead24645SDimitry Andric
373ead24645SDimitry Andric llvm::Expected<bool> IsInstance(const PythonObject &cls) {
374ead24645SDimitry Andric if (!m_py_obj || !cls.IsValid())
375ead24645SDimitry Andric return nullDeref();
376ead24645SDimitry Andric int r = PyObject_IsInstance(m_py_obj, cls.get());
377ead24645SDimitry Andric if (r < 0)
378ead24645SDimitry Andric return exception();
379ead24645SDimitry Andric return !!r;
380ead24645SDimitry Andric }
381ead24645SDimitry Andric
382ead24645SDimitry Andric protected:
383344a3780SDimitry Andric PyObject *m_py_obj = nullptr;
384e81d9d49SDimitry Andric };
385e81d9d49SDimitry Andric
386ead24645SDimitry Andric
387ead24645SDimitry Andric // This is why C++ needs monads.
388ead24645SDimitry Andric template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
389ead24645SDimitry Andric if (!obj)
390ead24645SDimitry Andric return obj.takeError();
391ead24645SDimitry Andric if (!T::Check(obj.get().get()))
392ead24645SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),
393ead24645SDimitry Andric "type error");
394ead24645SDimitry Andric return T(PyRefType::Borrowed, std::move(obj.get().get()));
395ead24645SDimitry Andric }
396ead24645SDimitry Andric
397ead24645SDimitry Andric template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
398ead24645SDimitry Andric
399ead24645SDimitry Andric template <>
400ead24645SDimitry Andric llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
401ead24645SDimitry Andric
402ead24645SDimitry Andric template <>
403cfca06d7SDimitry Andric llvm::Expected<unsigned long long>
404cfca06d7SDimitry Andric As<unsigned long long>(llvm::Expected<PythonObject> &&obj);
405cfca06d7SDimitry Andric
406cfca06d7SDimitry Andric template <>
407ead24645SDimitry Andric llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
408ead24645SDimitry Andric
409ead24645SDimitry Andric
410ead24645SDimitry Andric template <class T> class TypedPythonObject : public PythonObject {
4117fed546dSDimitry Andric public:
412ead24645SDimitry Andric TypedPythonObject(PyRefType type, PyObject *py_obj) {
413ead24645SDimitry Andric if (!py_obj)
414ead24645SDimitry Andric return;
415ead24645SDimitry Andric if (T::Check(py_obj))
416ead24645SDimitry Andric PythonObject::operator=(PythonObject(type, py_obj));
417ead24645SDimitry Andric else if (type == PyRefType::Owned)
418ead24645SDimitry Andric Py_DECREF(py_obj);
419ead24645SDimitry Andric }
420ead24645SDimitry Andric
421344a3780SDimitry Andric TypedPythonObject() = default;
422ead24645SDimitry Andric };
423ead24645SDimitry Andric
424ead24645SDimitry Andric class PythonBytes : public TypedPythonObject<PythonBytes> {
425ead24645SDimitry Andric public:
426ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
4277fed546dSDimitry Andric explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
4287fed546dSDimitry Andric PythonBytes(const uint8_t *bytes, size_t length);
4297fed546dSDimitry Andric
43014f1b3e8SDimitry Andric static bool Check(PyObject *py_obj);
4317fed546dSDimitry Andric
43214f1b3e8SDimitry Andric llvm::ArrayRef<uint8_t> GetBytes() const;
4337fed546dSDimitry Andric
43414f1b3e8SDimitry Andric size_t GetSize() const;
4357fed546dSDimitry Andric
43614f1b3e8SDimitry Andric void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4377fed546dSDimitry Andric
43814f1b3e8SDimitry Andric StructuredData::StringSP CreateStructuredString() const;
4397fed546dSDimitry Andric };
4407fed546dSDimitry Andric
441ead24645SDimitry Andric class PythonByteArray : public TypedPythonObject<PythonByteArray> {
442f3fbd1c0SDimitry Andric public:
443ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
444f3fbd1c0SDimitry Andric explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
445f3fbd1c0SDimitry Andric PythonByteArray(const uint8_t *bytes, size_t length);
446f3fbd1c0SDimitry Andric PythonByteArray(const PythonBytes &object);
447f3fbd1c0SDimitry Andric
44814f1b3e8SDimitry Andric static bool Check(PyObject *py_obj);
449f3fbd1c0SDimitry Andric
45014f1b3e8SDimitry Andric llvm::ArrayRef<uint8_t> GetBytes() const;
451f3fbd1c0SDimitry Andric
45214f1b3e8SDimitry Andric size_t GetSize() const;
453f3fbd1c0SDimitry Andric
45414f1b3e8SDimitry Andric void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
455f3fbd1c0SDimitry Andric
45614f1b3e8SDimitry Andric StructuredData::StringSP CreateStructuredString() const;
457f3fbd1c0SDimitry Andric };
458f3fbd1c0SDimitry Andric
459ead24645SDimitry Andric class PythonString : public TypedPythonObject<PythonString> {
460e81d9d49SDimitry Andric public:
461ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
462ead24645SDimitry Andric static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
463e81d9d49SDimitry Andric
464ead24645SDimitry Andric PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
465ead24645SDimitry Andric
466ead24645SDimitry Andric explicit PythonString(llvm::StringRef string); // safe, null on error
467e81d9d49SDimitry Andric
468e81d9d49SDimitry Andric static bool Check(PyObject *py_obj);
469e81d9d49SDimitry Andric
470ead24645SDimitry Andric llvm::StringRef GetString() const; // safe, empty string on error
471e81d9d49SDimitry Andric
472ead24645SDimitry Andric llvm::Expected<llvm::StringRef> AsUTF8() const;
473e81d9d49SDimitry Andric
47414f1b3e8SDimitry Andric size_t GetSize() const;
475e81d9d49SDimitry Andric
476ead24645SDimitry Andric void SetString(llvm::StringRef string); // safe, null on error
477e81d9d49SDimitry Andric
478e81d9d49SDimitry Andric StructuredData::StringSP CreateStructuredString() const;
479e81d9d49SDimitry Andric };
480e81d9d49SDimitry Andric
481ead24645SDimitry Andric class PythonInteger : public TypedPythonObject<PythonInteger> {
482e81d9d49SDimitry Andric public:
483ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
484e81d9d49SDimitry Andric
485ead24645SDimitry Andric PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
486ead24645SDimitry Andric
487ead24645SDimitry Andric explicit PythonInteger(int64_t value);
488e81d9d49SDimitry Andric
489e81d9d49SDimitry Andric static bool Check(PyObject *py_obj);
490e81d9d49SDimitry Andric
49114f1b3e8SDimitry Andric void SetInteger(int64_t value);
492e81d9d49SDimitry Andric
493e81d9d49SDimitry Andric StructuredData::IntegerSP CreateStructuredInteger() const;
4947fa27ce4SDimitry Andric
4957fa27ce4SDimitry Andric StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const;
4967fa27ce4SDimitry Andric
4977fa27ce4SDimitry Andric StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const;
498e81d9d49SDimitry Andric };
499e81d9d49SDimitry Andric
500ead24645SDimitry Andric class PythonBoolean : public TypedPythonObject<PythonBoolean> {
5015f29bb8aSDimitry Andric public:
502ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
5035f29bb8aSDimitry Andric
504ead24645SDimitry Andric explicit PythonBoolean(bool value);
5055f29bb8aSDimitry Andric
5065f29bb8aSDimitry Andric static bool Check(PyObject *py_obj);
5075f29bb8aSDimitry Andric
5085f29bb8aSDimitry Andric bool GetValue() const;
5095f29bb8aSDimitry Andric
5105f29bb8aSDimitry Andric void SetValue(bool value);
5115f29bb8aSDimitry Andric
5125f29bb8aSDimitry Andric StructuredData::BooleanSP CreateStructuredBoolean() const;
5135f29bb8aSDimitry Andric };
5145f29bb8aSDimitry Andric
515ead24645SDimitry Andric class PythonList : public TypedPythonObject<PythonList> {
516e81d9d49SDimitry Andric public:
517ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
518ead24645SDimitry Andric
519ead24645SDimitry Andric PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
520ead24645SDimitry Andric
521e81d9d49SDimitry Andric explicit PythonList(PyInitialValue value);
522e81d9d49SDimitry Andric explicit PythonList(int list_size);
523e81d9d49SDimitry Andric
524e81d9d49SDimitry Andric static bool Check(PyObject *py_obj);
525e81d9d49SDimitry Andric
526e81d9d49SDimitry Andric uint32_t GetSize() const;
527e81d9d49SDimitry Andric
528e81d9d49SDimitry Andric PythonObject GetItemAtIndex(uint32_t index) const;
529e81d9d49SDimitry Andric
530e81d9d49SDimitry Andric void SetItemAtIndex(uint32_t index, const PythonObject &object);
531e81d9d49SDimitry Andric
532e81d9d49SDimitry Andric void AppendItem(const PythonObject &object);
533e81d9d49SDimitry Andric
534e81d9d49SDimitry Andric StructuredData::ArraySP CreateStructuredArray() const;
535e81d9d49SDimitry Andric };
536e81d9d49SDimitry Andric
537ead24645SDimitry Andric class PythonTuple : public TypedPythonObject<PythonTuple> {
538e81d9d49SDimitry Andric public:
539ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
540ead24645SDimitry Andric
541e81d9d49SDimitry Andric explicit PythonTuple(PyInitialValue value);
542e81d9d49SDimitry Andric explicit PythonTuple(int tuple_size);
543e81d9d49SDimitry Andric PythonTuple(std::initializer_list<PythonObject> objects);
544e81d9d49SDimitry Andric PythonTuple(std::initializer_list<PyObject *> objects);
545e81d9d49SDimitry Andric
546e81d9d49SDimitry Andric static bool Check(PyObject *py_obj);
547e81d9d49SDimitry Andric
548e81d9d49SDimitry Andric uint32_t GetSize() const;
549e81d9d49SDimitry Andric
550e81d9d49SDimitry Andric PythonObject GetItemAtIndex(uint32_t index) const;
551e81d9d49SDimitry Andric
552e81d9d49SDimitry Andric void SetItemAtIndex(uint32_t index, const PythonObject &object);
553e81d9d49SDimitry Andric
554e81d9d49SDimitry Andric StructuredData::ArraySP CreateStructuredArray() const;
555e81d9d49SDimitry Andric };
556e81d9d49SDimitry Andric
557ead24645SDimitry Andric class PythonDictionary : public TypedPythonObject<PythonDictionary> {
558e81d9d49SDimitry Andric public:
559ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
560e81d9d49SDimitry Andric
561ead24645SDimitry Andric PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
562ead24645SDimitry Andric
563ead24645SDimitry Andric explicit PythonDictionary(PyInitialValue value);
564e81d9d49SDimitry Andric
565e81d9d49SDimitry Andric static bool Check(PyObject *py_obj);
566e81d9d49SDimitry Andric
567b1c73532SDimitry Andric bool HasKey(const llvm::Twine &key) const;
568b1c73532SDimitry Andric
569e81d9d49SDimitry Andric uint32_t GetSize() const;
570e81d9d49SDimitry Andric
571e81d9d49SDimitry Andric PythonList GetKeys() const;
572e81d9d49SDimitry Andric
573ead24645SDimitry Andric PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
574ead24645SDimitry Andric void SetItemForKey(const PythonObject &key,
575ead24645SDimitry Andric const PythonObject &value); // DEPRECATED
576ead24645SDimitry Andric
577ead24645SDimitry Andric llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
578ead24645SDimitry Andric llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
579ead24645SDimitry Andric llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
580ead24645SDimitry Andric llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
581e81d9d49SDimitry Andric
582e81d9d49SDimitry Andric StructuredData::DictionarySP CreateStructuredDictionary() const;
583e81d9d49SDimitry Andric };
584e81d9d49SDimitry Andric
585ead24645SDimitry Andric class PythonModule : public TypedPythonObject<PythonModule> {
586e81d9d49SDimitry Andric public:
587ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
588e81d9d49SDimitry Andric
589e81d9d49SDimitry Andric static bool Check(PyObject *py_obj);
590e81d9d49SDimitry Andric
59114f1b3e8SDimitry Andric static PythonModule BuiltinsModule();
592e81d9d49SDimitry Andric
59314f1b3e8SDimitry Andric static PythonModule MainModule();
594e81d9d49SDimitry Andric
59514f1b3e8SDimitry Andric static PythonModule AddModule(llvm::StringRef module);
596e81d9d49SDimitry Andric
597ead24645SDimitry Andric // safe, returns invalid on error;
598ead24645SDimitry Andric static PythonModule ImportModule(llvm::StringRef name) {
599cfca06d7SDimitry Andric std::string s = std::string(name);
600ead24645SDimitry Andric auto mod = Import(s.c_str());
601ead24645SDimitry Andric if (!mod) {
602ead24645SDimitry Andric llvm::consumeError(mod.takeError());
603ead24645SDimitry Andric return PythonModule();
604ead24645SDimitry Andric }
605ead24645SDimitry Andric return std::move(mod.get());
606ead24645SDimitry Andric }
607e81d9d49SDimitry Andric
608ead24645SDimitry Andric static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
609e81d9d49SDimitry Andric
610ead24645SDimitry Andric llvm::Expected<PythonObject> Get(const llvm::Twine &name);
611e81d9d49SDimitry Andric
612e81d9d49SDimitry Andric PythonDictionary GetDictionary() const;
613e81d9d49SDimitry Andric };
614e81d9d49SDimitry Andric
615ead24645SDimitry Andric class PythonCallable : public TypedPythonObject<PythonCallable> {
616e81d9d49SDimitry Andric public:
617ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
618ead24645SDimitry Andric
619e81d9d49SDimitry Andric struct ArgInfo {
620ead24645SDimitry Andric /* the largest number of positional arguments this callable
621ead24645SDimitry Andric * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
622ead24645SDimitry Andric * function and can accept an arbitrary number */
623ead24645SDimitry Andric unsigned max_positional_args;
624ead24645SDimitry Andric static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
625e81d9d49SDimitry Andric };
626e81d9d49SDimitry Andric
62714f1b3e8SDimitry Andric static bool Check(PyObject *py_obj);
628e81d9d49SDimitry Andric
629ead24645SDimitry Andric llvm::Expected<ArgInfo> GetArgInfo() const;
630e81d9d49SDimitry Andric
63114f1b3e8SDimitry Andric PythonObject operator()();
632e81d9d49SDimitry Andric
63314f1b3e8SDimitry Andric PythonObject operator()(std::initializer_list<PyObject *> args);
634e81d9d49SDimitry Andric
63514f1b3e8SDimitry Andric PythonObject operator()(std::initializer_list<PythonObject> args);
636e81d9d49SDimitry Andric
637e81d9d49SDimitry Andric template <typename Arg, typename... Args>
63814f1b3e8SDimitry Andric PythonObject operator()(const Arg &arg, Args... args) {
639e81d9d49SDimitry Andric return operator()({arg, args...});
640e81d9d49SDimitry Andric }
641e81d9d49SDimitry Andric };
642e81d9d49SDimitry Andric
643ead24645SDimitry Andric class PythonFile : public TypedPythonObject<PythonFile> {
644e81d9d49SDimitry Andric public:
645ead24645SDimitry Andric using TypedPythonObject::TypedPythonObject;
646e81d9d49SDimitry Andric
647ead24645SDimitry Andric PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
648e81d9d49SDimitry Andric
649e81d9d49SDimitry Andric static bool Check(PyObject *py_obj);
650e81d9d49SDimitry Andric
651ead24645SDimitry Andric static llvm::Expected<PythonFile> FromFile(File &file,
652ead24645SDimitry Andric const char *mode = nullptr);
653e81d9d49SDimitry Andric
654ead24645SDimitry Andric llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
655ead24645SDimitry Andric llvm::Expected<lldb::FileSP>
656ead24645SDimitry Andric ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
657e81d9d49SDimitry Andric };
658e81d9d49SDimitry Andric
659ead24645SDimitry Andric class PythonException : public llvm::ErrorInfo<PythonException> {
660ead24645SDimitry Andric private:
661ead24645SDimitry Andric PyObject *m_exception_type, *m_exception, *m_traceback;
662ead24645SDimitry Andric PyObject *m_repr_bytes;
663ead24645SDimitry Andric
664ead24645SDimitry Andric public:
665ead24645SDimitry Andric static char ID;
666ead24645SDimitry Andric const char *toCString() const;
667ead24645SDimitry Andric PythonException(const char *caller = nullptr);
668ead24645SDimitry Andric void Restore();
669145449b1SDimitry Andric ~PythonException() override;
670ead24645SDimitry Andric void log(llvm::raw_ostream &OS) const override;
671ead24645SDimitry Andric std::error_code convertToErrorCode() const override;
672ead24645SDimitry Andric bool Matches(PyObject *exc) const;
673ead24645SDimitry Andric std::string ReadBacktrace() const;
674ead24645SDimitry Andric };
675ead24645SDimitry Andric
676ead24645SDimitry Andric // This extracts the underlying T out of an Expected<T> and returns it.
677ead24645SDimitry Andric // If the Expected is an Error instead of a T, that error will be converted
678ead24645SDimitry Andric // into a python exception, and this will return a default-constructed T.
679ead24645SDimitry Andric //
680ead24645SDimitry Andric // This is appropriate for use right at the boundary of python calling into
681ead24645SDimitry Andric // C++, such as in a SWIG typemap. In such a context you should simply
682ead24645SDimitry Andric // check if the returned T is valid, and if it is, return a NULL back
683ead24645SDimitry Andric // to python. This will result in the Error being raised as an exception
684ead24645SDimitry Andric // from python code's point of view.
685ead24645SDimitry Andric //
686ead24645SDimitry Andric // For example:
687ead24645SDimitry Andric // ```
688ead24645SDimitry Andric // Expected<Foo *> efoop = some_cpp_function();
689ead24645SDimitry Andric // Foo *foop = unwrapOrSetPythonException(efoop);
690ead24645SDimitry Andric // if (!foop)
691ead24645SDimitry Andric // return NULL;
692ead24645SDimitry Andric // do_something(*foop);
693ead24645SDimitry Andric //
694ead24645SDimitry Andric // If the Error returned was itself created because a python exception was
695ead24645SDimitry Andric // raised when C++ code called into python, then the original exception
696ead24645SDimitry Andric // will be restored. Otherwise a simple string exception will be raised.
697ead24645SDimitry Andric template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
698ead24645SDimitry Andric if (expected)
699ead24645SDimitry Andric return expected.get();
700ead24645SDimitry Andric llvm::handleAllErrors(
701ead24645SDimitry Andric expected.takeError(), [](PythonException &E) { E.Restore(); },
702ead24645SDimitry Andric [](const llvm::ErrorInfoBase &E) {
703ead24645SDimitry Andric PyErr_SetString(PyExc_Exception, E.message().c_str());
704ead24645SDimitry Andric });
705ead24645SDimitry Andric return T();
706ead24645SDimitry Andric }
707ead24645SDimitry Andric
708ead24645SDimitry Andric // This is only here to help incrementally migrate old, exception-unsafe
709ead24645SDimitry Andric // code.
710ead24645SDimitry Andric template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
711ead24645SDimitry Andric if (expected)
712ead24645SDimitry Andric return std::move(expected.get());
713ead24645SDimitry Andric llvm::consumeError(expected.takeError());
714ead24645SDimitry Andric return T();
715ead24645SDimitry Andric }
716ead24645SDimitry Andric
717ead24645SDimitry Andric llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
718ead24645SDimitry Andric const PythonDictionary &globals,
719ead24645SDimitry Andric const PythonDictionary &locals);
720ead24645SDimitry Andric
721ead24645SDimitry Andric llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
722ead24645SDimitry Andric const PythonDictionary &globals,
723ead24645SDimitry Andric const PythonDictionary &locals);
724ead24645SDimitry Andric
725ead24645SDimitry Andric // Sometimes the best way to interact with a python interpreter is
726ead24645SDimitry Andric // to run some python code. You construct a PythonScript with
727ead24645SDimitry Andric // script string. The script assigns some function to `_function_`
728ead24645SDimitry Andric // and you get a C++ callable object that calls the python function.
729ead24645SDimitry Andric //
730ead24645SDimitry Andric // Example:
731ead24645SDimitry Andric //
732ead24645SDimitry Andric // const char script[] = R"(
733ead24645SDimitry Andric // def main(x, y):
734ead24645SDimitry Andric // ....
735ead24645SDimitry Andric // )";
736ead24645SDimitry Andric //
737ead24645SDimitry Andric // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
738ead24645SDimitry Andric // // no need to synchronize access to this global, we already have the GIL
739ead24645SDimitry Andric // static PythonScript foo(script)
740ead24645SDimitry Andric // return foo(x, y);
741ead24645SDimitry Andric // }
742ead24645SDimitry Andric class PythonScript {
743ead24645SDimitry Andric const char *script;
744ead24645SDimitry Andric PythonCallable function;
745ead24645SDimitry Andric
746ead24645SDimitry Andric llvm::Error Init();
747ead24645SDimitry Andric
748ead24645SDimitry Andric public:
749ead24645SDimitry Andric PythonScript(const char *script) : script(script), function() {}
750ead24645SDimitry Andric
751ead24645SDimitry Andric template <typename... Args>
752ead24645SDimitry Andric llvm::Expected<PythonObject> operator()(Args &&... args) {
753ead24645SDimitry Andric if (llvm::Error error = Init())
754ead24645SDimitry Andric return std::move(error);
755ead24645SDimitry Andric return function.Call(std::forward<Args>(args)...);
756ead24645SDimitry Andric }
757ead24645SDimitry Andric };
758ead24645SDimitry Andric
7596f8fc217SDimitry Andric class StructuredPythonObject : public StructuredData::Generic {
7606f8fc217SDimitry Andric public:
7616f8fc217SDimitry Andric StructuredPythonObject() : StructuredData::Generic() {}
7626f8fc217SDimitry Andric
7636f8fc217SDimitry Andric // Take ownership of the object we received.
7646f8fc217SDimitry Andric StructuredPythonObject(PythonObject obj)
7656f8fc217SDimitry Andric : StructuredData::Generic(obj.release()) {}
7666f8fc217SDimitry Andric
7676f8fc217SDimitry Andric ~StructuredPythonObject() override {
7686f8fc217SDimitry Andric // Hand ownership back to a (temporary) PythonObject instance and let it
7696f8fc217SDimitry Andric // take care of releasing it.
7706f8fc217SDimitry Andric PythonObject(PyRefType::Owned, static_cast<PyObject *>(GetValue()));
7716f8fc217SDimitry Andric }
7726f8fc217SDimitry Andric
7736f8fc217SDimitry Andric bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
7746f8fc217SDimitry Andric
7756f8fc217SDimitry Andric void Serialize(llvm::json::OStream &s) const override;
7766f8fc217SDimitry Andric
7776f8fc217SDimitry Andric private:
7786f8fc217SDimitry Andric StructuredPythonObject(const StructuredPythonObject &) = delete;
7796f8fc217SDimitry Andric const StructuredPythonObject &
7806f8fc217SDimitry Andric operator=(const StructuredPythonObject &) = delete;
7816f8fc217SDimitry Andric };
7826f8fc217SDimitry Andric
783ead24645SDimitry Andric } // namespace python
784e81d9d49SDimitry Andric } // namespace lldb_private
785e81d9d49SDimitry Andric
786e81d9d49SDimitry Andric #endif
787e81d9d49SDimitry Andric
788e81d9d49SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
789