14

型指定された memoryviewとしてバイト文字列オブジェクト (通常の文字列、bytearray、またはbuffer protocolに従う別のオブジェクト) を取る Cython 関数を作成するにはどうすればよいですか?

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.

生成された 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 は型指定された memoryview オブジェクトへの読み取り専用バッファ オブジェクト (通常の文字列など) の強制をサポートしていませんか?

4

2 に答える 2

21

ドキュメントが別の方法を示唆しているにもかかわらず、Cython (少なくともバージョン 0.22 まで) は、読み取り専用のバッファー オブジェクトを強制的に型指定された memoryview オブジェクトに変換することをサポートしていません。Cython は、書き込みアクセスが必要ない場合でも、常にPyBUF_WRITABLEフラグを に渡します。PyObject_GetBuffer()これにより、読み取り専用のバッファー オブジェクトで例外が発生します。

は Cython 開発者メーリング リストでこの問題を提起し、(非常に大雑把な) パッチも含めました。返信がなかったので、Cython 開発者はこのバグを修正することに関心がないと思います。

于 2015-03-15T23:00:44.943 に答える