How can I print the content of PyByteArrayObject*?

Question:

I am using PyArg_Parsetuple to parse a bytearray sent from Python with the Y format specifier.

Y (bytearray) [PyByteArrayObject *]
Requires that the Python object is a bytearray object, without attempting any conversion.
Raises TypeError if the object is not a bytearray object.

In C code I am doing:

static PyObject* py_write(PyObject* self, PyObject* args)
{
       PyByteArrayObject* obj;
       PyArg_ParseTuple(args, "Y", &obj);

.
.
.

The Python script is sending the following data:

arr = bytearray()
arr.append(0x2)
arr.append(0x0)

How do I loop over the PyByteArrayObject* in C? To print 2 and 0?

Asked By: Tonyyyy

||

Answers:

With the help of the comment section, I found the definition for PyByteArrayObject

/* Object layout */
typedef struct {
    PyObject_VAR_HEAD
    Py_ssize_t ob_alloc;   /* How many bytes allocated in ob_bytes */
    char *ob_bytes;        /* Physical backing buffer */
    char *ob_start;        /* Logical start inside ob_bytes */
    Py_ssize_t ob_exports; /* How many buffer exports */
} PyByteArrayObject;

And the actual code to loop

PyByteArrayObject* obj;
PyArg_ParseTuple(args, "Y", &obj);

Py_ssize_t i = 0;
for (i = 0; i < PyByteArray_GET_SIZE(obj); i++)
    printf("%un", obj->ob_bytes[i]);

And I got the expected output.


Even better, simply use the Direct API

char* s = PyByteArray_AsString(obj);
int i = 0;
for (i = 0; i < PyByteArray_GET_SIZE(obj); i++)
    printf("%un", s[i]);
Answered By: Tonyyyy

Rather than poking implementation details, you should go through the documented API, particularly, accessing the data buffer through PyByteArray_AS_STRING or PyByteArray_AsString rather than through direct struct member access:

char *data = PyByteArray_AS_STRING(bytearray);
Py_ssize_t len = PyByteArray_GET_SIZE(bytearray);

for (Py_ssize_t i = 0; i < len; i++) {
    do_whatever_with(data[i]);
}

Note that everything in the public API takes the bytearray as a PyObject *, not a PyByteArrayObject *.

Answered By: user2357112
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.