2013-10-07 25 views
8

Io sono nel processo di estensione delle classi nella nostra biblioteca (che supporta Python 2.7) per supportare PEP 3118, che è stato back-porting 2.7.Definizione PyBufferProcs in Python 2.7, quando classe implementa PEP 3118

Dalla documentazione, ho bisogno di inizializzare il campo tp_as_buffer per puntare a un PyBufferProcs. Dalla documentazione per 2.7, tuttavia, the description of this structure contiene solo voci per il vecchio protocollo del buffer . Dalle origini, I gather che PyBufferProcs ha alcune voci aggiuntive per il nuovo protocollo (bf_getbuffer e bf_releasebuffer).

Le domande rimangono:

  • Devo fare qualcosa di speciale da raccontare Python che queste nuove voci sono validi?

  • Devo compilare le voci per il vecchio protocollo? (La documentazione per 2.7 dice, per esempio, che bf_getsegcount non può essere nullo. Ma questa voce non deve essere utilizzato se sono supporto PEP 3118.)

+1

Guarda ['bytearray_as_buffer'] (http://hg.python.org/cpython/file/ee879c0ffa11/Objects/bytearrayobject.c#l2800) in 2.7, con i campi aggiuntivi per' bf_getbuffer' e 'bf_releasebuffer' . Inoltre, ['PyByteArray_Type.tp_flags'] (http://hg.python.org/cpython/file/ee879c0ffa11/Objects/bytearrayobject.c#l2893) imposta' Py_TPFLAGS_HAVE_NEWBUFFER'. ['PyObject_GetBuffer'] (http://hg.python.org/cpython/file/ee879c0ffa11/Objects/abstract.c#l357) usa il [' PyObject_CheckBuffer'] (http://hg.python.org/cpython/ file/ee879c0ffa11/Include/abstract.h # l534) per verificare che questo flag sia impostato. – eryksun

+0

Sì, assolutamente, ho guardato esattamente quelle cose - ma non è questo il problema che ci stiamo ponendo (a meno che non manchi qualcosa, quelle sono le funzioni pubbliche e ufficiali di Python API - che non risponderanno correttamente al nostro python C -estensione degli oggetti senza le cose appropriate (e inutilmente documentate in modo criptico) impostate nei relativi PyBufferProcs (come indicato appropriatamente nel tipo struct def.) Aiutateci a ottenere tutto ciò che è corretto e corretto! – fish2000

+2

La domanda ["gather"] (https://github.com/python/cpython/blob/master/Objects/bytearrayobject.c#L3648-3651) punti di collegamento nell'implementazione 'bytearray' di Python 3, che non usa la versione Python 2 di' PyBufferProcs'. che ha * sei * campi, inclusi gli ultimi due per il nuovo protocollo di buffer.Utilizzando solo il nuovo protocollo richiede solo quei due campi.Il sorgente Python 3 inoltre non usa il flag 'Py_TPFLAGS_HAVE_NEWBUFFER', che è solo in Python 2.L'impostazione di questo flag è "qualcosa di speciale" che dice a "PyObject_CheckBuffer" che le nuove voci sono valide. – eryksun

risposta

2

Si può solo riempire l'ultima due campi di PyBufferProcsma è necessario aggiungere il flag Py_TPFLAGS_HAVE_NEWBUFFER allo tp_flags dei tipi. Questa è la cosa speciale introdotta in python2 per rendere disponibile il nuovo protocollo insieme a quello vecchio.

ho idea perché questo non è documentato da nessuna parte, ma si può vedere ha usato nella definizione del tipo bytearray per Python 2.7 (vedi here):

 
    &bytearray_as_buffer,    /* tp_as_buffer */ 
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | 
    Py_TPFLAGS_HAVE_NEWBUFFER,   /* tp_flags */ 

Questo contenuto è stato già pubblicato nei commenti, ma merita una risposta.

+0

Non può essere sopravvalutato quanto sia corretto questo - la mancanza di documentazione per 'Py_TPFLAGS_HAVE_NEWBUFFER' è in realtà elencata come un bug Python (qv https://bugs.python.org/issue23850) e, come dice @Bakuriu, è la" speciale " cosa "bisogna scatenare PEP 3118. Sì! – fish2000