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