xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (revision 722b61892454b3217d73ec486e52156c5a92b5b3)
1 //===-- PythonDataObjects.cpp -----------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifdef LLDB_DISABLE_PYTHON
10 
11 // Python is disabled in this build
12 
13 #else
14 
15 #include "PythonDataObjects.h"
16 #include "ScriptInterpreterPython.h"
17 
18 #include "lldb/Host/File.h"
19 #include "lldb/Host/FileSystem.h"
20 #include "lldb/Interpreter/ScriptInterpreter.h"
21 #include "lldb/Utility/Log.h"
22 #include "lldb/Utility/Stream.h"
23 
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/ConvertUTF.h"
27 #include "llvm/Support/Errno.h"
28 
29 #include <stdio.h>
30 
31 using namespace lldb_private;
32 using namespace lldb;
33 using namespace lldb_private::python;
34 using llvm::cantFail;
35 using llvm::Error;
36 using llvm::Expected;
37 using llvm::Twine;
38 
39 template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) {
40   if (!obj)
41     return obj.takeError();
42   return obj.get().IsTrue();
43 }
44 
45 template <>
46 Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
47   if (!obj)
48     return obj.takeError();
49   return obj.get().AsLongLong();
50 }
51 
52 template <>
53 Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
54   if (!obj)
55     return obj.takeError();
56   PyObject *str_obj = PyObject_Str(obj.get().get());
57   if (!obj)
58     return llvm::make_error<PythonException>();
59   auto str = Take<PythonString>(str_obj);
60   auto utf8 = str.AsUTF8();
61   if (!utf8)
62     return utf8.takeError();
63   return utf8.get();
64 }
65 
66 void StructuredPythonObject::Serialize(llvm::json::OStream &s) const {
67   s.value(llvm::formatv("Python Obj: {0:X}", GetValue()).str());
68 }
69 
70 // PythonObject
71 
72 void PythonObject::Dump(Stream &strm) const {
73   if (m_py_obj) {
74     FILE *file = llvm::sys::RetryAfterSignal(nullptr, ::tmpfile);
75     if (file) {
76       ::PyObject_Print(m_py_obj, file, 0);
77       const long length = ftell(file);
78       if (length) {
79         ::rewind(file);
80         std::vector<char> file_contents(length, '\0');
81         const size_t length_read =
82             ::fread(file_contents.data(), 1, file_contents.size(), file);
83         if (length_read > 0)
84           strm.Write(file_contents.data(), length_read);
85       }
86       ::fclose(file);
87     }
88   } else
89     strm.PutCString("NULL");
90 }
91 
92 PyObjectType PythonObject::GetObjectType() const {
93   if (!IsAllocated())
94     return PyObjectType::None;
95 
96   if (PythonModule::Check(m_py_obj))
97     return PyObjectType::Module;
98   if (PythonList::Check(m_py_obj))
99     return PyObjectType::List;
100   if (PythonTuple::Check(m_py_obj))
101     return PyObjectType::Tuple;
102   if (PythonDictionary::Check(m_py_obj))
103     return PyObjectType::Dictionary;
104   if (PythonString::Check(m_py_obj))
105     return PyObjectType::String;
106 #if PY_MAJOR_VERSION >= 3
107   if (PythonBytes::Check(m_py_obj))
108     return PyObjectType::Bytes;
109 #endif
110   if (PythonByteArray::Check(m_py_obj))
111     return PyObjectType::ByteArray;
112   if (PythonBoolean::Check(m_py_obj))
113     return PyObjectType::Boolean;
114   if (PythonInteger::Check(m_py_obj))
115     return PyObjectType::Integer;
116   if (PythonFile::Check(m_py_obj))
117     return PyObjectType::File;
118   if (PythonCallable::Check(m_py_obj))
119     return PyObjectType::Callable;
120   return PyObjectType::Unknown;
121 }
122 
123 PythonString PythonObject::Repr() const {
124   if (!m_py_obj)
125     return PythonString();
126   PyObject *repr = PyObject_Repr(m_py_obj);
127   if (!repr)
128     return PythonString();
129   return PythonString(PyRefType::Owned, repr);
130 }
131 
132 PythonString PythonObject::Str() const {
133   if (!m_py_obj)
134     return PythonString();
135   PyObject *str = PyObject_Str(m_py_obj);
136   if (!str)
137     return PythonString();
138   return PythonString(PyRefType::Owned, str);
139 }
140 
141 PythonObject
142 PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
143                                         const PythonDictionary &dict) {
144   size_t dot_pos = name.find('.');
145   llvm::StringRef piece = name.substr(0, dot_pos);
146   PythonObject result = dict.GetItemForKey(PythonString(piece));
147   if (dot_pos == llvm::StringRef::npos) {
148     // There was no dot, we're done.
149     return result;
150   }
151 
152   // There was a dot.  The remaining portion of the name should be looked up in
153   // the context of the object that was found in the dictionary.
154   return result.ResolveName(name.substr(dot_pos + 1));
155 }
156 
157 PythonObject PythonObject::ResolveName(llvm::StringRef name) const {
158   // Resolve the name in the context of the specified object.  If, for example,
159   // `this` refers to a PyModule, then this will look for `name` in this
160   // module.  If `this` refers to a PyType, then it will resolve `name` as an
161   // attribute of that type.  If `this` refers to an instance of an object,
162   // then it will resolve `name` as the value of the specified field.
163   //
164   // This function handles dotted names so that, for example, if `m_py_obj`
165   // refers to the `sys` module, and `name` == "path.append", then it will find
166   // the function `sys.path.append`.
167 
168   size_t dot_pos = name.find('.');
169   if (dot_pos == llvm::StringRef::npos) {
170     // No dots in the name, we should be able to find the value immediately as
171     // an attribute of `m_py_obj`.
172     return GetAttributeValue(name);
173   }
174 
175   // Look up the first piece of the name, and resolve the rest as a child of
176   // that.
177   PythonObject parent = ResolveName(name.substr(0, dot_pos));
178   if (!parent.IsAllocated())
179     return PythonObject();
180 
181   // Tail recursion.. should be optimized by the compiler
182   return parent.ResolveName(name.substr(dot_pos + 1));
183 }
184 
185 bool PythonObject::HasAttribute(llvm::StringRef attr) const {
186   if (!IsValid())
187     return false;
188   PythonString py_attr(attr);
189   return !!PyObject_HasAttr(m_py_obj, py_attr.get());
190 }
191 
192 PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
193   if (!IsValid())
194     return PythonObject();
195 
196   PythonString py_attr(attr);
197   if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
198     return PythonObject();
199 
200   return PythonObject(PyRefType::Owned,
201                       PyObject_GetAttr(m_py_obj, py_attr.get()));
202 }
203 
204 StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
205   switch (GetObjectType()) {
206   case PyObjectType::Dictionary:
207     return PythonDictionary(PyRefType::Borrowed, m_py_obj)
208         .CreateStructuredDictionary();
209   case PyObjectType::Boolean:
210     return PythonBoolean(PyRefType::Borrowed, m_py_obj)
211         .CreateStructuredBoolean();
212   case PyObjectType::Integer:
213     return PythonInteger(PyRefType::Borrowed, m_py_obj)
214         .CreateStructuredInteger();
215   case PyObjectType::List:
216     return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
217   case PyObjectType::String:
218     return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
219   case PyObjectType::Bytes:
220     return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
221   case PyObjectType::ByteArray:
222     return PythonByteArray(PyRefType::Borrowed, m_py_obj)
223         .CreateStructuredString();
224   case PyObjectType::None:
225     return StructuredData::ObjectSP();
226   default:
227     return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
228   }
229 }
230 
231 // PythonString
232 
233 PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
234 
235 PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) {
236   SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
237 }
238 
239 bool PythonBytes::Check(PyObject *py_obj) {
240   if (!py_obj)
241     return false;
242   return PyBytes_Check(py_obj);
243 }
244 
245 llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
246   if (!IsValid())
247     return llvm::ArrayRef<uint8_t>();
248 
249   Py_ssize_t size;
250   char *c;
251 
252   PyBytes_AsStringAndSize(m_py_obj, &c, &size);
253   return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
254 }
255 
256 size_t PythonBytes::GetSize() const {
257   if (!IsValid())
258     return 0;
259   return PyBytes_Size(m_py_obj);
260 }
261 
262 void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
263   const char *data = reinterpret_cast<const char *>(bytes.data());
264   PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
265   PythonObject::Reset(PyRefType::Owned, py_bytes);
266 }
267 
268 StructuredData::StringSP PythonBytes::CreateStructuredString() const {
269   StructuredData::StringSP result(new StructuredData::String);
270   Py_ssize_t size;
271   char *c;
272   PyBytes_AsStringAndSize(m_py_obj, &c, &size);
273   result->SetValue(std::string(c, size));
274   return result;
275 }
276 
277 PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
278     : PythonByteArray(bytes.data(), bytes.size()) {}
279 
280 PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
281   const char *str = reinterpret_cast<const char *>(bytes);
282   *this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length));
283 }
284 
285 bool PythonByteArray::Check(PyObject *py_obj) {
286   if (!py_obj)
287     return false;
288   return PyByteArray_Check(py_obj);
289 }
290 
291 llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
292   if (!IsValid())
293     return llvm::ArrayRef<uint8_t>();
294 
295   char *c = PyByteArray_AsString(m_py_obj);
296   size_t size = GetSize();
297   return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
298 }
299 
300 size_t PythonByteArray::GetSize() const {
301   if (!IsValid())
302     return 0;
303 
304   return PyByteArray_Size(m_py_obj);
305 }
306 
307 StructuredData::StringSP PythonByteArray::CreateStructuredString() const {
308   StructuredData::StringSP result(new StructuredData::String);
309   llvm::ArrayRef<uint8_t> bytes = GetBytes();
310   const char *str = reinterpret_cast<const char *>(bytes.data());
311   result->SetValue(std::string(str, bytes.size()));
312   return result;
313 }
314 
315 // PythonString
316 
317 Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) {
318 #if PY_MAJOR_VERSION >= 3
319   PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size());
320 #else
321   PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
322 #endif
323   if (!str)
324     return llvm::make_error<PythonException>();
325   return Take<PythonString>(str);
326 }
327 
328 PythonString::PythonString(llvm::StringRef string) { SetString(string); }
329 
330 bool PythonString::Check(PyObject *py_obj) {
331   if (!py_obj)
332     return false;
333 
334   if (PyUnicode_Check(py_obj))
335     return true;
336 #if PY_MAJOR_VERSION < 3
337   if (PyString_Check(py_obj))
338     return true;
339 #endif
340   return false;
341 }
342 
343 void PythonString::Convert(PyRefType &type, PyObject *&py_obj) {
344 #if PY_MAJOR_VERSION < 3
345   // In Python 2, Don't store PyUnicode objects directly, because we need
346   // access to their underlying character buffers which Python 2 doesn't
347   // provide.
348   if (PyUnicode_Check(py_obj)) {
349     PyObject *s = PyUnicode_AsUTF8String(py_obj);
350     if (s == nullptr) {
351       PyErr_Clear();
352       if (type == PyRefType::Owned)
353         Py_DECREF(py_obj);
354       return;
355     }
356     if (type == PyRefType::Owned)
357       Py_DECREF(py_obj);
358     else
359       type = PyRefType::Owned;
360     py_obj = s;
361   }
362 #endif
363 }
364 
365 llvm::StringRef PythonString::GetString() const {
366   auto s = AsUTF8();
367   if (!s) {
368     llvm::consumeError(s.takeError());
369     return llvm::StringRef("");
370   }
371   return s.get();
372 }
373 
374 Expected<llvm::StringRef> PythonString::AsUTF8() const {
375   if (!IsValid())
376     return nullDeref();
377 
378   Py_ssize_t size;
379   const char *data;
380 
381 #if PY_MAJOR_VERSION >= 3
382   data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
383 #else
384   char *c = NULL;
385   int r = PyString_AsStringAndSize(m_py_obj, &c, &size);
386   if (r < 0)
387     c = NULL;
388   data = c;
389 #endif
390 
391   if (!data)
392     return exception();
393 
394   return llvm::StringRef(data, size);
395 }
396 
397 size_t PythonString::GetSize() const {
398   if (IsValid()) {
399 #if PY_MAJOR_VERSION >= 3
400     return PyUnicode_GetSize(m_py_obj);
401 #else
402     return PyString_Size(m_py_obj);
403 #endif
404   }
405   return 0;
406 }
407 
408 void PythonString::SetString(llvm::StringRef string) {
409   auto s = FromUTF8(string);
410   if (!s) {
411     llvm::consumeError(s.takeError());
412     Reset();
413   } else {
414     *this = std::move(s.get());
415   }
416 }
417 
418 StructuredData::StringSP PythonString::CreateStructuredString() const {
419   StructuredData::StringSP result(new StructuredData::String);
420   result->SetValue(GetString());
421   return result;
422 }
423 
424 // PythonInteger
425 
426 PythonInteger::PythonInteger(int64_t value) { SetInteger(value); }
427 
428 bool PythonInteger::Check(PyObject *py_obj) {
429   if (!py_obj)
430     return false;
431 
432 #if PY_MAJOR_VERSION >= 3
433   // Python 3 does not have PyInt_Check.  There is only one type of integral
434   // value, long.
435   return PyLong_Check(py_obj);
436 #else
437   return PyLong_Check(py_obj) || PyInt_Check(py_obj);
438 #endif
439 }
440 
441 void PythonInteger::Convert(PyRefType &type, PyObject *&py_obj) {
442 #if PY_MAJOR_VERSION < 3
443   // Always store this as a PyLong, which makes interoperability between Python
444   // 2.x and Python 3.x easier.  This is only necessary in 2.x, since 3.x
445   // doesn't even have a PyInt.
446   if (PyInt_Check(py_obj)) {
447     // Since we converted the original object to a different type, the new
448     // object is an owned object regardless of the ownership semantics
449     // requested by the user.
450     long long value = PyInt_AsLong(py_obj);
451     PyObject *l = nullptr;
452     if (!PyErr_Occurred())
453       l = PyLong_FromLongLong(value);
454     if (l == nullptr) {
455       PyErr_Clear();
456       if (type == PyRefType::Owned)
457         Py_DECREF(py_obj);
458       return;
459     }
460     if (type == PyRefType::Owned)
461       Py_DECREF(py_obj);
462     else
463       type = PyRefType::Owned;
464     py_obj = l;
465   }
466 #endif
467 }
468 
469 int64_t PythonInteger::GetInteger() const {
470   if (m_py_obj) {
471     assert(PyLong_Check(m_py_obj) &&
472            "PythonInteger::GetInteger has a PyObject that isn't a PyLong");
473 
474     int overflow = 0;
475     int64_t result = PyLong_AsLongLongAndOverflow(m_py_obj, &overflow);
476     if (overflow != 0) {
477       // We got an integer that overflows, like 18446744072853913392L we can't
478       // use PyLong_AsLongLong() as it will return 0xffffffffffffffff. If we
479       // use the unsigned long long it will work as expected.
480       const uint64_t uval = PyLong_AsUnsignedLongLong(m_py_obj);
481       result = static_cast<int64_t>(uval);
482     }
483     return result;
484   }
485   return UINT64_MAX;
486 }
487 
488 void PythonInteger::SetInteger(int64_t value) {
489   PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
490 }
491 
492 StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
493   StructuredData::IntegerSP result(new StructuredData::Integer);
494   result->SetValue(GetInteger());
495   return result;
496 }
497 
498 // PythonBoolean
499 
500 PythonBoolean::PythonBoolean(bool value) {
501   SetValue(value);
502 }
503 
504 bool PythonBoolean::Check(PyObject *py_obj) {
505   return py_obj ? PyBool_Check(py_obj) : false;
506 }
507 
508 bool PythonBoolean::GetValue() const {
509   return m_py_obj ? PyObject_IsTrue(m_py_obj) : false;
510 }
511 
512 void PythonBoolean::SetValue(bool value) {
513   PythonObject::Reset(PyRefType::Owned, PyBool_FromLong(value));
514 }
515 
516 StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const {
517   StructuredData::BooleanSP result(new StructuredData::Boolean);
518   result->SetValue(GetValue());
519   return result;
520 }
521 
522 // PythonList
523 
524 PythonList::PythonList(PyInitialValue value) {
525   if (value == PyInitialValue::Empty)
526     *this = Take<PythonList>(PyList_New(0));
527 }
528 
529 PythonList::PythonList(int list_size) {
530   *this = Take<PythonList>(PyList_New(list_size));
531 }
532 
533 bool PythonList::Check(PyObject *py_obj) {
534   if (!py_obj)
535     return false;
536   return PyList_Check(py_obj);
537 }
538 
539 uint32_t PythonList::GetSize() const {
540   if (IsValid())
541     return PyList_GET_SIZE(m_py_obj);
542   return 0;
543 }
544 
545 PythonObject PythonList::GetItemAtIndex(uint32_t index) const {
546   if (IsValid())
547     return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
548   return PythonObject();
549 }
550 
551 void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) {
552   if (IsAllocated() && object.IsValid()) {
553     // PyList_SetItem is documented to "steal" a reference, so we need to
554     // convert it to an owned reference by incrementing it.
555     Py_INCREF(object.get());
556     PyList_SetItem(m_py_obj, index, object.get());
557   }
558 }
559 
560 void PythonList::AppendItem(const PythonObject &object) {
561   if (IsAllocated() && object.IsValid()) {
562     // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
563     // here like we do with `PyList_SetItem`.
564     PyList_Append(m_py_obj, object.get());
565   }
566 }
567 
568 StructuredData::ArraySP PythonList::CreateStructuredArray() const {
569   StructuredData::ArraySP result(new StructuredData::Array);
570   uint32_t count = GetSize();
571   for (uint32_t i = 0; i < count; ++i) {
572     PythonObject obj = GetItemAtIndex(i);
573     result->AddItem(obj.CreateStructuredObject());
574   }
575   return result;
576 }
577 
578 // PythonTuple
579 
580 PythonTuple::PythonTuple(PyInitialValue value) {
581   if (value == PyInitialValue::Empty)
582     *this = Take<PythonTuple>(PyTuple_New(0));
583 }
584 
585 PythonTuple::PythonTuple(int tuple_size) {
586   *this = Take<PythonTuple>(PyTuple_New(tuple_size));
587 }
588 
589 PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
590   m_py_obj = PyTuple_New(objects.size());
591 
592   uint32_t idx = 0;
593   for (auto object : objects) {
594     if (object.IsValid())
595       SetItemAtIndex(idx, object);
596     idx++;
597   }
598 }
599 
600 PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
601   m_py_obj = PyTuple_New(objects.size());
602 
603   uint32_t idx = 0;
604   for (auto py_object : objects) {
605     PythonObject object(PyRefType::Borrowed, py_object);
606     if (object.IsValid())
607       SetItemAtIndex(idx, object);
608     idx++;
609   }
610 }
611 
612 bool PythonTuple::Check(PyObject *py_obj) {
613   if (!py_obj)
614     return false;
615   return PyTuple_Check(py_obj);
616 }
617 
618 uint32_t PythonTuple::GetSize() const {
619   if (IsValid())
620     return PyTuple_GET_SIZE(m_py_obj);
621   return 0;
622 }
623 
624 PythonObject PythonTuple::GetItemAtIndex(uint32_t index) const {
625   if (IsValid())
626     return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
627   return PythonObject();
628 }
629 
630 void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) {
631   if (IsAllocated() && object.IsValid()) {
632     // PyTuple_SetItem is documented to "steal" a reference, so we need to
633     // convert it to an owned reference by incrementing it.
634     Py_INCREF(object.get());
635     PyTuple_SetItem(m_py_obj, index, object.get());
636   }
637 }
638 
639 StructuredData::ArraySP PythonTuple::CreateStructuredArray() const {
640   StructuredData::ArraySP result(new StructuredData::Array);
641   uint32_t count = GetSize();
642   for (uint32_t i = 0; i < count; ++i) {
643     PythonObject obj = GetItemAtIndex(i);
644     result->AddItem(obj.CreateStructuredObject());
645   }
646   return result;
647 }
648 
649 // PythonDictionary
650 
651 PythonDictionary::PythonDictionary(PyInitialValue value) {
652   if (value == PyInitialValue::Empty)
653     *this = Take<PythonDictionary>(PyDict_New());
654 }
655 
656 bool PythonDictionary::Check(PyObject *py_obj) {
657   if (!py_obj)
658     return false;
659 
660   return PyDict_Check(py_obj);
661 }
662 
663 uint32_t PythonDictionary::GetSize() const {
664   if (IsValid())
665     return PyDict_Size(m_py_obj);
666   return 0;
667 }
668 
669 PythonList PythonDictionary::GetKeys() const {
670   if (IsValid())
671     return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
672   return PythonList(PyInitialValue::Invalid);
673 }
674 
675 PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const {
676   auto item = GetItem(key);
677   if (!item) {
678     llvm::consumeError(item.takeError());
679     return PythonObject();
680   }
681   return std::move(item.get());
682 }
683 
684 Expected<PythonObject>
685 PythonDictionary::GetItem(const PythonObject &key) const {
686   if (!IsValid())
687     return nullDeref();
688 #if PY_MAJOR_VERSION >= 3
689   PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
690   if (PyErr_Occurred())
691     return exception();
692 #else
693   PyObject *o = PyDict_GetItem(m_py_obj, key.get());
694 #endif
695   if (!o)
696     return keyError();
697   return Retain<PythonObject>(o);
698 }
699 
700 Expected<PythonObject> PythonDictionary::GetItem(const Twine &key) const {
701   if (!IsValid())
702     return nullDeref();
703   PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
704   if (PyErr_Occurred())
705     return exception();
706   if (!o)
707     return keyError();
708   return Retain<PythonObject>(o);
709 }
710 
711 Error PythonDictionary::SetItem(const PythonObject &key,
712                                 const PythonObject &value) const {
713   if (!IsValid() || !value.IsValid())
714     return nullDeref();
715   int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
716   if (r < 0)
717     return exception();
718   return Error::success();
719 }
720 
721 Error PythonDictionary::SetItem(const Twine &key,
722                                 const PythonObject &value) const {
723   if (!IsValid() || !value.IsValid())
724     return nullDeref();
725   int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
726   if (r < 0)
727     return exception();
728   return Error::success();
729 }
730 
731 void PythonDictionary::SetItemForKey(const PythonObject &key,
732                                      const PythonObject &value) {
733   Error error = SetItem(key, value);
734   if (error)
735     llvm::consumeError(std::move(error));
736 }
737 
738 StructuredData::DictionarySP
739 PythonDictionary::CreateStructuredDictionary() const {
740   StructuredData::DictionarySP result(new StructuredData::Dictionary);
741   PythonList keys(GetKeys());
742   uint32_t num_keys = keys.GetSize();
743   for (uint32_t i = 0; i < num_keys; ++i) {
744     PythonObject key = keys.GetItemAtIndex(i);
745     PythonObject value = GetItemForKey(key);
746     StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
747     result->AddItem(key.Str().GetString(), structured_value);
748   }
749   return result;
750 }
751 
752 PythonModule PythonModule::BuiltinsModule() {
753 #if PY_MAJOR_VERSION >= 3
754   return AddModule("builtins");
755 #else
756   return AddModule("__builtin__");
757 #endif
758 }
759 
760 PythonModule PythonModule::MainModule() { return AddModule("__main__"); }
761 
762 PythonModule PythonModule::AddModule(llvm::StringRef module) {
763   std::string str = module.str();
764   return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
765 }
766 
767 Expected<PythonModule> PythonModule::Import(const Twine &name) {
768   PyObject *mod = PyImport_ImportModule(NullTerminated(name));
769   if (!mod)
770     return exception();
771   return Take<PythonModule>(mod);
772 }
773 
774 Expected<PythonObject> PythonModule::Get(const Twine &name) {
775   if (!IsValid())
776     return nullDeref();
777   PyObject *dict = PyModule_GetDict(m_py_obj);
778   if (!dict)
779     return exception();
780   PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
781   if (!item)
782     return exception();
783   return Retain<PythonObject>(item);
784 }
785 
786 bool PythonModule::Check(PyObject *py_obj) {
787   if (!py_obj)
788     return false;
789 
790   return PyModule_Check(py_obj);
791 }
792 
793 PythonDictionary PythonModule::GetDictionary() const {
794   if (!IsValid())
795     return PythonDictionary();
796   return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
797 }
798 
799 bool PythonCallable::Check(PyObject *py_obj) {
800   if (!py_obj)
801     return false;
802 
803   return PyCallable_Check(py_obj);
804 }
805 
806 PythonCallable::ArgInfo PythonCallable::GetNumInitArguments() const {
807   auto arginfo = GetInitArgInfo();
808   if (!arginfo) {
809     llvm::consumeError(arginfo.takeError());
810     return ArgInfo{};
811   }
812   return arginfo.get();
813 }
814 
815 Expected<PythonCallable::ArgInfo> PythonCallable::GetInitArgInfo() const {
816   if (!IsValid())
817     return nullDeref();
818   auto init = As<PythonCallable>(GetAttribute("__init__"));
819   if (!init)
820     return init.takeError();
821   return init.get().GetArgInfo();
822 }
823 
824 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
825 static const char get_arg_info_script[] = R"(
826 from inspect import signature, Parameter, ismethod
827 from collections import namedtuple
828 ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs', 'is_bound_method'])
829 def get_arg_info(f):
830     count = 0
831     varargs = False
832     for parameter in signature(f).parameters.values():
833         kind = parameter.kind
834         if kind in (Parameter.POSITIONAL_ONLY,
835                     Parameter.POSITIONAL_OR_KEYWORD):
836             count += 1
837         elif kind == Parameter.VAR_POSITIONAL:
838             varargs = True
839         elif kind in (Parameter.KEYWORD_ONLY,
840                       Parameter.VAR_KEYWORD):
841             pass
842         else:
843             raise Exception(f'unknown parameter kind: {kind}')
844     return ArgInfo(count, varargs, ismethod(f))
845 )";
846 #endif
847 
848 Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
849   ArgInfo result = {};
850   if (!IsValid())
851     return nullDeref();
852 
853 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
854 
855   // this global is protected by the GIL
856   static PythonCallable get_arg_info;
857 
858   if (!get_arg_info.IsValid()) {
859     PythonDictionary globals(PyInitialValue::Empty);
860 
861     auto builtins = PythonModule::BuiltinsModule();
862     Error error = globals.SetItem("__builtins__", builtins);
863     if (error)
864       return std::move(error);
865     PyObject *o = PyRun_String(get_arg_info_script, Py_file_input,
866                                globals.get(), globals.get());
867     if (!o)
868       return exception();
869     Take<PythonObject>(o);
870     auto function = As<PythonCallable>(globals.GetItem("get_arg_info"));
871     if (!function)
872       return function.takeError();
873     get_arg_info = std::move(function.get());
874   }
875 
876   Expected<PythonObject> pyarginfo = get_arg_info.Call(*this);
877   if (!pyarginfo)
878     return pyarginfo.takeError();
879   result.count = cantFail(As<long long>(pyarginfo.get().GetAttribute("count")));
880   result.has_varargs =
881       cantFail(As<bool>(pyarginfo.get().GetAttribute("has_varargs")));
882   bool is_method =
883       cantFail(As<bool>(pyarginfo.get().GetAttribute("is_bound_method")));
884   result.max_positional_args =
885       result.has_varargs ? ArgInfo::UNBOUNDED : result.count;
886 
887   // FIXME emulate old broken behavior
888   if (is_method)
889     result.count++;
890 
891 #else
892   bool is_bound_method = false;
893   PyObject *py_func_obj = m_py_obj;
894   if (PyMethod_Check(py_func_obj)) {
895     py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
896     PythonObject im_self = GetAttributeValue("im_self");
897     if (im_self.IsValid() && !im_self.IsNone())
898       is_bound_method = true;
899   } else {
900     // see if this is a callable object with an __call__ method
901     if (!PyFunction_Check(py_func_obj)) {
902       PythonObject __call__ = GetAttributeValue("__call__");
903       if (__call__.IsValid()) {
904         auto __callable__ = __call__.AsType<PythonCallable>();
905         if (__callable__.IsValid()) {
906           py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
907           PythonObject im_self = __callable__.GetAttributeValue("im_self");
908           if (im_self.IsValid() && !im_self.IsNone())
909             is_bound_method = true;
910         }
911       }
912     }
913   }
914 
915   if (!py_func_obj)
916     return result;
917 
918   PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj);
919   if (!code)
920     return result;
921 
922   result.count = code->co_argcount;
923   result.has_varargs = !!(code->co_flags & CO_VARARGS);
924   result.max_positional_args = result.has_varargs
925                                    ? ArgInfo::UNBOUNDED
926                                    : (result.count - (int)is_bound_method);
927 
928 #endif
929 
930   return result;
931 }
932 
933 constexpr unsigned
934     PythonCallable::ArgInfo::UNBOUNDED; // FIXME delete after c++17
935 
936 PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
937   auto arginfo = GetArgInfo();
938   if (!arginfo) {
939     llvm::consumeError(arginfo.takeError());
940     return ArgInfo{};
941   }
942   return arginfo.get();
943 }
944 
945 PythonObject PythonCallable::operator()() {
946   return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
947 }
948 
949 PythonObject PythonCallable::
950 operator()(std::initializer_list<PyObject *> args) {
951   PythonTuple arg_tuple(args);
952   return PythonObject(PyRefType::Owned,
953                       PyObject_CallObject(m_py_obj, arg_tuple.get()));
954 }
955 
956 PythonObject PythonCallable::
957 operator()(std::initializer_list<PythonObject> args) {
958   PythonTuple arg_tuple(args);
959   return PythonObject(PyRefType::Owned,
960                       PyObject_CallObject(m_py_obj, arg_tuple.get()));
961 }
962 
963 bool PythonFile::Check(PyObject *py_obj) {
964   if (!py_obj)
965     return false;
966 #if PY_MAJOR_VERSION < 3
967   return PyFile_Check(py_obj);
968 #else
969   // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
970   // first-class object type anymore.  `PyFile_FromFd` is just a thin wrapper
971   // over `io.open()`, which returns some object derived from `io.IOBase`. As a
972   // result, the only way to detect a file in Python 3 is to check whether it
973   // inherits from `io.IOBase`.
974   auto io_module = PythonModule::Import("io");
975   if (!io_module) {
976     llvm::consumeError(io_module.takeError());
977     return false;
978   }
979   auto iobase = io_module.get().Get("IOBase");
980   if (!iobase) {
981     llvm::consumeError(iobase.takeError());
982     return false;
983   }
984   int r = PyObject_IsInstance(py_obj, iobase.get().get());
985   if (r < 0) {
986     llvm::consumeError(exception()); // clear the exception and log it.
987     return false;
988   }
989   return !!r;
990 #endif
991 }
992 
993 namespace {
994 class GIL {
995 public:
996   GIL() {
997     m_state = PyGILState_Ensure();
998     assert(!PyErr_Occurred());
999   }
1000   ~GIL() { PyGILState_Release(m_state); }
1001 
1002 protected:
1003   PyGILState_STATE m_state;
1004 };
1005 } // namespace
1006 
1007 const char *PythonException::toCString() const {
1008   if (!m_repr_bytes)
1009     return "unknown exception";
1010   return PyBytes_AS_STRING(m_repr_bytes);
1011 }
1012 
1013 PythonException::PythonException(const char *caller) {
1014   assert(PyErr_Occurred());
1015   m_exception_type = m_exception = m_traceback = m_repr_bytes = NULL;
1016   PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
1017   PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
1018   PyErr_Clear();
1019   if (m_exception) {
1020     PyObject *repr = PyObject_Repr(m_exception);
1021     if (repr) {
1022       m_repr_bytes = PyUnicode_AsEncodedString(repr, "utf-8", nullptr);
1023       if (!m_repr_bytes) {
1024         PyErr_Clear();
1025       }
1026       Py_XDECREF(repr);
1027     } else {
1028       PyErr_Clear();
1029     }
1030   }
1031   Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT);
1032   if (caller)
1033     LLDB_LOGF(log, "%s failed with exception: %s", caller, toCString());
1034   else
1035     LLDB_LOGF(log, "python exception: %s", toCString());
1036 }
1037 void PythonException::Restore() {
1038   if (m_exception_type && m_exception) {
1039     PyErr_Restore(m_exception_type, m_exception, m_traceback);
1040   } else {
1041     PyErr_SetString(PyExc_Exception, toCString());
1042   }
1043   m_exception_type = m_exception = m_traceback = NULL;
1044 }
1045 
1046 PythonException::~PythonException() {
1047   Py_XDECREF(m_exception_type);
1048   Py_XDECREF(m_exception);
1049   Py_XDECREF(m_traceback);
1050   Py_XDECREF(m_repr_bytes);
1051 }
1052 
1053 void PythonException::log(llvm::raw_ostream &OS) const { OS << toCString(); }
1054 
1055 std::error_code PythonException::convertToErrorCode() const {
1056   return llvm::inconvertibleErrorCode();
1057 }
1058 
1059 char PythonException::ID = 0;
1060 
1061 llvm::Expected<File::OpenOptions>
1062 GetOptionsForPyObject(const PythonObject &obj) {
1063 #if PY_MAJOR_VERSION >= 3
1064   auto options = File::OpenOptions(0);
1065   auto readable = As<bool>(obj.CallMethod("readable"));
1066   if (!readable)
1067     return readable.takeError();
1068   auto writable = As<bool>(obj.CallMethod("writable"));
1069   if (!writable)
1070     return writable.takeError();
1071   if (readable.get())
1072     options |= File::eOpenOptionRead;
1073   if (writable.get())
1074     options |= File::eOpenOptionWrite;
1075   return options;
1076 #else
1077   PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>();
1078   return File::GetOptionsFromMode(py_mode.GetString());
1079 #endif
1080 }
1081 
1082 // Base class template for python files.   All it knows how to do
1083 // is hold a reference to the python object and close or flush it
1084 // when the File is closed.
1085 namespace {
1086 template <typename Base> class OwnedPythonFile : public Base {
1087 public:
1088   template <typename... Args>
1089   OwnedPythonFile(const PythonFile &file, bool borrowed, Args... args)
1090       : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1091     assert(m_py_obj);
1092   }
1093 
1094   ~OwnedPythonFile() override {
1095     assert(m_py_obj);
1096     GIL takeGIL;
1097     Close();
1098     // we need to ensure the python object is released while we still
1099     // hold the GIL
1100     m_py_obj.Reset();
1101   }
1102 
1103   bool IsPythonSideValid() const {
1104     GIL takeGIL;
1105     auto closed = As<bool>(m_py_obj.GetAttribute("closed"));
1106     if (!closed) {
1107       llvm::consumeError(closed.takeError());
1108       return false;
1109     }
1110     return !closed.get();
1111   }
1112 
1113   bool IsValid() const override {
1114     return IsPythonSideValid() && Base::IsValid();
1115   }
1116 
1117   Status Close() override {
1118     assert(m_py_obj);
1119     Status py_error, base_error;
1120     GIL takeGIL;
1121     if (!m_borrowed) {
1122       auto r = m_py_obj.CallMethod("close");
1123       if (!r)
1124         py_error = Status(r.takeError());
1125     }
1126     base_error = Base::Close();
1127     if (py_error.Fail())
1128       return py_error;
1129     return base_error;
1130   };
1131 
1132   PyObject *GetPythonObject() const {
1133     assert(m_py_obj.IsValid());
1134     return m_py_obj.get();
1135   }
1136 
1137   static bool classof(const File *file) = delete;
1138 
1139 protected:
1140   PythonFile m_py_obj;
1141   bool m_borrowed;
1142 };
1143 } // namespace
1144 
1145 // A SimplePythonFile is a OwnedPythonFile that just does all I/O as
1146 // a NativeFile
1147 namespace {
1148 class SimplePythonFile : public OwnedPythonFile<NativeFile> {
1149 public:
1150   SimplePythonFile(const PythonFile &file, bool borrowed, int fd,
1151                    File::OpenOptions options)
1152       : OwnedPythonFile(file, borrowed, fd, options, false) {}
1153 
1154   static char ID;
1155   bool isA(const void *classID) const override {
1156     return classID == &ID || NativeFile::isA(classID);
1157   }
1158   static bool classof(const File *file) { return file->isA(&ID); }
1159 };
1160 char SimplePythonFile::ID = 0;
1161 } // namespace
1162 
1163 #if PY_MAJOR_VERSION >= 3
1164 
1165 namespace {
1166 class PythonBuffer {
1167 public:
1168   PythonBuffer &operator=(const PythonBuffer &) = delete;
1169   PythonBuffer(const PythonBuffer &) = delete;
1170 
1171   static Expected<PythonBuffer> Create(PythonObject &obj,
1172                                        int flags = PyBUF_SIMPLE) {
1173     Py_buffer py_buffer = {};
1174     PyObject_GetBuffer(obj.get(), &py_buffer, flags);
1175     if (!py_buffer.obj)
1176       return llvm::make_error<PythonException>();
1177     return PythonBuffer(py_buffer);
1178   }
1179 
1180   PythonBuffer(PythonBuffer &&other) {
1181     m_buffer = other.m_buffer;
1182     other.m_buffer.obj = nullptr;
1183   }
1184 
1185   ~PythonBuffer() {
1186     if (m_buffer.obj)
1187       PyBuffer_Release(&m_buffer);
1188   }
1189 
1190   Py_buffer &get() { return m_buffer; }
1191 
1192 private:
1193   // takes ownership of the buffer.
1194   PythonBuffer(const Py_buffer &py_buffer) : m_buffer(py_buffer) {}
1195   Py_buffer m_buffer;
1196 };
1197 } // namespace
1198 
1199 // Shared methods between TextPythonFile and BinaryPythonFile
1200 namespace {
1201 class PythonIOFile : public OwnedPythonFile<File> {
1202 public:
1203   PythonIOFile(const PythonFile &file, bool borrowed)
1204       : OwnedPythonFile(file, borrowed) {}
1205 
1206   ~PythonIOFile() override { Close(); }
1207 
1208   bool IsValid() const override { return IsPythonSideValid(); }
1209 
1210   Status Close() override {
1211     assert(m_py_obj);
1212     GIL takeGIL;
1213     if (m_borrowed)
1214       return Flush();
1215     auto r = m_py_obj.CallMethod("close");
1216     if (!r)
1217       return Status(r.takeError());
1218     return Status();
1219   }
1220 
1221   Status Flush() override {
1222     GIL takeGIL;
1223     auto r = m_py_obj.CallMethod("flush");
1224     if (!r)
1225       return Status(r.takeError());
1226     return Status();
1227   }
1228 
1229   Expected<File::OpenOptions> GetOptions() const override {
1230     GIL takeGIL;
1231     return GetOptionsForPyObject(m_py_obj);
1232   }
1233 
1234   static char ID;
1235   bool isA(const void *classID) const override {
1236     return classID == &ID || File::isA(classID);
1237   }
1238   static bool classof(const File *file) { return file->isA(&ID); }
1239 };
1240 char PythonIOFile::ID = 0;
1241 } // namespace
1242 
1243 namespace {
1244 class BinaryPythonFile : public PythonIOFile {
1245 protected:
1246   int m_descriptor;
1247 
1248 public:
1249   BinaryPythonFile(int fd, const PythonFile &file, bool borrowed)
1250       : PythonIOFile(file, borrowed),
1251         m_descriptor(File::DescriptorIsValid(fd) ? fd
1252                                                  : File::kInvalidDescriptor) {}
1253 
1254   int GetDescriptor() const override { return m_descriptor; }
1255 
1256   Status Write(const void *buf, size_t &num_bytes) override {
1257     GIL takeGIL;
1258     PyObject *pybuffer_p = PyMemoryView_FromMemory(
1259         const_cast<char *>((const char *)buf), num_bytes, PyBUF_READ);
1260     if (!pybuffer_p)
1261       return Status(llvm::make_error<PythonException>());
1262     auto pybuffer = Take<PythonObject>(pybuffer_p);
1263     num_bytes = 0;
1264     auto bytes_written = As<long long>(m_py_obj.CallMethod("write", pybuffer));
1265     if (!bytes_written)
1266       return Status(bytes_written.takeError());
1267     if (bytes_written.get() < 0)
1268       return Status(".write() method returned a negative number!");
1269     static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1270     num_bytes = bytes_written.get();
1271     return Status();
1272   }
1273 
1274   Status Read(void *buf, size_t &num_bytes) override {
1275     GIL takeGIL;
1276     static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1277     auto pybuffer_obj =
1278         m_py_obj.CallMethod("read", (unsigned long long)num_bytes);
1279     if (!pybuffer_obj)
1280       return Status(pybuffer_obj.takeError());
1281     num_bytes = 0;
1282     if (pybuffer_obj.get().IsNone()) {
1283       // EOF
1284       num_bytes = 0;
1285       return Status();
1286     }
1287     auto pybuffer = PythonBuffer::Create(pybuffer_obj.get());
1288     if (!pybuffer)
1289       return Status(pybuffer.takeError());
1290     memcpy(buf, pybuffer.get().get().buf, pybuffer.get().get().len);
1291     num_bytes = pybuffer.get().get().len;
1292     return Status();
1293   }
1294 };
1295 } // namespace
1296 
1297 namespace {
1298 class TextPythonFile : public PythonIOFile {
1299 protected:
1300   int m_descriptor;
1301 
1302 public:
1303   TextPythonFile(int fd, const PythonFile &file, bool borrowed)
1304       : PythonIOFile(file, borrowed),
1305         m_descriptor(File::DescriptorIsValid(fd) ? fd
1306                                                  : File::kInvalidDescriptor) {}
1307 
1308   int GetDescriptor() const override { return m_descriptor; }
1309 
1310   Status Write(const void *buf, size_t &num_bytes) override {
1311     GIL takeGIL;
1312     auto pystring =
1313         PythonString::FromUTF8(llvm::StringRef((const char *)buf, num_bytes));
1314     if (!pystring)
1315       return Status(pystring.takeError());
1316     num_bytes = 0;
1317     auto bytes_written =
1318         As<long long>(m_py_obj.CallMethod("write", pystring.get()));
1319     if (!bytes_written)
1320       return Status(bytes_written.takeError());
1321     if (bytes_written.get() < 0)
1322       return Status(".write() method returned a negative number!");
1323     static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1324     num_bytes = bytes_written.get();
1325     return Status();
1326   }
1327 
1328   Status Read(void *buf, size_t &num_bytes) override {
1329     GIL takeGIL;
1330     size_t num_chars = num_bytes / 6;
1331     size_t orig_num_bytes = num_bytes;
1332     num_bytes = 0;
1333     if (orig_num_bytes < 6) {
1334       return Status("can't read less than 6 bytes from a utf8 text stream");
1335     }
1336     auto pystring = As<PythonString>(
1337         m_py_obj.CallMethod("read", (unsigned long long)num_chars));
1338     if (!pystring)
1339       return Status(pystring.takeError());
1340     if (pystring.get().IsNone()) {
1341       // EOF
1342       return Status();
1343     }
1344     auto stringref = pystring.get().AsUTF8();
1345     if (!stringref)
1346       return Status(stringref.takeError());
1347     num_bytes = stringref.get().size();
1348     memcpy(buf, stringref.get().begin(), num_bytes);
1349     return Status();
1350   }
1351 };
1352 } // namespace
1353 
1354 #endif
1355 
1356 llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) {
1357   if (!IsValid())
1358     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1359                                    "invalid PythonFile");
1360 
1361   int fd = PyObject_AsFileDescriptor(m_py_obj);
1362   if (fd < 0) {
1363     PyErr_Clear();
1364     return ConvertToFileForcingUseOfScriptingIOMethods(borrowed);
1365   }
1366   auto options = GetOptionsForPyObject(*this);
1367   if (!options)
1368     return options.takeError();
1369 
1370   // LLDB and python will not share I/O buffers.  We should probably
1371   // flush the python buffers now.
1372   auto r = CallMethod("flush");
1373   if (!r)
1374     return r.takeError();
1375 
1376   FileSP file_sp;
1377   if (borrowed) {
1378     // In this case we we don't need to retain the python
1379     // object at all.
1380     file_sp = std::make_shared<NativeFile>(fd, options.get(), false);
1381   } else {
1382     file_sp = std::static_pointer_cast<File>(
1383         std::make_shared<SimplePythonFile>(*this, borrowed, fd, options.get()));
1384   }
1385   if (!file_sp->IsValid())
1386     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1387                                    "invalid File");
1388 
1389   return file_sp;
1390 }
1391 
1392 llvm::Expected<FileSP>
1393 PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) {
1394 
1395   assert(!PyErr_Occurred());
1396 
1397   if (!IsValid())
1398     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1399                                    "invalid PythonFile");
1400 
1401 #if PY_MAJOR_VERSION < 3
1402 
1403   return llvm::createStringError(llvm::inconvertibleErrorCode(),
1404                                  "not supported on python 2");
1405 
1406 #else
1407 
1408   int fd = PyObject_AsFileDescriptor(m_py_obj);
1409   if (fd < 0) {
1410     PyErr_Clear();
1411     fd = File::kInvalidDescriptor;
1412   }
1413 
1414   auto io_module = PythonModule::Import("io");
1415   if (!io_module)
1416     return io_module.takeError();
1417   auto textIOBase = io_module.get().Get("TextIOBase");
1418   if (!textIOBase)
1419     return textIOBase.takeError();
1420   auto rawIOBase = io_module.get().Get("RawIOBase");
1421   if (!rawIOBase)
1422     return rawIOBase.takeError();
1423   auto bufferedIOBase = io_module.get().Get("BufferedIOBase");
1424   if (!bufferedIOBase)
1425     return bufferedIOBase.takeError();
1426 
1427   FileSP file_sp;
1428 
1429   auto isTextIO = IsInstance(textIOBase.get());
1430   if (!isTextIO)
1431     return isTextIO.takeError();
1432   if (isTextIO.get())
1433     file_sp = std::static_pointer_cast<File>(
1434         std::make_shared<TextPythonFile>(fd, *this, borrowed));
1435 
1436   auto isRawIO = IsInstance(rawIOBase.get());
1437   if (!isRawIO)
1438     return isRawIO.takeError();
1439   auto isBufferedIO = IsInstance(bufferedIOBase.get());
1440   if (!isBufferedIO)
1441     return isBufferedIO.takeError();
1442 
1443   if (isRawIO.get() || isBufferedIO.get()) {
1444     file_sp = std::static_pointer_cast<File>(
1445         std::make_shared<BinaryPythonFile>(fd, *this, borrowed));
1446   }
1447 
1448   if (!file_sp)
1449     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1450                                    "python file is neither text nor binary");
1451 
1452   if (!file_sp->IsValid())
1453     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1454                                    "invalid File");
1455 
1456   return file_sp;
1457 
1458 #endif
1459 }
1460 
1461 Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) {
1462   if (!file.IsValid())
1463     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1464                                    "invalid file");
1465 
1466   if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
1467     return Retain<PythonFile>(simple->GetPythonObject());
1468 #if PY_MAJOR_VERSION >= 3
1469   if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
1470     return Retain<PythonFile>(pythonio->GetPythonObject());
1471 #endif
1472 
1473   if (!mode) {
1474     auto m = file.GetOpenMode();
1475     if (!m)
1476       return m.takeError();
1477     mode = m.get();
1478   }
1479 
1480   PyObject *file_obj;
1481 #if PY_MAJOR_VERSION >= 3
1482   file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr,
1483                            "ignore", nullptr, 0);
1484 #else
1485   // Read through the Python source, doesn't seem to modify these strings
1486   char *cmode = const_cast<char *>(mode);
1487   // We pass ::flush instead of ::fclose here so we borrow the FILE* --
1488   // the lldb_private::File still owns it.
1489   file_obj =
1490       PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, ::fflush);
1491 #endif
1492 
1493   if (!file_obj)
1494     return exception();
1495 
1496   return Take<PythonFile>(file_obj);
1497 }
1498 
1499 #endif
1500