xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (revision b58fb2f47a4f792fed292b139c2b2a325ed3abb5)
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, 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 bool
829 PythonModule::Check(PyObject *py_obj)
830 {
831     if (!py_obj)
832         return false;
833 
834     return PyModule_Check(py_obj);
835 }
836 
837 void
838 PythonModule::Reset(PyRefType type, PyObject *py_obj)
839 {
840     // Grab the desired reference type so that if we end up rejecting
841     // `py_obj` it still gets decremented if necessary.
842     PythonObject result(type, py_obj);
843 
844     if (!PythonModule::Check(py_obj))
845     {
846         PythonObject::Reset();
847         return;
848     }
849 
850     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
851     // back into the virtual implementation.
852     PythonObject::Reset(PyRefType::Borrowed, result.get());
853 }
854 
855 PythonDictionary
856 PythonModule::GetDictionary() const
857 {
858     return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj));
859 }
860 
861 PythonCallable::PythonCallable() : PythonObject()
862 {
863 }
864 
865 PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj)
866 {
867     Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable
868 }
869 
870 PythonCallable::PythonCallable(const PythonCallable &callable)
871     : PythonObject(callable)
872 {
873 }
874 
875 PythonCallable::~PythonCallable()
876 {
877 }
878 
879 bool
880 PythonCallable::Check(PyObject *py_obj)
881 {
882     if (!py_obj)
883         return false;
884 
885     return PyCallable_Check(py_obj);
886 }
887 
888 void
889 PythonCallable::Reset(PyRefType type, PyObject *py_obj)
890 {
891     // Grab the desired reference type so that if we end up rejecting
892     // `py_obj` it still gets decremented if necessary.
893     PythonObject result(type, py_obj);
894 
895     if (!PythonCallable::Check(py_obj))
896     {
897         PythonObject::Reset();
898         return;
899     }
900 
901     // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
902     // back into the virtual implementation.
903     PythonObject::Reset(PyRefType::Borrowed, result.get());
904 }
905 
906 
907 PythonCallable::ArgInfo
908 PythonCallable::GetNumArguments() const
909 {
910     ArgInfo result = { 0, false, false };
911     if (!IsValid())
912         return result;
913 
914     PyObject *py_func_obj = m_py_obj;
915     if (PyMethod_Check(py_func_obj))
916         py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
917 
918     if (!py_func_obj)
919         return result;
920 
921     PyCodeObject* code = (PyCodeObject*)PyFunction_GET_CODE(py_func_obj);
922     if (!code)
923         return result;
924 
925     result.count = code->co_argcount;
926     result.has_varargs = !!(code->co_flags & CO_VARARGS);
927     result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS);
928     return result;
929 }
930 
931 PythonObject
932 PythonCallable::operator ()()
933 {
934     return PythonObject(PyRefType::Owned,
935         PyObject_CallObject(m_py_obj, nullptr));
936 }
937 
938 PythonObject
939 PythonCallable::operator ()(std::initializer_list<PyObject*> args)
940 {
941     PythonTuple arg_tuple(args);
942     return PythonObject(PyRefType::Owned,
943         PyObject_CallObject(m_py_obj, arg_tuple.get()));
944 }
945 
946 PythonObject
947 PythonCallable::operator ()(std::initializer_list<PythonObject> args)
948 {
949     PythonTuple arg_tuple(args);
950     return PythonObject(PyRefType::Owned,
951         PyObject_CallObject(m_py_obj, arg_tuple.get()));
952 }
953 
954 PythonFile::PythonFile()
955     : PythonObject()
956 {
957 }
958 
959 PythonFile::PythonFile(File &file, const char *mode)
960 {
961     Reset(file, mode);
962 }
963 
964 PythonFile::PythonFile(const char *path, const char *mode)
965 {
966     FILE *fp = nullptr;
967     fp = fopen(path, mode);
968     lldb_private::File file(fp, true);
969     Reset(file, mode);
970 }
971 
972 PythonFile::PythonFile(PyRefType type, PyObject *o)
973 {
974     Reset(type, o);
975 }
976 
977 PythonFile::~PythonFile()
978 {
979 }
980 
981 bool
982 PythonFile::Check(PyObject *py_obj)
983 {
984 #if PY_MAJOR_VERSION < 3
985     return PyFile_Check(py_obj);
986 #else
987     // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
988     // first-class object type anymore.  `PyFile_FromFd` is just a thin wrapper
989     // over `io.open()`, which returns some object derived from `io.IOBase`.
990     // As a result, the only way to detect a file in Python 3 is to check whether
991     // it inherits from `io.IOBase`.  Since it is possible for non-files to also
992     // inherit from `io.IOBase`, we additionally verify that it has the `fileno`
993     // attribute, which should guarantee that it is backed by the file system.
994     PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
995     PythonDictionary io_dict(PyRefType::Borrowed, PyModule_GetDict(io_module.get()));
996     PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase"));
997 
998     PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj));
999 
1000     if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get()))
1001         return false;
1002     if (!object_type.HasAttribute("fileno"))
1003         return false;
1004 
1005     return true;
1006 #endif
1007 }
1008 
1009 void
1010 PythonFile::Reset(PyRefType type, PyObject *py_obj)
1011 {
1012     // Grab the desired reference type so that if we end up rejecting
1013     // `py_obj` it still gets decremented if necessary.
1014     PythonObject result(type, py_obj);
1015 
1016     if (!PythonFile::Check(py_obj))
1017     {
1018         PythonObject::Reset();
1019         return;
1020     }
1021 
1022     // Calling PythonObject::Reset(const PythonObject&) will lead to stack
1023     // overflow since it calls back into the virtual implementation.
1024     PythonObject::Reset(PyRefType::Borrowed, result.get());
1025 }
1026 
1027 void
1028 PythonFile::Reset(File &file, const char *mode)
1029 {
1030     char *cmode = const_cast<char *>(mode);
1031 #if PY_MAJOR_VERSION >= 3
1032     Reset(PyRefType::Owned,
1033         PyFile_FromFd(file.GetDescriptor(), nullptr, cmode, -1, nullptr, "ignore", nullptr, 0));
1034 #else
1035     // Read through the Python source, doesn't seem to modify these strings
1036     Reset(PyRefType::Owned,
1037         PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, nullptr));
1038 #endif
1039 }
1040 
1041 bool
1042 PythonFile::GetUnderlyingFile(File &file) const
1043 {
1044     if (!IsValid())
1045         return false;
1046 
1047     file.Close();
1048     // We don't own the file descriptor returned by this function, make sure the
1049     // File object knows about that.
1050     file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
1051     return file.IsValid();
1052 }
1053 
1054 
1055 #endif
1056