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