2013-10-07 5 views
8

Я нахожусь в процессе расширения классов в нашей библиотеке (который поддерживает Python 2.7) для поддержки PEP 3118, который был обратно портирована на 2,7.Определение PyBufferProcs в Python 2.7, когда класс реализует PEP 3118

Из документации, мне нужно инициализировать tp_as_buffer поле, чтобы указать на PyBufferProcs. Однако из документации для 2.7 the description of this structure содержит только записи для старого протокола . Из источников I gather, что PyBufferProcs имеет дополнительные записи для нового протокола (bf_getbuffer и bf_releasebuffer).

вопросы остаются:

  • Должен ли я сделать что-то особенное, чтобы сказать, что эти Python новые записи действительны?

  • Должен ли я заполнять записи для старого протокола? (The документация 2.7 говорит, что, например, bf_getsegcount не может быть пустым. Но эта запись не должна использоваться, если я поддерживает PEP 3118.)

+1

Посмотрите на ['bytearray_as_buffer'] (http://hg.python.org/cpython/file/ee879c0ffa11/Objects/bytearrayobject.c#l2800) в 2.7, с дополнительными полями для' bf_getbuffer' и 'bf_releasebuffer' , Кроме того, ['PyByteArray_Type.tp_flags'] (http://hg.python.org/cpython/file/ee879c0ffa11/Objects/bytearrayobject.c#l2893) устанавливает' Py_TPFLAGS_HAVE_NEWBUFFER'. ['PyObject_GetBuffer'] (http://hg.python.org/cpython/file/ee879c0ffa11/Objects/abstract.c#l357) использует [' PyObject_CheckBuffer'] (http://hg.python.org/cpython/ file/ee879c0ffa11/Include/abstract.h # l534), чтобы проверить, установлен ли этот флаг. – eryksun

+0

Да, абсолютно, я посмотрел именно на эти вещи - но это не проблема, о которой мы просим (если я не пропущу что-то, это публичные официальные функции API Python - которые не будут корректно отвечать на наш питон C -extension объектов без надлежащего (и ненужно задушевно документированного) материала, созданного в связанных PyBufferProcs (как указано в определении типа struct def). Помогите нам получить все это правильно и правильно! – fish2000

+2

Вопрос [«собрать»] (https://github.com/python/cpython/blob/master/Objects/bytearrayobject.c#L3648-3651) ссылки на реализацию Python 3 'bytearray', которая не использует версию Python 2' PyBufferProcs' который имеет * шесть * полей, включая последние два для нового протокола буфера. Использование только нового протокола требует только этих двух полей. Источник Python 3 также не использует флаг 'Py_TPFLAGS_HAVE_NEWBUFFER', который находится только на Python 2.Установка этого флага - это «что-то особенное», которое сообщает 'PyObject_CheckBuffer', что новые записи действительны. – eryksun

ответ

2

Вы можете просто заполнить последний два поля PyBufferProcs, но, вы должны добавить флаг Py_TPFLAGS_HAVE_NEWBUFFER в tp_flags ваших типов. Это особая вещь, которая была введена в python2, чтобы сделать новый протокол доступным вместе со старым.

Я понятия не имею, почему это нигде не документированы, но вы можете увидеть его использовать в определении bytearray типа для Python 2.7 (см here):

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

Это содержание было уже отправленный в комментариях, но он заслуживает ответа.

+0

Нельзя переоценить, насколько это правильно: отсутствие документации для Py_TPFLAGS_HAVE_NEWBUFFER фактически упоминается как ошибка Python (qv https://bugs.python.org/issue23850), и, как говорит @Bakuriu, это «специальный вещь "нужно развязать PEP 3118. Да! – fish2000