Como usar as visões de memória do Cython para aceitar strings do Python?

Como escrever uma função Cython que usa um objeto de string de bytes (uma string normal, um bytearray ou outro objeto que segue oprotocolo de buffer) como ummemoryview digitado?

De acordo comUnicode e seqüências de caracteres de passagem Na página de tutorial do Cython, o seguinte deve funcionar:

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

Funciona para bytearrays e outros buffers graváveis:

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

Mas não funciona para cadeias normais e outros objetos de buffer somente leitura:

$ 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.

Observando o código C gerado, o Cython está sempre passando oPyBUF_WRITABLE sinalizar paraPyObject_GetBuffer(), o que explica a exceção.

Posso obter manualmente uma visualização no objeto buffer, mas não é tão 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'

Estou fazendo algo errado ou o Cython não suporta coagir objetos de buffer somente leitura (como seqüências de caracteres normais) em objetos de visualização de memória digitados?

questionAnswers(2)

yourAnswerToTheQuestion