From 7498f3c2fc49160739d72fa33e976912a5c7aa0a Mon Sep 17 00:00:00 2001
From: Dag Sverre Seljebotn <dagss@student.matnat.uio.no>
Date: Mon, 4 Aug 2008 19:01:10 +0200
Subject: [PATCH] Buffer stuff: Patching suboffsets back to NULL if that was
 what we retrieved, just to be more predictable.

---
 Cython/Compiler/Buffer.py | 10 ++++++++--
 tests/run/bufaccess.pyx   | 10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/Cython/Compiler/Buffer.py b/Cython/Compiler/Buffer.py
index 6e591c97..edf56965 100644
--- a/Cython/Compiler/Buffer.py
+++ b/Cython/Compiler/Buffer.py
@@ -157,7 +157,7 @@ def put_acquire_arg_buffer(entry, code, pos):
 #        entry.buffer_aux.buffer_info_var.cname))
 
 def get_release_buffer_code(entry):
-    return "if (%s != Py_None) PyObject_ReleaseBuffer(%s, &%s)" % (
+    return "if (%s != Py_None) __Pyx_ReleaseBuffer(%s, &%s)" % (
         entry.cname,
         entry.cname,
         entry.buffer_aux.buffer_info_var.cname)
@@ -192,7 +192,7 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type,
         # Release any existing buffer
         code.put('if (%s != Py_None) ' % lhs_cname)
         code.begin_block();
-        code.putln('PyObject_ReleaseBuffer(%s, &%s);' % (
+        code.putln('__Pyx_ReleaseBuffer(%s, &%s);' % (
             lhs_cname, bufstruct))
         code.end_block()
         # Acquire
@@ -551,11 +551,17 @@ static void __Pyx_RaiseBufferIndexError(int axis) {
 # exporter.
 #
 acquire_utility_code = ["""\
+static INLINE void __Pyx_ReleaseBuffer(PyObject* obj, Py_buffer* info);
 static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf); /*proto*/
 static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts); /*proto*/
 static INLINE const char* __Pyx_BufferTypestringCheckEndian(const char* ts); /*proto*/
 static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim); /*proto*/
 """, """
+static INLINE void __Pyx_ReleaseBuffer(PyObject* obj, Py_buffer* info) {
+  if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+  PyObject_ReleaseBuffer(obj, info);
+}
+
 static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
   buf->buf = NULL;
   buf->strides = __Pyx_zeros;
diff --git a/tests/run/bufaccess.pyx b/tests/run/bufaccess.pyx
index d7a04778..42799301 100644
--- a/tests/run/bufaccess.pyx
+++ b/tests/run/bufaccess.pyx
@@ -354,7 +354,6 @@ def get_int_2d(object[int, 2] buf, int i, int j):
     Traceback (most recent call last):
         ...
     IndexError: Out of bounds on buffer access (axis 1)
-    
     """
     return buf[i, j]
 
@@ -500,6 +499,10 @@ def strided(object[int, 1, 'strided'] buf):
     2
     >>> A.recieved_flags
     ['FORMAT', 'ND', 'STRIDES']
+
+    Check that the suboffsets were patched back prior to release.
+    >>> A.release_ok
+    True
     """
     return buf[2]
 
@@ -663,11 +666,12 @@ cdef class MockBuffer:
     cdef Py_ssize_t* suboffsets
     cdef object label, log
     
-    cdef readonly object recieved_flags
+    cdef readonly object recieved_flags, release_ok
     cdef public object fail
     
     def __init__(self, label, data, shape=None, strides=None, format=None):
         self.label = label
+        self.release_ok = True
         self.log = ""
         self.itemsize = self.get_itemsize()
         if format is None: format = self.get_default_format()
@@ -776,6 +780,8 @@ cdef class MockBuffer:
         self.log += msg + "\n"
 
     def __releasebuffer__(MockBuffer self, Py_buffer* buffer):
+        if buffer.suboffsets != self.suboffsets:
+            self.release_ok = False
         msg = "released %s" % self.label
         print msg 
         self.log += msg + "\n"
-- 
2.26.2