Closes #22668: Merge from 3.4.

This commit is contained in:
Stefan Krah 2015-01-29 14:29:51 +01:00
commit f5324d7074
5 changed files with 78 additions and 9 deletions

View File

@ -485,6 +485,12 @@ Changes in the Python API
Changes in the C API
--------------------
* The undocumented :c:member:`~PyMemoryViewObject.format` member of the
(non-public) :c:type:`PyMemoryViewObject` structure has been removed.
All extensions relying on the relevant parts in ``memoryobject.h``
must be rebuilt.
* The :c:type:`PyMemAllocator` structure was renamed to
:c:type:`PyMemAllocatorEx` and a new ``calloc`` field was added.

View File

@ -45,9 +45,6 @@ typedef struct {
} _PyManagedBufferObject;
/* static storage used for casting between formats */
#define _Py_MEMORYVIEW_MAX_FORMAT 3 /* must be >= 3 */
/* memoryview state flags */
#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */
#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */
@ -62,7 +59,6 @@ typedef struct {
int flags; /* state flags */
Py_ssize_t exports; /* number of buffer re-exports */
Py_buffer view; /* private copy of the exporter's view */
char format[_Py_MEMORYVIEW_MAX_FORMAT]; /* used for casting */
PyObject *weakreflist;
Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */
} PyMemoryViewObject;

View File

@ -360,6 +360,25 @@ class AbstractMemoryTests:
self.assertEqual(list(reversed(m)), aslist)
self.assertEqual(list(reversed(m)), list(m[::-1]))
def test_issue22668(self):
m = memoryview(bytes(range(8)))
b = m.cast('H')
c = b[0:2]
d = memoryview(b)
del b
self.assertEqual(c[0], 256)
self.assertEqual(d[0], 256)
self.assertEqual(c.format, "H")
self.assertEqual(d.format, "H")
_ = m.cast('I')
self.assertEqual(c[0], 256)
self.assertEqual(d[0], 256)
self.assertEqual(c.format, "H")
self.assertEqual(d.format, "H")
# Variations on source objects for the buffer: bytes-like objects, then arrays
# with itemsize > 1.

View File

@ -965,7 +965,7 @@ class SizeofTest(unittest.TestCase):
check(int(PyLong_BASE**2-1), vsize('') + 2*self.longdigit)
check(int(PyLong_BASE**2), vsize('') + 3*self.longdigit)
# memoryview
check(memoryview(b''), size('Pnin 2P2n2i5P 3cPn'))
check(memoryview(b''), size('Pnin 2P2n2i5P Pn'))
# module
check(unittest, size('PnPPP'))
# None

View File

@ -1132,6 +1132,51 @@ get_native_fmtchar(char *result, const char *fmt)
return -1;
}
Py_LOCAL_INLINE(char *)
get_native_fmtstr(const char *fmt)
{
int at = 0;
if (fmt[0] == '@') {
at = 1;
fmt++;
}
if (fmt[0] == '\0' || fmt[1] != '\0') {
return NULL;
}
#define RETURN(s) do { return at ? "@" s : s; } while (0)
switch (fmt[0]) {
case 'c': RETURN("c");
case 'b': RETURN("b");
case 'B': RETURN("B");
case 'h': RETURN("h");
case 'H': RETURN("H");
case 'i': RETURN("i");
case 'I': RETURN("I");
case 'l': RETURN("l");
case 'L': RETURN("L");
#ifdef HAVE_LONG_LONG
case 'q': RETURN("q");
case 'Q': RETURN("Q");
#endif
case 'n': RETURN("n");
case 'N': RETURN("N");
case 'f': RETURN("f");
case 'd': RETURN("d");
#ifdef HAVE_C99_BOOL
case '?': RETURN("?");
#else
case '?': RETURN("?");
#endif
case 'P': RETURN("P");
}
return NULL;
}
/* Cast a memoryview's data type to 'format'. The input array must be
C-contiguous. At least one of input-format, output-format must have
byte size. The output array is 1-D, with the same byte length as the
@ -1181,10 +1226,13 @@ cast_to_1D(PyMemoryViewObject *mv, PyObject *format)
goto out;
}
strncpy(mv->format, PyBytes_AS_STRING(asciifmt),
_Py_MEMORYVIEW_MAX_FORMAT);
mv->format[_Py_MEMORYVIEW_MAX_FORMAT-1] = '\0';
view->format = mv->format;
view->format = get_native_fmtstr(PyBytes_AS_STRING(asciifmt));
if (view->format == NULL) {
/* NOT_REACHED: get_native_fmtchar() already validates the format. */
PyErr_SetString(PyExc_RuntimeError,
"memoryview: internal error");
goto out;
}
view->itemsize = itemsize;
view->ndim = 1;