xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (revision 190fadcdb245707011e31b69a24bd6bba7c93ab5)
1 //===-- PythonDataObjects.cpp ------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifdef LLDB_DISABLE_PYTHON
11 
12 // Python is disabled in this build
13 
14 #else
15 
16 #include "lldb-python.h"
17 #include "PythonDataObjects.h"
18 #include "ScriptInterpreterPython.h"
19 
20 #include "lldb/Core/Stream.h"
21 #include "lldb/Host/File.h"
22 #include "lldb/Host/FileSystem.h"
23 #include "lldb/Interpreter/ScriptInterpreter.h"
24 
25 #include "llvm/Support/ConvertUTF.h"
26 
27 #include <stdio.h>
28 
29 #include "llvm/ADT/StringSwitch.h"
30 
31 using namespace lldb_private;
32 using namespace lldb;
33 
34 void
35 StructuredPythonObject::Dump(Stream &s) const
36 {
37     s << "Python Obj: 0x" << GetValue();
38 }
39 
40 //----------------------------------------------------------------------
41 // PythonObject
42 //----------------------------------------------------------------------
43 
44 void
45 PythonObject::Dump(Stream &strm) const
46 {
47     if (m_py_obj)
48     {
49         FILE *file = ::tmpfile();
50         if (file)
51         {
52             ::PyObject_Print (m_py_obj, file, 0);
53             const long length = ftell (file);
54             if (length)
55             {
56                 ::rewind(file);
57                 std::vector<char> file_contents (length,'\0');
58                 const size_t length_read = ::fread (file_contents.data(), 1, file_contents.size(), file);
59                 if (length_read > 0)
60                     strm.Write (file_contents.data(), length_read);
61             }
62             ::fclose (file);
63         }
64     }
65     else
66         strm.PutCString ("NULL");
67 }
68 
69 PyObjectType
70 PythonObject::GetObjectType() const
71 {
72     if (!IsAllocated())
73         return PyObjectType::None;
74 
75     if (PythonModule::Check(m_py_obj))
76         return PyObjectType::Module;
77     if (PythonList::Check(m_py_obj))
78         return PyObjectType::List;
79     if (PythonTuple::Check(m_py_obj))
80         return PyObjectType::Tuple;
81     if (PythonDictionary::Check(m_py_obj))
82         return PyObjectType::Dictionary;
83     if (PythonString::Check(m_py_obj))
84         return PyObjectType::String;
85 #if PY_MAJOR_VERSION >= 3
86     if (PythonBytes::Check(m_py_obj))
87         return PyObjectType::Bytes;
88 #endif
89     if (PythonByteArray::Check(m_py_obj))
90         return PyObjectType::ByteArray;
91     if (PythonInteger::Check(m_py_obj))
92         return PyObjectType::Integer;
93     if (PythonFile::Check(m_py_obj))
94         return PyObjectType::File;
95     if (PythonCallable::Check(m_py_obj))
96         return PyObjectType::Callable;
97     return PyObjectType::Unknown;
98 }
99 
100 PythonString
101 PythonObject::Repr() const
102 {
103     if (!m_py_obj)
104         return PythonString();
105     PyObject *repr = PyObject_Repr(m_py_obj);
106     if (!repr)
107         return PythonString();
108     return PythonString(PyRefType::Owned, repr);
109 }
110 
111 PythonString
112 PythonObject::Str() const
113 {
114     if (!m_py_obj)
115         return PythonString();
116     PyObject *str = PyObject_Str(m_py_obj);
117     if (!str)
118         return PythonString();
119     return PythonString(PyRefType::Owned, str);
120 }
121 
122 PythonObject
123 PythonObject::ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict)
124 {
125     size_t dot_pos = name.find_first_of('.');
126     llvm::StringRef piece = name.substr(0, dot_pos);
127     PythonObject result = dict.GetItemForKey(PythonString(piece));
128     if (dot_pos == llvm::StringRef::npos)
129     {
130         // There was no dot, we're done.
131         return result;
132     }
133 
134     // There was a dot.  The remaining portion of the name should be looked up in
135     // the context of the object that was found in the dictionary.
136     return result.ResolveName(name.substr(dot_pos + 1));
137 }
138 
139 PythonObject
140 PythonObject::ResolveName(llvm::StringRef name) const
141 {
142     // Resolve the name in the context of the specified object.  If,
143     // for example, `this` refers to a PyModule, then this will look for
144     // `name` in this module.  If `this` refers to a PyType, then it will
145     // resolve `name` as an attribute of that type.  If `this` refers to
146     // an instance of an object, then it will resolve `name` as the value
147     // of the specified field.
148     //
149     // This function handles dotted names so that, for example, if `m_py_obj`
150     // refers to the `sys` module, and `name` == "path.append", then it
151     // will find the function `sys.path.append`.
152 
153     size_t dot_pos = name.find_first_of('.');
154     if (dot_pos == llvm::StringRef::npos)
155     {
156         // No dots in the name, we should be able to find the value immediately
157         // as an attribute of `m_py_obj`.
158         return GetAttributeValue(name);
159     }
160 
161     // Look up the first piece of the name, and resolve the rest as a child of that.
162     PythonObject parent = ResolveName(name.substr(0, dot_pos));
163     if (!parent.IsAllocated())
164         return PythonObject();
165 
166     // Tail recursion.. should be optimized by the compiler
167     return parent.ResolveName(name.substr(dot_pos + 1));
168 }
169 
170 bool
171 PythonObject::HasAttribute(llvm::StringRef attr) const
172 {
173     if (!IsValid())
174         return false;
175     PythonString py_attr(attr);
176     return !!PyObject_HasAttr(m_py_obj, py_attr.get());
177 }
178 
179 PythonObject
180 PythonObject::GetAttributeValue(llvm::StringRef attr) const
181 {
182     if (!IsValid())
183         return PythonObject();
184 
185     PythonString py_attr(attr);
186     if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
187         return PythonObject();
188 
189     return PythonObject(PyRefType::Owned,
190         PyObject_GetAttr(m_py_obj, py_attr.get()));
191 }
192 
193 bool
194 PythonObject::IsNone() const
195 {
196     return m_py_obj == Py_None;
197 }
198 
199 bool
200 PythonObject::IsValid() const
201 {
202     return m_py_obj != nullptr;
203 }
204 
205 bool
206 PythonObject::IsAllocated() const
207 {
208     return IsValid() && !IsNone();
209 }
210 
211 StructuredData::ObjectSP
212 PythonObject::CreateStructuredObject() const
213 {
214     switch (GetObjectType())
215     {
216         case PyObjectType::Dictionary:
217             return PythonDictionary(PyRefType::Borrowed, m_py_obj).CreateStructuredDictionary();
218         case PyObjectType::Integer:
219             return PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger();
220         case PyObjectType::List:
221             return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
222         case PyObjectType::String:
223             return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
224         case PyObjectType::Bytes:
225             return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
226         case PyObjectType::ByteArray:
227             return PythonByteArray(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
228         case PyObjectType::None:
229             return StructuredData::ObjectSP();
230         default:
231             return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
232     }
233 }
234 
235 //----------------------------------------------------------------------
236 // PythonString
237 //----------------------------------------------------------------------
238 PythonBytes::PythonBytes() : PythonObject()
239 {
240 }
241 
242 PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject()
243 {
244     SetBytes(bytes);
245 }
246 
247 PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject()
248 {
249     SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
250 }
251 
252 PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject()
253 {
254     Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
255 }
256 
257 PythonBytes::PythonBytes(const PythonBytes &object) : PythonObject(object)
258 {
259 }
260 
261 PythonBytes::~PythonBytes()
262 {
263 }
264 
265 bool
266 PythonBytes::Check(PyObject *py_obj)
267 {
268     if (!py_obj)
269         return false;
270     if (PyBytes_Check(py_obj))
271         return true;
272     return false;
273 }
274 
275 void
276 PythonBytes::Reset(PyRefType type, PyObject *py_obj)
277 {
278     // Grab the desired reference type so that if we end up rejecting
279     // `py_obj` it still gets decremented if necessary.
280     PythonObject result(type, py_obj);
281 
282     if (!PythonBytes::Check(py_obj))
283     {
284         PythonObject::Reset();
285         return;
286     }
287 
288     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
289     // back into the virtual implementation.
290     PythonObject::Reset(PyRefType::Borrowed, result.get());
291 }
292 
293 llvm::ArrayRef<uint8_t>
294 PythonBytes::GetBytes() const
295 {
296     if (!IsValid())
297         return llvm::ArrayRef<uint8_t>();
298 
299     Py_ssize_t size;
300     char *c;
301 
302     PyBytes_AsStringAndSize(m_py_obj, &c, &size);
303     return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
304 }
305 
306 size_t
307 PythonBytes::GetSize() const
308 {
309     if (!IsValid())
310         return 0;
311     return PyBytes_Size(m_py_obj);
312 }
313 
314 void
315 PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes)
316 {
317     const char *data = reinterpret_cast<const char *>(bytes.data());
318     PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
319     PythonObject::Reset(PyRefType::Owned, py_bytes);
320 }
321 
322 StructuredData::StringSP
323 PythonBytes::CreateStructuredString() const
324 {
325     StructuredData::StringSP result(new StructuredData::String);
326     Py_ssize_t size;
327     char *c;
328     PyBytes_AsStringAndSize(m_py_obj, &c, &size);
329     result->SetValue(std::string(c, size));
330     return result;
331 }
332 
333 PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes) : PythonByteArray(bytes.data(), bytes.size())
334 {
335 }
336 
337 PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length)
338 {
339     const char *str = reinterpret_cast<const char *>(bytes);
340     Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
341 }
342 
343 PythonByteArray::PythonByteArray(PyRefType type, PyObject *o)
344 {
345     Reset(type, o);
346 }
347 
348 PythonByteArray::PythonByteArray(const PythonBytes &object) : PythonObject(object)
349 {
350 }
351 
352 PythonByteArray::~PythonByteArray()
353 {
354 }
355 
356 bool
357 PythonByteArray::Check(PyObject *py_obj)
358 {
359     if (!py_obj)
360         return false;
361     if (PyByteArray_Check(py_obj))
362         return true;
363     return false;
364 }
365 
366 void
367 PythonByteArray::Reset(PyRefType type, PyObject *py_obj)
368 {
369     // Grab the desired reference type so that if we end up rejecting
370     // `py_obj` it still gets decremented if necessary.
371     PythonObject result(type, py_obj);
372 
373     if (!PythonByteArray::Check(py_obj))
374     {
375         PythonObject::Reset();
376         return;
377     }
378 
379     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
380     // back into the virtual implementation.
381     PythonObject::Reset(PyRefType::Borrowed, result.get());
382 }
383 
384 llvm::ArrayRef<uint8_t>
385 PythonByteArray::GetBytes() const
386 {
387     if (!IsValid())
388         return llvm::ArrayRef<uint8_t>();
389 
390     char *c = PyByteArray_AsString(m_py_obj);
391     size_t size = GetSize();
392     return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
393 }
394 
395 size_t
396 PythonByteArray::GetSize() const
397 {
398     if (!IsValid())
399         return 0;
400 
401     return PyByteArray_Size(m_py_obj);
402 }
403 
404 StructuredData::StringSP
405 PythonByteArray::CreateStructuredString() const
406 {
407     StructuredData::StringSP result(new StructuredData::String);
408     llvm::ArrayRef<uint8_t> bytes = GetBytes();
409     const char *str = reinterpret_cast<const char *>(bytes.data());
410     result->SetValue(std::string(str, bytes.size()));
411     return result;
412 }
413 
414 //----------------------------------------------------------------------
415 // PythonString
416 //----------------------------------------------------------------------
417 
418 PythonString::PythonString(PyRefType type, PyObject *py_obj)
419     : PythonObject()
420 {
421     Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
422 }
423 
424 PythonString::PythonString(const PythonString &object)
425     : PythonObject(object)
426 {
427 }
428 
429 PythonString::PythonString(llvm::StringRef string)
430     : PythonObject()
431 {
432     SetString(string);
433 }
434 
435 PythonString::PythonString(const char *string)
436     : PythonObject()
437 {
438     SetString(llvm::StringRef(string));
439 }
440 
441 PythonString::PythonString()
442     : PythonObject()
443 {
444 }
445 
446 PythonString::~PythonString ()
447 {
448 }
449 
450 bool
451 PythonString::Check(PyObject *py_obj)
452 {
453     if (!py_obj)
454         return false;
455 
456     if (PyUnicode_Check(py_obj))
457         return true;
458 #if PY_MAJOR_VERSION < 3
459     if (PyString_Check(py_obj))
460         return true;
461 #endif
462     return false;
463 }
464 
465 void
466 PythonString::Reset(PyRefType type, PyObject *py_obj)
467 {
468     // Grab the desired reference type so that if we end up rejecting
469     // `py_obj` it still gets decremented if necessary.
470     PythonObject result(type, py_obj);
471 
472     if (!PythonString::Check(py_obj))
473     {
474         PythonObject::Reset();
475         return;
476     }
477 #if PY_MAJOR_VERSION < 3
478     // In Python 2, Don't store PyUnicode objects directly, because we need
479     // access to their underlying character buffers which Python 2 doesn't
480     // provide.
481     if (PyUnicode_Check(py_obj))
482         result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get()));
483 #endif
484     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
485     // back into the virtual implementation.
486     PythonObject::Reset(PyRefType::Borrowed, result.get());
487 }
488 
489 llvm::StringRef
490 PythonString::GetString() const
491 {
492     if (!IsValid())
493         return llvm::StringRef();
494 
495     Py_ssize_t size;
496     char *c;
497 
498 #if PY_MAJOR_VERSION >= 3
499     c = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
500 #else
501     PyString_AsStringAndSize(m_py_obj, &c, &size);
502 #endif
503     return llvm::StringRef(c, size);
504 }
505 
506 size_t
507 PythonString::GetSize() const
508 {
509     if (IsValid())
510     {
511 #if PY_MAJOR_VERSION >= 3
512         return PyUnicode_GetSize(m_py_obj);
513 #else
514         return PyString_Size(m_py_obj);
515 #endif
516     }
517     return 0;
518 }
519 
520 void
521 PythonString::SetString (llvm::StringRef string)
522 {
523 #if PY_MAJOR_VERSION >= 3
524     PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size());
525     PythonObject::Reset(PyRefType::Owned, unicode);
526 #else
527     PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
528     PythonObject::Reset(PyRefType::Owned, str);
529 #endif
530 }
531 
532 StructuredData::StringSP
533 PythonString::CreateStructuredString() const
534 {
535     StructuredData::StringSP result(new StructuredData::String);
536     result->SetValue(GetString());
537     return result;
538 }
539 
540 //----------------------------------------------------------------------
541 // PythonInteger
542 //----------------------------------------------------------------------
543 
544 PythonInteger::PythonInteger()
545     : PythonObject()
546 {
547 
548 }
549 
550 PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj)
551     : PythonObject()
552 {
553     Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type
554 }
555 
556 PythonInteger::PythonInteger(const PythonInteger &object)
557     : PythonObject(object)
558 {
559 }
560 
561 PythonInteger::PythonInteger(int64_t value)
562     : PythonObject()
563 {
564     SetInteger(value);
565 }
566 
567 
568 PythonInteger::~PythonInteger ()
569 {
570 }
571 
572 bool
573 PythonInteger::Check(PyObject *py_obj)
574 {
575     if (!py_obj)
576         return false;
577 
578 #if PY_MAJOR_VERSION >= 3
579     // Python 3 does not have PyInt_Check.  There is only one type of
580     // integral value, long.
581     return PyLong_Check(py_obj);
582 #else
583     return PyLong_Check(py_obj) || PyInt_Check(py_obj);
584 #endif
585 }
586 
587 void
588 PythonInteger::Reset(PyRefType type, PyObject *py_obj)
589 {
590     // Grab the desired reference type so that if we end up rejecting
591     // `py_obj` it still gets decremented if necessary.
592     PythonObject result(type, py_obj);
593 
594     if (!PythonInteger::Check(py_obj))
595     {
596         PythonObject::Reset();
597         return;
598     }
599 
600 #if PY_MAJOR_VERSION < 3
601     // Always store this as a PyLong, which makes interoperability between
602     // Python 2.x and Python 3.x easier.  This is only necessary in 2.x,
603     // since 3.x doesn't even have a PyInt.
604     if (PyInt_Check(py_obj))
605     {
606         // Since we converted the original object to a different type, the new
607         // object is an owned object regardless of the ownership semantics requested
608         // by the user.
609         result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj)));
610     }
611 #endif
612 
613     assert(PyLong_Check(result.get()) && "Couldn't get a PyLong from this PyObject");
614 
615     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
616     // back into the virtual implementation.
617     PythonObject::Reset(PyRefType::Borrowed, result.get());
618 }
619 
620 int64_t
621 PythonInteger::GetInteger() const
622 {
623     if (m_py_obj)
624     {
625         assert(PyLong_Check(m_py_obj) && "PythonInteger::GetInteger has a PyObject that isn't a PyLong");
626 
627         return PyLong_AsLongLong(m_py_obj);
628     }
629     return UINT64_MAX;
630 }
631 
632 void
633 PythonInteger::SetInteger(int64_t value)
634 {
635     PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
636 }
637 
638 StructuredData::IntegerSP
639 PythonInteger::CreateStructuredInteger() const
640 {
641     StructuredData::IntegerSP result(new StructuredData::Integer);
642     result->SetValue(GetInteger());
643     return result;
644 }
645 
646 //----------------------------------------------------------------------
647 // PythonList
648 //----------------------------------------------------------------------
649 
650 PythonList::PythonList(PyInitialValue value)
651     : PythonObject()
652 {
653     if (value == PyInitialValue::Empty)
654         Reset(PyRefType::Owned, PyList_New(0));
655 }
656 
657 PythonList::PythonList(int list_size)
658     : PythonObject()
659 {
660     Reset(PyRefType::Owned, PyList_New(list_size));
661 }
662 
663 PythonList::PythonList(PyRefType type, PyObject *py_obj)
664     : PythonObject()
665 {
666     Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list
667 }
668 
669 PythonList::PythonList(const PythonList &list)
670     : PythonObject(list)
671 {
672 }
673 
674 PythonList::~PythonList ()
675 {
676 }
677 
678 bool
679 PythonList::Check(PyObject *py_obj)
680 {
681     if (!py_obj)
682         return false;
683     return PyList_Check(py_obj);
684 }
685 
686 void
687 PythonList::Reset(PyRefType type, PyObject *py_obj)
688 {
689     // Grab the desired reference type so that if we end up rejecting
690     // `py_obj` it still gets decremented if necessary.
691     PythonObject result(type, py_obj);
692 
693     if (!PythonList::Check(py_obj))
694     {
695         PythonObject::Reset();
696         return;
697     }
698 
699     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
700     // back into the virtual implementation.
701     PythonObject::Reset(PyRefType::Borrowed, result.get());
702 }
703 
704 uint32_t
705 PythonList::GetSize() const
706 {
707     if (IsValid())
708         return PyList_GET_SIZE(m_py_obj);
709     return 0;
710 }
711 
712 PythonObject
713 PythonList::GetItemAtIndex(uint32_t index) const
714 {
715     if (IsValid())
716         return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
717     return PythonObject();
718 }
719 
720 void
721 PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object)
722 {
723     if (IsAllocated() && object.IsValid())
724     {
725         // PyList_SetItem is documented to "steal" a reference, so we need to
726         // convert it to an owned reference by incrementing it.
727         Py_INCREF(object.get());
728         PyList_SetItem(m_py_obj, index, object.get());
729     }
730 }
731 
732 void
733 PythonList::AppendItem(const PythonObject &object)
734 {
735     if (IsAllocated() && object.IsValid())
736     {
737         // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
738         // here like we do with `PyList_SetItem`.
739         PyList_Append(m_py_obj, object.get());
740     }
741 }
742 
743 StructuredData::ArraySP
744 PythonList::CreateStructuredArray() const
745 {
746     StructuredData::ArraySP result(new StructuredData::Array);
747     uint32_t count = GetSize();
748     for (uint32_t i = 0; i < count; ++i)
749     {
750         PythonObject obj = GetItemAtIndex(i);
751         result->AddItem(obj.CreateStructuredObject());
752     }
753     return result;
754 }
755 
756 //----------------------------------------------------------------------
757 // PythonTuple
758 //----------------------------------------------------------------------
759 
760 PythonTuple::PythonTuple(PyInitialValue value)
761     : PythonObject()
762 {
763     if (value == PyInitialValue::Empty)
764         Reset(PyRefType::Owned, PyTuple_New(0));
765 }
766 
767 PythonTuple::PythonTuple(int tuple_size)
768     : PythonObject()
769 {
770     Reset(PyRefType::Owned, PyTuple_New(tuple_size));
771 }
772 
773 PythonTuple::PythonTuple(PyRefType type, PyObject *py_obj)
774     : PythonObject()
775 {
776     Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a tuple
777 }
778 
779 PythonTuple::PythonTuple(const PythonTuple &tuple)
780     : PythonObject(tuple)
781 {
782 }
783 
784 PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects)
785 {
786     m_py_obj = PyTuple_New(objects.size());
787 
788     uint32_t idx = 0;
789     for (auto object : objects)
790     {
791         if (object.IsValid())
792             SetItemAtIndex(idx, object);
793         idx++;
794     }
795 }
796 
797 PythonTuple::PythonTuple(std::initializer_list<PyObject*> objects)
798 {
799     m_py_obj = PyTuple_New(objects.size());
800 
801     uint32_t idx = 0;
802     for (auto py_object : objects)
803     {
804         PythonObject object(PyRefType::Borrowed, py_object);
805         if (object.IsValid())
806             SetItemAtIndex(idx, object);
807         idx++;
808     }
809 }
810 
811 PythonTuple::~PythonTuple()
812 {
813 }
814 
815 bool
816 PythonTuple::Check(PyObject *py_obj)
817 {
818     if (!py_obj)
819         return false;
820     return PyTuple_Check(py_obj);
821 }
822 
823 void
824 PythonTuple::Reset(PyRefType type, PyObject *py_obj)
825 {
826     // Grab the desired reference type so that if we end up rejecting
827     // `py_obj` it still gets decremented if necessary.
828     PythonObject result(type, py_obj);
829 
830     if (!PythonTuple::Check(py_obj))
831     {
832         PythonObject::Reset();
833         return;
834     }
835 
836     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
837     // back into the virtual implementation.
838     PythonObject::Reset(PyRefType::Borrowed, result.get());
839 }
840 
841 uint32_t
842 PythonTuple::GetSize() const
843 {
844     if (IsValid())
845         return PyTuple_GET_SIZE(m_py_obj);
846     return 0;
847 }
848 
849 PythonObject
850 PythonTuple::GetItemAtIndex(uint32_t index) const
851 {
852     if (IsValid())
853         return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
854     return PythonObject();
855 }
856 
857 void
858 PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object)
859 {
860     if (IsAllocated() && object.IsValid())
861     {
862         // PyTuple_SetItem is documented to "steal" a reference, so we need to
863         // convert it to an owned reference by incrementing it.
864         Py_INCREF(object.get());
865         PyTuple_SetItem(m_py_obj, index, object.get());
866     }
867 }
868 
869 StructuredData::ArraySP
870 PythonTuple::CreateStructuredArray() const
871 {
872     StructuredData::ArraySP result(new StructuredData::Array);
873     uint32_t count = GetSize();
874     for (uint32_t i = 0; i < count; ++i)
875     {
876         PythonObject obj = GetItemAtIndex(i);
877         result->AddItem(obj.CreateStructuredObject());
878     }
879     return result;
880 }
881 
882 //----------------------------------------------------------------------
883 // PythonDictionary
884 //----------------------------------------------------------------------
885 
886 PythonDictionary::PythonDictionary(PyInitialValue value)
887     : PythonObject()
888 {
889     if (value == PyInitialValue::Empty)
890         Reset(PyRefType::Owned, PyDict_New());
891 }
892 
893 PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj)
894     : PythonObject()
895 {
896     Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
897 }
898 
899 PythonDictionary::PythonDictionary(const PythonDictionary &object)
900     : PythonObject(object)
901 {
902 }
903 
904 PythonDictionary::~PythonDictionary ()
905 {
906 }
907 
908 bool
909 PythonDictionary::Check(PyObject *py_obj)
910 {
911     if (!py_obj)
912         return false;
913 
914     return PyDict_Check(py_obj);
915 }
916 
917 void
918 PythonDictionary::Reset(PyRefType type, PyObject *py_obj)
919 {
920     // Grab the desired reference type so that if we end up rejecting
921     // `py_obj` it still gets decremented if necessary.
922     PythonObject result(type, py_obj);
923 
924     if (!PythonDictionary::Check(py_obj))
925     {
926         PythonObject::Reset();
927         return;
928     }
929 
930     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
931     // back into the virtual implementation.
932     PythonObject::Reset(PyRefType::Borrowed, result.get());
933 }
934 
935 uint32_t
936 PythonDictionary::GetSize() const
937 {
938     if (IsValid())
939         return PyDict_Size(m_py_obj);
940     return 0;
941 }
942 
943 PythonList
944 PythonDictionary::GetKeys() const
945 {
946     if (IsValid())
947         return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
948     return PythonList(PyInitialValue::Invalid);
949 }
950 
951 PythonObject
952 PythonDictionary::GetItemForKey(const PythonObject &key) const
953 {
954     if (IsAllocated() && key.IsValid())
955         return PythonObject(PyRefType::Borrowed, PyDict_GetItem(m_py_obj, key.get()));
956     return PythonObject();
957 }
958 
959 void
960 PythonDictionary::SetItemForKey(const PythonObject &key, const PythonObject &value)
961 {
962     if (IsAllocated() && key.IsValid() && value.IsValid())
963         PyDict_SetItem(m_py_obj, key.get(), value.get());
964 }
965 
966 StructuredData::DictionarySP
967 PythonDictionary::CreateStructuredDictionary() const
968 {
969     StructuredData::DictionarySP result(new StructuredData::Dictionary);
970     PythonList keys(GetKeys());
971     uint32_t num_keys = keys.GetSize();
972     for (uint32_t i = 0; i < num_keys; ++i)
973     {
974         PythonObject key = keys.GetItemAtIndex(i);
975         PythonObject value = GetItemForKey(key);
976         StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
977         result->AddItem(key.Str().GetString(), structured_value);
978     }
979     return result;
980 }
981 
982 PythonModule::PythonModule() : PythonObject()
983 {
984 }
985 
986 PythonModule::PythonModule(PyRefType type, PyObject *py_obj)
987 {
988     Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a module
989 }
990 
991 PythonModule::PythonModule(const PythonModule &dict) : PythonObject(dict)
992 {
993 }
994 
995 PythonModule::~PythonModule()
996 {
997 }
998 
999 PythonModule
1000 PythonModule::BuiltinsModule()
1001 {
1002 #if PY_MAJOR_VERSION >= 3
1003     return AddModule("builtins");
1004 #else
1005     return AddModule("__builtin__");
1006 #endif
1007 }
1008 
1009 PythonModule
1010 PythonModule::MainModule()
1011 {
1012     return AddModule("__main__");
1013 }
1014 
1015 PythonModule
1016 PythonModule::AddModule(llvm::StringRef module)
1017 {
1018     std::string str = module.str();
1019     return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
1020 }
1021 
1022 
1023 PythonModule
1024 PythonModule::ImportModule(llvm::StringRef module)
1025 {
1026     std::string str = module.str();
1027     return PythonModule(PyRefType::Owned, PyImport_ImportModule(str.c_str()));
1028 }
1029 
1030 bool
1031 PythonModule::Check(PyObject *py_obj)
1032 {
1033     if (!py_obj)
1034         return false;
1035 
1036     return PyModule_Check(py_obj);
1037 }
1038 
1039 void
1040 PythonModule::Reset(PyRefType type, PyObject *py_obj)
1041 {
1042     // Grab the desired reference type so that if we end up rejecting
1043     // `py_obj` it still gets decremented if necessary.
1044     PythonObject result(type, py_obj);
1045 
1046     if (!PythonModule::Check(py_obj))
1047     {
1048         PythonObject::Reset();
1049         return;
1050     }
1051 
1052     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
1053     // back into the virtual implementation.
1054     PythonObject::Reset(PyRefType::Borrowed, result.get());
1055 }
1056 
1057 PythonDictionary
1058 PythonModule::GetDictionary() const
1059 {
1060     return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj));
1061 }
1062 
1063 PythonCallable::PythonCallable() : PythonObject()
1064 {
1065 }
1066 
1067 PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj)
1068 {
1069     Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable
1070 }
1071 
1072 PythonCallable::PythonCallable(const PythonCallable &callable)
1073     : PythonObject(callable)
1074 {
1075 }
1076 
1077 PythonCallable::~PythonCallable()
1078 {
1079 }
1080 
1081 bool
1082 PythonCallable::Check(PyObject *py_obj)
1083 {
1084     if (!py_obj)
1085         return false;
1086 
1087     return PyCallable_Check(py_obj);
1088 }
1089 
1090 void
1091 PythonCallable::Reset(PyRefType type, PyObject *py_obj)
1092 {
1093     // Grab the desired reference type so that if we end up rejecting
1094     // `py_obj` it still gets decremented if necessary.
1095     PythonObject result(type, py_obj);
1096 
1097     if (!PythonCallable::Check(py_obj))
1098     {
1099         PythonObject::Reset();
1100         return;
1101     }
1102 
1103     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
1104     // back into the virtual implementation.
1105     PythonObject::Reset(PyRefType::Borrowed, result.get());
1106 }
1107 
1108 
1109 PythonCallable::ArgInfo
1110 PythonCallable::GetNumArguments() const
1111 {
1112     ArgInfo result = { 0, false, false };
1113     if (!IsValid())
1114         return result;
1115 
1116     PyObject *py_func_obj = m_py_obj;
1117     if (PyMethod_Check(py_func_obj))
1118         py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
1119 
1120     if (!py_func_obj)
1121         return result;
1122 
1123     PyCodeObject* code = (PyCodeObject*)PyFunction_GET_CODE(py_func_obj);
1124     if (!code)
1125         return result;
1126 
1127     result.count = code->co_argcount;
1128     result.has_varargs = !!(code->co_flags & CO_VARARGS);
1129     result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS);
1130     return result;
1131 }
1132 
1133 PythonObject
1134 PythonCallable::operator ()()
1135 {
1136     return PythonObject(PyRefType::Owned,
1137         PyObject_CallObject(m_py_obj, nullptr));
1138 }
1139 
1140 PythonObject
1141 PythonCallable::operator ()(std::initializer_list<PyObject*> args)
1142 {
1143     PythonTuple arg_tuple(args);
1144     return PythonObject(PyRefType::Owned,
1145         PyObject_CallObject(m_py_obj, arg_tuple.get()));
1146 }
1147 
1148 PythonObject
1149 PythonCallable::operator ()(std::initializer_list<PythonObject> args)
1150 {
1151     PythonTuple arg_tuple(args);
1152     return PythonObject(PyRefType::Owned,
1153         PyObject_CallObject(m_py_obj, arg_tuple.get()));
1154 }
1155 
1156 PythonFile::PythonFile()
1157     : PythonObject()
1158 {
1159 }
1160 
1161 PythonFile::PythonFile(File &file, const char *mode)
1162 {
1163     Reset(file, mode);
1164 }
1165 
1166 PythonFile::PythonFile(const char *path, const char *mode)
1167 {
1168     lldb_private::File file(path, GetOptionsFromMode(mode));
1169     Reset(file, mode);
1170 }
1171 
1172 PythonFile::PythonFile(PyRefType type, PyObject *o)
1173 {
1174     Reset(type, o);
1175 }
1176 
1177 PythonFile::~PythonFile()
1178 {
1179 }
1180 
1181 bool
1182 PythonFile::Check(PyObject *py_obj)
1183 {
1184 #if PY_MAJOR_VERSION < 3
1185     return PyFile_Check(py_obj);
1186 #else
1187     // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
1188     // first-class object type anymore.  `PyFile_FromFd` is just a thin wrapper
1189     // over `io.open()`, which returns some object derived from `io.IOBase`.
1190     // As a result, the only way to detect a file in Python 3 is to check whether
1191     // it inherits from `io.IOBase`.  Since it is possible for non-files to also
1192     // inherit from `io.IOBase`, we additionally verify that it has the `fileno`
1193     // attribute, which should guarantee that it is backed by the file system.
1194     PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
1195     PythonDictionary io_dict(PyRefType::Borrowed, PyModule_GetDict(io_module.get()));
1196     PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase"));
1197 
1198     PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj));
1199 
1200     if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get()))
1201         return false;
1202     if (!object_type.HasAttribute("fileno"))
1203         return false;
1204 
1205     return true;
1206 #endif
1207 }
1208 
1209 void
1210 PythonFile::Reset(PyRefType type, PyObject *py_obj)
1211 {
1212     // Grab the desired reference type so that if we end up rejecting
1213     // `py_obj` it still gets decremented if necessary.
1214     PythonObject result(type, py_obj);
1215 
1216     if (!PythonFile::Check(py_obj))
1217     {
1218         PythonObject::Reset();
1219         return;
1220     }
1221 
1222     // Calling PythonObject::Reset(const PythonObject&) will lead to stack
1223     // overflow since it calls back into the virtual implementation.
1224     PythonObject::Reset(PyRefType::Borrowed, result.get());
1225 }
1226 
1227 void
1228 PythonFile::Reset(File &file, const char *mode)
1229 {
1230     if (!file.IsValid())
1231     {
1232         Reset();
1233         return;
1234     }
1235 
1236     char *cmode = const_cast<char *>(mode);
1237 #if PY_MAJOR_VERSION >= 3
1238     Reset(PyRefType::Owned,
1239         PyFile_FromFd(file.GetDescriptor(), nullptr, cmode, -1, nullptr, "ignore", nullptr, 0));
1240 #else
1241     // Read through the Python source, doesn't seem to modify these strings
1242     Reset(PyRefType::Owned,
1243         PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, nullptr));
1244 #endif
1245 }
1246 
1247 uint32_t
1248 PythonFile::GetOptionsFromMode(llvm::StringRef mode)
1249 {
1250     if (mode.empty())
1251         return 0;
1252 
1253     return llvm::StringSwitch<uint32_t>(mode.str().c_str())
1254     .Case("r",   File::eOpenOptionRead)
1255     .Case("w",   File::eOpenOptionWrite)
1256     .Case("a",   File::eOpenOptionAppend|File::eOpenOptionCanCreate)
1257     .Case("r+",  File::eOpenOptionRead|File::eOpenOptionWrite)
1258     .Case("w+",  File::eOpenOptionRead|File::eOpenOptionWrite|File::eOpenOptionCanCreate|File::eOpenOptionTruncate)
1259     .Case("a+",  File::eOpenOptionRead|File::eOpenOptionWrite|File::eOpenOptionCanCreate)
1260     .Default(0);
1261 }
1262 
1263 bool
1264 PythonFile::GetUnderlyingFile(File &file) const
1265 {
1266     if (!IsValid())
1267         return false;
1268 
1269     file.Close();
1270     // We don't own the file descriptor returned by this function, make sure the
1271     // File object knows about that.
1272     file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
1273     PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
1274     file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString()));
1275     return file.IsValid();
1276 }
1277 
1278 
1279 #endif
1280