Esta función:
PyObject_GetBuffer
PyBuffer_Release
PyBuffer_Release
llama a PyBufferProcs.bf_releasebuffer(PyObject *exporter, Py_buffer *view)
, que según los documentos puede _ "liberar toda la memoria asociada con view
" _, y no exige que view
permanezca vivo mientras siempre que exporter
.
Entonces, en principio, un tipo que asigna un búfer para sí mismo sobre la marcha en bf_getbuffer
y lo elimina cuando se liberan los últimos usos, causará un uso después de libre en numpy.
No sé si algunos implementadores del protocolo de búfer realmente hacen esto, pero mi lectura es que tienen permiso para hacerlo.
Esto es extraño. Creo que me gustaría que la interfaz del búfer especificara que mientras los campos de la estructura del búfer (como zancadas, etc.) se liberan por PyBuffer_Release
la memoria real apuntada debe ser propiedad del objeto original (esto sería resolver nuestro problema con el muy molesto _dealloc_cached_buffer_info
). Creo que esta es la intención y la verdad, pero ...
Ahora, esta función devuelve PyArray_Chunk
y no un búfer, por lo que si hace la aclaración que digo anteriormente, en realidad está completamente bien.
Su interpretación suena más razonable; quizás una solicitud de extracción contra python / cpython sería prudente para actualizar los documentos para decirle a la gente que no implemente lo que describí anteriormente.
Iba a abrir, pero luego fui a almorzar primero: https://bugs.python.org/issue39471 Puedo considerar proponer cambios en el texto. Si podemos estar de acuerdo con mi interpretación, podemos limpiar código muy feo y muy lento en la implementación del protocolo de búfer (actualmente ralentiza las matemáticas escalares en un 20 +%). (EDITAR: Pero supongo que solo después de que Python corrija su código ArgParse :()
Eso agrega algo de claridad, gracias, no me había dado cuenta de que Python estaba usando la misma lectura que bf_releasebuffer
que yo.
Maldita sea, lo había leído demasiado antes (del PEP):
Los exportadores necesitarán definir una función bf_releasebuffer si pueden reasignar su memoria, zancadas, forma, subcompensaciones o variables de formato que podrían compartir a través de struct bufferinfo.
Lo que se lee como si fuera válido para darle al búfer una nueva porción de memoria :(.
Aunque: mirando la implementación de array
(python one), todo lo que hace es usarlo para asegurarse de que deshabilita el cambio de tamaño si existe un búfer.