summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2015-10-14 21:06:13 +0000
committerZachary Turner <zturner@google.com>2015-10-14 21:06:13 +0000
commit18426935ac8596a42f5cf1a39c7d29e97af8fe21 (patch)
tree3e89906b3a3b1eee87d9ec15fb87db2f73c8674b /lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
parentedffd91bcec7cb02dd527a9ca210888b28eaf0f2 (diff)
downloadbcm5719-llvm-18426935ac8596a42f5cf1a39c7d29e97af8fe21.tar.gz
bcm5719-llvm-18426935ac8596a42f5cf1a39c7d29e97af8fe21.zip
Get Python unit tests working with Python 3.
There were a couple of issues related to string handling that needed to be fixed. In particular, we cannot get away with converting `PyUnicode` objects to `PyBytes` objects and storing the `PyBytes` regardless of Python version. Instead we have to store a `PyUnicode` on Python 3 and a `PyString` on Python 2. The reason for this is that if you call `PyObject_Str` on a `PyBytes` in Python 3, it will return you a string that actually contains the string value wrappedin the characters b''. So if we create a `PythonString` with the value "test", and we call Str() on it, we will get back the string "b'test'", which breaks string equality. The only way to fix this is to store a native `PyUnicode` object under Python 3. With this CL, ScriptInterpreterPythonTests unit tests pass 100% under Python 2 and Python 3. llvm-svn: 250327
Diffstat (limited to 'lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp')
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp67
1 files changed, 28 insertions, 39 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 1ab5e4aa51a..fa556ed3ac5 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -67,22 +67,14 @@ PythonObject::GetObjectType() const
if (!IsAllocated())
return PyObjectType::None;
- if (PyList_Check(m_py_obj))
+ if (PythonList::Check(m_py_obj))
return PyObjectType::List;
- if (PyDict_Check(m_py_obj))
+ if (PythonDictionary::Check(m_py_obj))
return PyObjectType::Dictionary;
- if (PyUnicode_Check(m_py_obj))
+ if (PythonString::Check(m_py_obj))
return PyObjectType::String;
- if (PyLong_Check(m_py_obj))
+ if (PythonInteger::Check(m_py_obj))
return PyObjectType::Integer;
-#if PY_MAJOR_VERSION < 3
- // These functions don't exist in Python 3.x. PyString is PyUnicode
- // and PyInt is PyLong.
- if (PyString_Check(m_py_obj))
- return PyObjectType::String;
- if (PyInt_Check(m_py_obj))
- return PyObjectType::Integer;
-#endif
return PyObjectType::Unknown;
}
@@ -187,11 +179,11 @@ PythonString::Check(PyObject *py_obj)
{
if (!py_obj)
return false;
+
#if PY_MAJOR_VERSION >= 3
- // Python 3 does not have PyString objects, only PyUnicode.
return PyUnicode_Check(py_obj);
#else
- return PyUnicode_Check(py_obj) || PyString_Check(py_obj);
+ return PyString_Check(py_obj);
#endif
}
@@ -208,18 +200,6 @@ PythonString::Reset(PyRefType type, PyObject *py_obj)
return;
}
- // Convert this to a PyBytes object, and only store the PyBytes. Note that in
- // Python 2.x, PyString and PyUnicode are interchangeable, and PyBytes is an alias
- // of PyString. So on 2.x, if we get into this branch, we already have a PyBytes.
- if (PyUnicode_Check(py_obj))
- {
- // Since we're converting this to a different object, we assume ownership of the
- // new object regardless of the value of `type`.
- result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(py_obj));
- }
-
- assert(PyBytes_Check(result.get()) && "PythonString::Reset received a non-string");
-
// Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
// back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
@@ -228,21 +208,31 @@ PythonString::Reset(PyRefType type, PyObject *py_obj)
llvm::StringRef
PythonString::GetString() const
{
- if (IsValid())
- {
- Py_ssize_t size;
- char *c;
- PyBytes_AsStringAndSize(m_py_obj, &c, &size);
- return llvm::StringRef(c, size);
- }
- return llvm::StringRef();
+ if (!IsValid())
+ return llvm::StringRef();
+
+ Py_ssize_t size;
+ char *c;
+
+#if PY_MAJOR_VERSION >= 3
+ c = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
+#else
+ PyString_AsStringAndSize(m_py_obj, &c, &size);
+#endif
+ return llvm::StringRef(c, size);
}
size_t
PythonString::GetSize() const
{
if (IsValid())
- return PyBytes_Size(m_py_obj);
+ {
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_GetSize(m_py_obj);
+#else
+ return PyString_Size(m_py_obj);
+#endif
+ }
return 0;
}
@@ -251,11 +241,10 @@ PythonString::SetString (llvm::StringRef string)
{
#if PY_MAJOR_VERSION >= 3
PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size());
- PyObject *bytes = PyUnicode_AsUTF8String(unicode);
- PythonObject::Reset(PyRefType::Owned, bytes);
- Py_DECREF(unicode);
+ PythonObject::Reset(PyRefType::Owned, unicode);
#else
- PythonObject::Reset(PyRefType::Owned, PyString_FromStringAndSize(string.data(), string.size()));
+ PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
+ PythonObject::Reset(PyRefType::Owned, str);
#endif
}
OpenPOWER on IntegriCloud