Commit b62d8ba5 authored by Stefan Behnel's avatar Stefan Behnel

Merge branch '0.29.x'

parents d10c07a6 0041db28
...@@ -3466,8 +3466,8 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3466,8 +3466,8 @@ class DefNodeWrapper(FuncDefNode):
if docstr.is_unicode: if docstr.is_unicode:
docstr = docstr.as_utf8_string() docstr = docstr.as_utf8_string()
code.putln( if with_pymethdef:
'static char %s[] = %s;' % ( code.putln('static char %s[] = %s;' % (
entry.doc_cname, entry.doc_cname,
docstr.as_c_string_literal())) docstr.as_c_string_literal()))
......
...@@ -1216,7 +1216,7 @@ static int __pyx_FusedFunction_init(void) { ...@@ -1216,7 +1216,7 @@ static int __pyx_FusedFunction_init(void) {
//////////////////// ClassMethod.proto //////////////////// //////////////////// ClassMethod.proto ////////////////////
#include "descrobject.h" #include "descrobject.h"
static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/ static CYTHON_UNUSED PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
//////////////////// ClassMethod //////////////////// //////////////////// ClassMethod ////////////////////
......
...@@ -123,13 +123,13 @@ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ...@@ -123,13 +123,13 @@ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t
#define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \ #define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \
(likely(PyList_CheckExact(L) && __Pyx_fits_Py_ssize_t(ix, type, is_signed))) ? \ (likely(PyList_CheckExact(L) && __Pyx_fits_Py_ssize_t(ix, type, is_signed))) ? \
__Pyx__PyList_PopIndex(L, py_ix, ix) : ( \ __Pyx__PyList_PopIndex(L, py_ix, ix) : ( \
(unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \ (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \
__Pyx__PyObject_PopIndex(L, py_ix))) __Pyx__PyObject_PopIndex(L, py_ix)))
#define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \ #define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \
__Pyx_fits_Py_ssize_t(ix, type, is_signed) ? \ __Pyx_fits_Py_ssize_t(ix, type, is_signed) ? \
__Pyx__PyList_PopIndex(L, py_ix, ix) : ( \ __Pyx__PyList_PopIndex(L, py_ix, ix) : ( \
(unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \ (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \
__Pyx__PyObject_PopIndex(L, py_ix))) __Pyx__PyObject_PopIndex(L, py_ix)))
#else #else
...@@ -138,7 +138,7 @@ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ...@@ -138,7 +138,7 @@ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t
__Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func)
#define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \ #define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \
(unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \ (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \
__Pyx__PyObject_PopIndex(L, py_ix)) __Pyx__PyObject_PopIndex(L, py_ix))
#endif #endif
......
# queue.pyx # queue.pyx
cimport cqueue cimport cqueue
cdef class Queue: cdef class Queue:
"""A queue class for C integer values. """A queue class for C integer values.
>>> q = Queue() >>> q = Queue()
>>> q.append(5) >>> q.append(5)
>>> q.peek() >>> q.peek()
5 5
>>> q.pop() >>> q.pop()
5 5
""" """
cdef cqueue.Queue* _c_queue cdef cqueue.Queue* _c_queue
def __cinit__(self): def __cinit__(self):
self._c_queue = cqueue.queue_new() self._c_queue = cqueue.queue_new()
if self._c_queue is NULL: if self._c_queue is NULL:
raise MemoryError() raise MemoryError()
def __dealloc__(self): def __dealloc__(self):
if self._c_queue is not NULL: if self._c_queue is not NULL:
cqueue.queue_free(self._c_queue) cqueue.queue_free(self._c_queue)
cpdef append(self, int value): cpdef append(self, int value):
if not cqueue.queue_push_tail(self._c_queue, if not cqueue.queue_push_tail(self._c_queue,
<void*> value): <void*> <Py_ssize_t> value):
raise MemoryError() raise MemoryError()
# The `cpdef` feature is obviously not available for the original "extend()" # The `cpdef` feature is obviously not available for the original "extend()"
# method, as the method signature is incompatible with Python argument # method, as the method signature is incompatible with Python argument
# types (Python does not have pointers). However, we can rename # types (Python does not have pointers). However, we can rename
# the C-ish "extend()" method to e.g. "extend_ints()", and write # the C-ish "extend()" method to e.g. "extend_ints()", and write
# a new "extend()" method that provides a suitable Python interface by # a new "extend()" method that provides a suitable Python interface by
# accepting an arbitrary Python iterable. # accepting an arbitrary Python iterable.
cpdef extend(self, values): cpdef extend(self, values):
for value in values: for value in values:
self.append(value) self.append(value)
cdef extend_ints(self, int* values, size_t count): cdef extend_ints(self, int* values, size_t count):
cdef int value cdef int value
for value in values[:count]: # Slicing pointer to limit the iteration boundaries. for value in values[:count]: # Slicing pointer to limit the iteration boundaries.
self.append(value) self.append(value)
cpdef int peek(self) except? -1: cpdef int peek(self) except? -1:
cdef int value = <Py_ssize_t> cqueue.queue_peek_head(self._c_queue) cdef int value = <Py_ssize_t> cqueue.queue_peek_head(self._c_queue)
if value == 0: if value == 0:
# this may mean that the queue is empty, # this may mean that the queue is empty,
# or that it happens to contain a 0 value # or that it happens to contain a 0 value
if cqueue.queue_is_empty(self._c_queue): if cqueue.queue_is_empty(self._c_queue):
raise IndexError("Queue is empty") raise IndexError("Queue is empty")
return value return value
cpdef int pop(self) except? -1: cpdef int pop(self) except? -1:
if cqueue.queue_is_empty(self._c_queue): if cqueue.queue_is_empty(self._c_queue):
raise IndexError("Queue is empty") raise IndexError("Queue is empty")
return <Py_ssize_t> cqueue.queue_pop_head(self._c_queue) return <Py_ssize_t> cqueue.queue_pop_head(self._c_queue)
def __bool__(self): def __bool__(self):
return not cqueue.queue_is_empty(self._c_queue) return not cqueue.queue_is_empty(self._c_queue)
from cython.view cimport array as cvarray from cython.view cimport array as cvarray
import numpy as np import numpy as np
# Memoryview on a NumPy array # Memoryview on a NumPy array
narr = np.arange(27, dtype=np.dtype("i")).reshape((3, 3, 3)) narr = np.arange(27, dtype=np.dtype("i")).reshape((3, 3, 3))
cdef int [:, :, :] narr_view = narr cdef int [:, :, :] narr_view = narr
# Memoryview on a C array # Memoryview on a C array
cdef int carr[3][3][3] cdef int carr[3][3][3]
cdef int [:, :, :] carr_view = carr cdef int [:, :, :] carr_view = carr
# Memoryview on a Cython array # Memoryview on a Cython array
cyarr = cvarray(shape=(3, 3, 3), itemsize=sizeof(int), format="i") cyarr = cvarray(shape=(3, 3, 3), itemsize=sizeof(int), format="i")
cdef int [:, :, :] cyarr_view = cyarr cdef int [:, :, :] cyarr_view = cyarr
# Show the sum of all the arrays before altering it # Show the sum of all the arrays before altering it
print("NumPy sum of the NumPy array before assignments: %s" % narr.sum()) print("NumPy sum of the NumPy array before assignments: %s" % narr.sum())
# We can copy the values from one memoryview into another using a single # We can copy the values from one memoryview into another using a single
# statement, by either indexing with ... or (NumPy-style) with a colon. # statement, by either indexing with ... or (NumPy-style) with a colon.
carr_view[...] = narr_view carr_view[...] = narr_view
cyarr_view[:] = narr_view cyarr_view[:] = narr_view
# NumPy-style syntax for assigning a single value to all elements. # NumPy-style syntax for assigning a single value to all elements.
narr_view[:, :, :] = 3 narr_view[:, :, :] = 3
# Just to distinguish the arrays # Just to distinguish the arrays
carr_view[0, 0, 0] = 100 carr_view[0, 0, 0] = 100
cyarr_view[0, 0, 0] = 1000 cyarr_view[0, 0, 0] = 1000
# Assigning into the memoryview on the NumPy array alters the latter # Assigning into the memoryview on the NumPy array alters the latter
print("NumPy sum of NumPy array after assignments: %s" % narr.sum()) print("NumPy sum of NumPy array after assignments: %s" % narr.sum())
# A function using a memoryview does not usually need the GIL # A function using a memoryview does not usually need the GIL
cpdef int sum3d(int[:, :, :] arr) nogil: cpdef int sum3d(int[:, :, :] arr) nogil:
cdef size_t i, j, k cdef size_t i, j, k, I, J, K
cdef int total = 0 cdef int total = 0
I = arr.shape[0] I = arr.shape[0]
J = arr.shape[1] J = arr.shape[1]
K = arr.shape[2] K = arr.shape[2]
for i in range(I): for i in range(I):
for j in range(J): for j in range(J):
for k in range(K): for k in range(K):
total += arr[i, j, k] total += arr[i, j, k]
return total return total
# A function accepting a memoryview knows how to use a NumPy array, # A function accepting a memoryview knows how to use a NumPy array,
# a C array, a Cython array... # a C array, a Cython array...
print("Memoryview sum of NumPy array is %s" % sum3d(narr)) print("Memoryview sum of NumPy array is %s" % sum3d(narr))
print("Memoryview sum of C array is %s" % sum3d(carr)) print("Memoryview sum of C array is %s" % sum3d(carr))
print("Memoryview sum of Cython array is %s" % sum3d(cyarr)) print("Memoryview sum of Cython array is %s" % sum3d(cyarr))
# ... and of course, a memoryview. # ... and of course, a memoryview.
print("Memoryview sum of C memoryview is %s" % sum3d(carr_view)) print("Memoryview sum of C memoryview is %s" % sum3d(carr_view))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment