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