From d9b553ec9961e95740535d3aeff62817f867767f Mon Sep 17 00:00:00 2001 From: Lawrence D'Anna Date: Tue, 15 Oct 2019 16:46:27 +0000 Subject: SBFile::GetFile: convert SBFile back into python native files. Summary: This makes SBFile::GetFile public and adds a SWIG typemap to convert the result back into a python native file. If the underlying File itself came from a python file, it is returned identically. Otherwise a new python file object is created using the file descriptor. Reviewers: JDevlieghere, jasonmolenda, labath Reviewed By: labath Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D68737 llvm-svn: 374911 --- .../ScriptInterpreter/Python/PythonDataObjects.cpp | 85 ++++++++++++++++------ 1 file changed, 64 insertions(+), 21 deletions(-) (limited to 'lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp') diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index c3588f6..4d77e55 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -22,6 +22,7 @@ #include "lldb/Utility/Stream.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Errno.h" @@ -1012,8 +1013,6 @@ operator()(std::initializer_list args) { PythonFile::PythonFile() : PythonObject() {} -PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); } - PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); } PythonFile::~PythonFile() {} @@ -1063,25 +1062,6 @@ void PythonFile::Reset(PyRefType type, PyObject *py_obj) { PythonObject::Reset(PyRefType::Borrowed, result.get()); } -void PythonFile::Reset(File &file, const char *mode) { - if (!file.IsValid()) { - Reset(); - return; - } - - char *cmode = const_cast(mode); -#if PY_MAJOR_VERSION >= 3 - Reset(PyRefType::Owned, PyFile_FromFd(file.GetDescriptor(), nullptr, cmode, - -1, nullptr, "ignore", nullptr, 0)); -#else - // Read through the Python source, doesn't seem to modify these strings - Reset(PyRefType::Owned, - PyFile_FromFile(file.GetStream(), const_cast(""), cmode, - nullptr)); -#endif -} - - FileUP PythonFile::GetUnderlyingFile() const { if (!IsValid()) return nullptr; @@ -1238,6 +1218,13 @@ public: return base_error; }; + PyObject *GetPythonObject() const { + assert(m_py_obj.IsValid()); + return m_py_obj.get(); + } + + static bool classof(const File *file) = delete; + protected: PythonFile m_py_obj; bool m_borrowed; @@ -1252,7 +1239,14 @@ public: SimplePythonFile(const PythonFile &file, bool borrowed, int fd, File::OpenOptions options) : OwnedPythonFile(file, borrowed, fd, options, false) {} + + static char ID; + bool isA(const void *classID) const override { + return classID == &ID || NativeFile::isA(classID); + } + static bool classof(const File *file) { return file->isA(&ID); } }; +char SimplePythonFile::ID = 0; } // namespace #if PY_MAJOR_VERSION >= 3 @@ -1321,7 +1315,18 @@ public: return Status(); } + Expected GetOptions() const override { + GIL takeGIL; + return GetOptionsForPyObject(m_py_obj); + } + + static char ID; + bool isA(const void *classID) const override { + return classID == &ID || File::isA(classID); + } + static bool classof(const File *file) { return file->isA(&ID); } }; +char PythonIOFile::ID = 0; } // namespace namespace { @@ -1542,4 +1547,42 @@ PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) { #endif } +Expected PythonFile::FromFile(File &file, const char *mode) { + if (!file.IsValid()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "invalid file"); + + if (auto *simple = llvm::dyn_cast(&file)) + return Retain(simple->GetPythonObject()); +#if PY_MAJOR_VERSION >= 3 + if (auto *pythonio = llvm::dyn_cast(&file)) + return Retain(pythonio->GetPythonObject()); +#endif + + if (!mode) { + auto m = file.GetOpenMode(); + if (!m) + return m.takeError(); + mode = m.get(); + } + + PyObject *file_obj; +#if PY_MAJOR_VERSION >= 3 + file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr, + "ignore", nullptr, 0); +#else + // Read through the Python source, doesn't seem to modify these strings + char *cmode = const_cast(mode); + // We pass ::flush instead of ::fclose here so we borrow the FILE* -- + // the lldb_private::File still owns it. + file_obj = + PyFile_FromFile(file.GetStream(), const_cast(""), cmode, ::fflush); +#endif + + if (!file_obj) + return exception(); + + return Take(file_obj); +} + #endif -- cgit v1.1