[issue15821] PyMemoryView_FromBuffer() behavior change (possible regression)

2012-09-28 Thread Jesús Cea Avión

Changes by Jesús Cea Avión j...@jcea.es:


--
nosy: +jcea

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15821
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15821] PyMemoryView_FromBuffer() behavior change (possible regression)

2012-09-01 Thread Stefan Krah

Stefan Krah added the comment:

In general, the number of calls to PyObject_GetBuffer() must be equal to
the number of calls to PyBuffer_Release(), otherwise bad things will happen
in the same way as with malloc()/free().


Now, in my test case I omitted the call to PyObject_GetBuffer() *with*
the internal knowledge that in the case of the bytes object it does
not matter: The releasebufferproc is NULL, so PyBuffer_Release()
is just a way of decrementing the reference count of the bytes object.


No matter how you turn it, if info.obj != NULL you need some internal
knowledge what the obj's releasebufferproc will do. For example, I
suspect that many existing releasebufferprocs do not account for
the fact that a consumer may change shape, strides and suboffsets.

So you need to know the exporter really well.


My strategy here is this: I want to keep backwards compatibility
for PyMemoryView_FromBuffer(), which I think should be deprecated
at some point.


A proper function that returns a memoryview with automatic cleanup
would not involve getbuffer/releasebuffer at all and could look like
this:

Flags:
--
PyManagedBuffer_FreeBuf
PyManagedBuffer_FreeFormat
PyManagedBuffer_FreeArrays  // shape, strides, suboffsets

PyMemoryView_FromBufferWithCleanup(info, flags)
{
/* info should never have been obtained by a call to PyObject_GetBuffer().
   Hence it should never be released. */
assert(info.obj == NULL);

/* buf, format, shape, strides and suboffsets MUST stay valid
   for the lifetime of the returned memoryview. Usually they
   will be dynamically allocated using PyMem_Malloc(). This is
   no problem, since there is automatic cleanup in mbuf_dealloc(). */

mbuf = mbuf_alloc();
mbuf-master = *info;
mbuf-flags |= flags;

...

return new memoryview
}

mbuf_dealloc(self)
{
if (self-flagsPyManagedBuffer_FreeBuf)
PyMem_Free(self-master.buf);
...
}

This is much more flexible than the existing function and does not suffer
from any abuse of getbuffer/releasebuffer.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15821
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15821] PyMemoryView_FromBuffer() behavior change (possible regression)

2012-08-31 Thread Stefan Krah

Stefan Krah added the comment:

Alexander, your test case is brilliant and could eventually go into
_testbuffer.c, but I'd prefer a simpler test case for now. :)

Here's a patch that restores the info.obj cleanup facility.

I intentionally did not add copying the format in order to keep the
diff small (in case this can go into rc2). Crashing on stack addresses
for format is not a regression.


Apparently PyMemoryView_FromBuffer() is used for low level tinkering and
automatic cleanup, so I now think that it's better not to break backwards
compatibility, i.e. leave the value of info.obj untouched.

Otherwise people using the cleanup facility will have reference leaks.


However, I don't like the interface at all: Passing a pointer to a struct
and then relying on the fact that *some* values are copied (shape, strides
and suboffsets) but not others (format, buf) is counterintuitive.


With the ManagedBuffer, we could now write a new function that returns
a memoryview with much nicer cleanup facilities. But that doesn't help
here since we're stuck with this function for 3.3.0.


What do you think? Should this go into 3.3.0? The changes to memoryobject.c
are minimal, the rest are tests and docs.

--
assignee: docs@python - skrah
components: +Interpreter Core -Documentation
stage:  - patch review
title: Improve docs for PyMemoryView_FromBuffer() - PyMemoryView_FromBuffer() 
behavior change (possible regression)
type: enhancement - behavior
Added file: http://bugs.python.org/file27076/issue15821.diff

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15821
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15821] PyMemoryView_FromBuffer() behavior change (possible regression)

2012-08-31 Thread Alexander Belopolsky

Alexander Belopolsky added the comment:

On Fri, Aug 31, 2012 at 2:34 PM, Stefan Krah rep...@bugs.python.org wrote:
 With the ManagedBuffer, we could now write a new function that returns
 a memoryview with much nicer cleanup facilities. But that doesn't help
 here since we're stuck with this function for 3.3.0.


 What do you think? Should this go into 3.3.0?

I am still getting up to speed with all the changes that went in since
3.2.  I'll review your patch over the weekend.  Meanwhile, I think the
goal should be that after PyMemoryview_FromBuffer(info) is called, it
should be OK to discard info by calling PyBuffer_Release() and if info
is not allocated on the stack, Py_DECREF(info).  I think we are almost
there achieving that goal with possible exception of dynamically or
stack-allocated fmt strings.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15821
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15821] PyMemoryView_FromBuffer() behavior change (possible regression)

2012-08-31 Thread Stefan Krah

Stefan Krah added the comment:

Alexander Belopolsky rep...@bugs.python.org wrote:
 I am still getting up to speed with all the changes that went in since
 3.2.  I'll review your patch over the weekend.  Meanwhile, I think the
 goal should be that after PyMemoryview_FromBuffer(info) is called, it
 should be OK to discard info by calling PyBuffer_Release()

Now I'm puzzled: I thought your goal was to preserve the implicit cleanup
from 3.2, i.e. PyBuffer_Release() is called when the managed buffer is
deallocated.

Without the patch it's OK to call PyBuffer_Release(info) after
PyMemoryview_FromBuffer(info). With the patch you can't call
PyBuffer_Release(info), since it's done automatically already.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15821
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15821] PyMemoryView_FromBuffer() behavior change (possible regression)

2012-08-31 Thread Alexander Belopolsky

Alexander Belopolsky added the comment:

On Fri, Aug 31, 2012 at 3:12 PM, Stefan Krah rep...@bugs.python.org wrote:
 Now I'm puzzled: I thought your goal was to preserve the implicit cleanup
 from 3.2, i.e. PyBuffer_Release() is called when the managed buffer is
 deallocated.


The issue that I raised in msg169472 above was that
PyMemoryView_FromBuffer() would not copy .obj from Py_buffer structure
to the memoryview.  A related issue is that it looks like
PyObject_GetBuffer() often does not fill .obj either.   I would expect
that PyObject_GetBuffer() would always store a new reference in .obj
to assure that the .buf pointer remains valid until PyBuffer_Release()
is called explicitly.  (I am ignoring the issue of mutable objects
such as lists for the moment.)   PyMemoryView_FromBuffer() in turn
should store an additional reference in its own private copy of
Py_buffer structure.  After PyMemoryView_FromBuffer() returns a
well-behaved program should call PyBuffer_Release() releasing the
first reference and the second reference should be released in
memoryview destructor.  Am I missing something?

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15821
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15821] PyMemoryView_FromBuffer() behavior change (possible regression)

2012-08-31 Thread Alexander Belopolsky

Alexander Belopolsky added the comment:

Here is what I think the test case should look like (untested):


static PyObject *
memoryview_from_buffer_cleanup(PyObject *self, PyObject *noargs)
{
PyObject *b, *view = NULL;
Py_buffer info;
Py_ssize_t shape[3] = {2, 2, 3};
Py_ssize_t strides[3] = {6, 3, 1};
const char *cp = abcdefghijkl;

b = PyBytes_FromString(cp);
if (b == NULL)
return NULL;

if (PyObject_GetBuffer(b, info, PyBUF_FULL_RO)  0)
goto done;
/* reshape */
info.ndim = 3;
info.shape = shape;
info.strides = strides;

view = PyMemoryView_FromBuffer(info);
/* release resources allocated for Py_buffer struct 
   before it goes out of scope */
PyBuffer_Release(info);
 done:
Py_DECREF(b);
return view;
}

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15821
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com