[pypy-commit] pypy py3.5: Implement PyObject_Bytes

rlamy pypy.commits at gmail.com
Sun Jan 22 19:03:49 EST 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.5
Changeset: r89702:742da0d33a6a
Date: 2017-01-23 00:03 +0000
http://bitbucket.org/pypy/pypy/changeset/742da0d33a6a/

Log:	Implement PyObject_Bytes

diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -1,7 +1,7 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (
     cpython_api, generic_cpy_call, CANNOT_FAIL, Py_ssize_t, Py_ssize_tP,
-    PyVarObject, Py_buffer, size_t, slot_function,
+    PyVarObject, Py_buffer, size_t, slot_function, api_decl, cts,
     PyBUF_FORMAT, PyBUF_ND, PyBUF_STRIDES,
     Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT,
     Py_GE, CONST_STRING, CONST_STRINGP, FILEP, fwrite)
@@ -11,6 +11,7 @@
 from pypy.module.cpyext.typeobject import PyTypeObjectPtr
 from pypy.module.cpyext.pyerrors import PyErr_NoMemory, PyErr_BadInternalCall
 from pypy.objspace.std.typeobject import W_TypeObject
+from pypy.objspace.std.bytesobject import invoke_bytes_method
 from pypy.interpreter.error import OperationError, oefmt
 import pypy.module.__builtin__.operation as operation
 
@@ -247,6 +248,19 @@
         return space.wrap("<NULL>")
     return space.str(w_obj)
 
+ at api_decl("PyObject * PyObject_Bytes(PyObject *v)", cts)
+def PyObject_Bytes(space, w_obj):
+    if w_obj is None:
+        return space.newbytes("<NULL>")
+    if space.type(w_obj) is space.w_bytes:
+        return w_obj
+    w_result = invoke_bytes_method(space, w_obj)
+    if w_result is not None:
+        return w_result
+    # return PyBytes_FromObject(space, w_obj)
+    buffer = space.buffer_w(w_obj, space.BUF_FULL_RO)
+    return space.newbytes(buffer.as_str())
+
 @cpython_api([PyObject], PyObject)
 def PyObject_Repr(space, w_obj):
     """Compute a string representation of object o.  Returns the string
diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -296,6 +296,20 @@
         a = module.empty_format('hello')
         assert isinstance(a, str)
 
+    def test_Bytes(self):
+        class sub1(bytes):
+            pass
+        class sub2(bytes):
+            def __bytes__(self):
+                return self
+        module = self.import_extension('test_Bytes', [
+            ('asbytes', 'METH_O',
+             """
+                return PyObject_Bytes(args);
+             """)])
+        assert type(module.asbytes(sub1(b''))) is bytes
+        assert type(module.asbytes(sub2(b''))) is sub2
+
 class AppTestPyBuffer_FillInfo(AppTestCpythonExtensionBase):
     """
     PyBuffer_FillInfo populates the fields of a Py_buffer from its arguments.


More information about the pypy-commit mailing list