diff -r c0b0dda16009 Doc/c-api/buffer.rst --- a/Doc/c-api/buffer.rst Fri Sep 19 15:23:30 2014 +0800 +++ b/Doc/c-api/buffer.rst Sun Sep 21 13:32:27 2014 +0200 @@ -466,6 +466,9 @@ ``'C'``) or Fortran-style (*order* is ``'F'``) contiguous or either one (*order* is ``'A'``). Return 0 otherwise. + Note that buffers with zero length are always contiguous. Also + ``strides[i]`` may be arbitrary if ``shape[i] == 1``. + .. c:function:: void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char order) diff -r c0b0dda16009 Objects/abstract.c --- a/Objects/abstract.c Fri Sep 19 15:23:30 2014 +0800 +++ b/Objects/abstract.c Sun Sep 21 13:32:27 2014 +0200 @@ -368,15 +368,36 @@ Py_ssize_t sd, dim; int i; - if (view->ndim == 0) return 1; - if (view->strides == NULL) return (view->ndim == 1); + if (view->shape == NULL) { + if (view->ndim == 0) { + return 1; + } + else if (view->strides == NULL){ + return 1; + } + if (view->strides[0] == view->itemsize) { + return 1; + } + return 0; + } + + if (view->strides == NULL) { + /* By definition the buffer is C-contiguous, but it might be + both if it is effectively 1-d or empty. + */ + sd = 0; + for (i=0; i < view->ndim; i++) { + if (view->shape[i] == 0) return 1; + if (view->shape[i] != 1) sd += 1; + } + return sd <= 1; + } sd = view->itemsize; - if (view->ndim == 1) return (view->shape[0] == 1 || - sd == view->strides[0]); for (i=0; indim; i++) { dim = view->shape[i]; if (dim == 0) return 1; + if (dim == 1) continue; if (view->strides[i] != sd) return 0; sd *= dim; } @@ -389,15 +410,23 @@ Py_ssize_t sd, dim; int i; - if (view->ndim == 0) return 1; if (view->strides == NULL) return 1; + if (view->shape == NULL) { + if (view->ndim == 0) { + return 1; + } + if (view->strides[0] == view->itemsize) { + return 1; + } + return 0; + } + sd = view->itemsize; - if (view->ndim == 1) return (view->shape[0] == 1 || - sd == view->strides[0]); for (i=view->ndim-1; i>=0; i--) { dim = view->shape[i]; if (dim == 0) return 1; + if (dim == 1) continue; if (view->strides[i] != sd) return 0; sd *= dim; }