¿Cómo usar las vistas de memoria mecanografiadas de Cython para aceptar cadenas de Python?

¿Cómo puedo escribir una función de Cython que tome un objeto de cadena de bytes (una cadena normal, un bytearray u otro objeto que siga elprotocolo de amortiguación) como unmemoria escrita?

De acuerdo con laCuerdas Unicode y Pasando Página del tutorial de Cython, lo siguiente debería funcionar:

cpdef object printbuf(unsigned char[:] buf):
    chars = [chr(x) for x in buf]
    print repr(''.join(chars))

Funciona para bytearrays y otros buffers de escritura:

$ python -c 'import test; test.printbuf(bytearray("test\0ing"))'
'test\x00ing'

Pero no funciona para cadenas normales y otros objetos de búfer de solo lectura:

$ python -c 'import test; test.printbuf("test\0ing")'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "test.pyx", line 1, in test.printbuf (test.c:1417)
  File "stringsource", line 614, in View.MemoryView.memoryview_cwrapper (test.c:6795)
  File "stringsource", line 321, in View.MemoryView.memoryview.__cinit__ (test.c:3341)
BufferError: Object is not writable.

Mirando el código C generado, Cython siempre pasa elPyBUF_WRITABLE bandera aPyObject_GetBuffer(), lo que explica la excepción.

Yo mismo puedo obtener una vista del objeto buffer manualmente, pero no es tan conveniente:

from cpython.buffer cimport \
    PyBUF_SIMPLE, PyBUF_WRITABLE, \
    PyObject_CheckBuffer, PyObject_GetBuffer, PyBuffer_Release

cpdef object printbuf(object buf):
    if not PyObject_CheckBuffer(buf):
        raise TypeError("argument must follow the buffer protocol")
    cdef Py_buffer view
    PyObject_GetBuffer(buf, &view, PyBUF_SIMPLE)
    try:
        chars = [chr((<unsigned char *>view.buf)[i])
                 for i in range(view.len)]
        print repr(''.join(chars))
    finally:
        PyBuffer_Release(&view)
$ python -c 'import test; test.printbuf(bytearray("test\0ing"))'
'test\x00ing'
$ python -c 'import test; test.printbuf("test\0ing")'
'test\x00ing'

¿Estoy haciendo algo mal o Cython no admite la coacción de objetos de búfer de solo lectura (como cadenas normales) en objetos de vista de memoria escritos?

Respuestas a la pregunta(2)

Su respuesta a la pregunta