2015-01-28 5 views
12

मैं एक साइथन फ़ंक्शन कैसे लिख सकता हूं जो एक बाइट स्ट्रिंग ऑब्जेक्ट (एक सामान्य स्ट्रिंग, एक बाइटियर, या buffer protocol का पालन करने वाली दूसरी ऑब्जेक्ट) typed memoryview के रूप में ले सकता है?पायथन से स्ट्रिंग स्वीकार करने के लिए साइथन टाइप किए गए मेमोरीव्यू का उपयोग कैसे करें?

Unicode and Passing Strings Cython ट्यूटोरियल पृष्ठ के अनुसार, निम्नलिखित काम करना चाहिए:

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

यह करता bytearrays और अन्य लिखने योग्य बफ़र्स के लिए काम करते:

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

लूकी उत्पन्न सी कोड पर, साइथन हमेशा 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 coercing केवल पढ़ने के लिए वस्तुओं बफ़र का समर्थन नहीं करता (जैसे कि सामान्य स्ट्रिंग्स) टाइप किए गए मेमोरीव्यू ऑब्जेक्ट्स में?

+0

मुझे आपका पैच मिला [यहां] (https://mail.python.org/pipermail/cython-devel/2015- फरवरी /004316.html) यहां तक ​​कि 'const' जोड़ने से भी मदद नहीं मिलती है, इसलिए इसका मतलब है कि सुझाए गए दस्तावेज़ काम नहीं कर रहा। – dashesy

उत्तर

18

(कम से कम संस्करण 0.22 तक) प्रलेखन, अन्यथा सुझाव Cython बावजूद नहीं समर्थन coercing केवल पढ़ने के लिए आपके द्वारा लिखा गया memoryview वस्तुओं में वस्तुओं बफ़र करता है। साइथन हमेशा PyBUF_WRITABLE ध्वज PyObject_GetBuffer() पास करता है, भले ही इसे लेखन पहुंच की आवश्यकता न हो। यह अपवाद बढ़ाने के लिए केवल-पढ़ने वाले बफर ऑब्जेक्ट का कारण बनता है।

I raised this issue on the Cython developer mailing list, और यहां तक ​​कि एक (बहुत मोटा) पैच भी शामिल था। मुझे कभी जवाब नहीं मिला, इसलिए मुझे लगता है कि साइथन डेवलपर्स इस बग को ठीक करने में रूचि नहीं रखते हैं।

+0

मुझे भी वही समस्या मिली, क्यों वे इसे ठीक करने में रूचि नहीं रखते? – avocado

+0

आप पैच को गिटहब पुल अनुरोध के रूप में सबमिट करने का प्रयास कर सकते हैं; और कुछ परीक्षण मामलों में जोड़ना। – joeln

+0

वास्तव में, क्या आपने गिटहब के माध्यम से पैच को धक्का देने की कोशिश की है? –

संबंधित मुद्दे