[Python-Dev] Understanding the buffer API
Jeff Allen
"ja...py" at farowl.co.uk
Sun Aug 5 12:08:58 CEST 2012
- Summary:
The PEP, or sometimes just the documentation, definitely requires that
features not requested shall be NULL.
The API would benefit from:
a. stored flags that tell you the actual structural features.
b. requiring exporters to provide full information (e.g. strides =
{1}, format = "B") even when trivial.
It could and possibly should work this way in Python 4.0.
Nick thinks we could *allow* exporters to behave this way (PEP change)
in Python 3.x. Stefan thinks not, because "Perhaps there is code that
tests for shape==NULL to determine C-contiguity."
Jython exporters should return full information unconditionally from the
start: "any implementation that doesn't use the Py_buffer struct
directly in a C-API should just always return a full buffer" (Stefan);
"I think that's the way Jython should go: *require* that those fields be
populated appropriately" (Nick).
- But what I now think is:
_If the only problem really is_ "code that tests for shape==NULL to
determine C-contiguity", or makes similar deductions, I agree that
providing unasked-for information is_safe_. I think the stipulation in
PEP/documentation has some efficiency value: on finding shape!=NULL the
code has to do a more complicated test, as inPyBuffer_IsContiguous(). I
have the option to provide an isContiguous that has the answer written
down already, so the risk is only from/to ported code. If it is only a
risk to the efficiency of ported code, I'm relaxed: I hesitate only to
check that there's no circumstance that logically requires nullity for
correctness. Whether it was safe that was the key question.
In the hypothetical Python 4.0 buffer API (and in Jython) where feature
flags are provided, the efficiency is still useful, but complicated
deductive logic in the consumer should be deprecated in favour of
(functions for) interrogating the flags.
An example illustrating the semantics would then be:
1. consumer requests a buffer, saying "I can cope with a strided arrays"
(PyBUF_STRIDED);
2. exporter provides a strides array, but in the feature flags
STRIDED=0, meaning "you don't need the strides array";
3. exporter (optionally) uses efficient, non-strided access.
_I do not think_ that full provision by the exporter has to be
_mandatory_, as the discussion has gone on to suggest. I know your
experience is that you have often had to regenerate the missing
information to write generic code, but I think this does not continue
once you have the feature flags. An example would be:
1. consumer requests a buffer, saying "I can cope with a N-dimensional
but not strided arrays" (PyBUF_ND);
2. exporter sets strides=NULL, and the feature flag STRIDED=0;
3. exporter accesses the data, without reference to the strides array,
as it planned;
4. new generic code that respects the feature flag STRIDED=0, does not
reference the strides array;
5. old generic code, ignorant of the feature flags, finds the
strides=NULL and so does not dereference strides.
Insofar as it is not necessary, there is some efficiency in not
providing it. There would only be a problem with broken code that both
ignores the feature flag and uses the strides array unchecked. But this
code was always broken.
Really useful discussion this.
Jeff
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20120805/51a95d9a/attachment.html>
More information about the Python-Dev
mailing list