2015-01-28 3 views
12

Как написать функцию Cython, которая принимает объект строки байта (обычная строка, bytearray или другой объект, который следует за buffer protocol) как typed memoryview?Как использовать Cython типизированные представления памяти для принятия строк из Python?

Согласно странице учебника Unicode and Passing Strings Cython, следующее должно работать:

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

Это делает работу для ByteArray, и других доступных для записи буферов:

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

Но это не работает для нормальных строк и других буферных объектов только для чтения:

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

Looki ng при сгенерированном C-коде, Cython всегда передает флаг PyBUF_WRITABLE в PyObject_GetBuffer(), что объясняет исключение.

я могу вручную получить представление в буфер объект сам, но это не так удобно:

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' 

Я делаю что-то неправильно, или же Cython не поддерживает принуждении только для чтения буфера объектов (такие как обычные строки) в типизированные объекты памяти?

+0

Я нашел ваш патч [здесь] (https://mail.python.org/pipermail/cython-devel/2015-February/004316.html), даже добавление 'const' не помогает, поэтому это означает предлагаемую документацию не работает. – dashesy

ответ

18

Несмотря на документацию, указывающую на то, что Cython (по крайней мере, до версии 0.22) делает не поддерживает принудительное сохранение объектов буфера только для чтения в типизированные объекты памяти. Cython всегда передает флаг PyBUF_WRITABLE в PyObject_GetBuffer(), даже если ему не нужен доступ для записи. Это приводит к тому, что объекты буфера только для чтения создают исключение.

I raised this issue on the Cython developer mailing list, и даже включая (очень грубый) патч. Я никогда не получал ответа, поэтому я предполагаю, что разработчики Cython не заинтересованы в исправлении этой ошибки.

+0

У меня тоже такая же проблема, почему они не заинтересованы в ее исправлении? – avocado

+0

Вы можете попробовать отправить патч в качестве запроса на извлечение GitHub; и добавление в некоторые тестовые примеры. – joeln

+0

Действительно, вы пытались нажать патч через GitHub? –

 Смежные вопросы

  • Нет связанных вопросов^_^