diff options
Diffstat (limited to 'docs/examples/tutorial/clibraries')
-rw-r--r-- | docs/examples/tutorial/clibraries/cqueue.pxd | 2 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/queue.py | 8 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/queue.pyx | 17 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/queue2.py | 10 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/queue2.pyx | 21 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/queue3.py | 68 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/queue3.pyx | 11 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/test_queue.py | 72 |
8 files changed, 149 insertions, 60 deletions
diff --git a/docs/examples/tutorial/clibraries/cqueue.pxd b/docs/examples/tutorial/clibraries/cqueue.pxd index 13a07d317..a657ae331 100644 --- a/docs/examples/tutorial/clibraries/cqueue.pxd +++ b/docs/examples/tutorial/clibraries/cqueue.pxd @@ -1,5 +1,3 @@ -# cqueue.pxd
-
cdef extern from "c-algorithms/src/queue.h":
ctypedef struct Queue:
pass
diff --git a/docs/examples/tutorial/clibraries/queue.py b/docs/examples/tutorial/clibraries/queue.py new file mode 100644 index 000000000..e99b9b32c --- /dev/null +++ b/docs/examples/tutorial/clibraries/queue.py @@ -0,0 +1,8 @@ +from cython.cimports import cqueue + +@cython.cclass +class Queue: + _c_queue: cython.pointer(cqueue.Queue) + + def __cinit__(self): + self._c_queue = cqueue.queue_new() diff --git a/docs/examples/tutorial/clibraries/queue.pyx b/docs/examples/tutorial/clibraries/queue.pyx index 5363ee4f5..654c07b8d 100644 --- a/docs/examples/tutorial/clibraries/queue.pyx +++ b/docs/examples/tutorial/clibraries/queue.pyx @@ -1,9 +1,8 @@ -# queue.pyx
-
-cimport cqueue
-
-cdef class Queue:
- cdef cqueue.Queue* _c_queue
-
- def __cinit__(self):
- self._c_queue = cqueue.queue_new()
+cimport cqueue + + +cdef class Queue: + cdef cqueue.Queue* _c_queue + + def __cinit__(self): + self._c_queue = cqueue.queue_new() diff --git a/docs/examples/tutorial/clibraries/queue2.py b/docs/examples/tutorial/clibraries/queue2.py new file mode 100644 index 000000000..de6d58a99 --- /dev/null +++ b/docs/examples/tutorial/clibraries/queue2.py @@ -0,0 +1,10 @@ +from cython.cimports import cqueue + +@cython.cclass +class Queue: + _c_queue = cython.declare(cython.pointer(cqueue.Queue)) + + def __cinit__(self): + self._c_queue = cqueue.queue_new() + if self._c_queue is cython.NULL: + raise MemoryError() diff --git a/docs/examples/tutorial/clibraries/queue2.pyx b/docs/examples/tutorial/clibraries/queue2.pyx index 9278fbf4b..5dca04c22 100644 --- a/docs/examples/tutorial/clibraries/queue2.pyx +++ b/docs/examples/tutorial/clibraries/queue2.pyx @@ -1,11 +1,10 @@ -# queue.pyx
-
-cimport cqueue
-
-cdef class Queue:
- cdef cqueue.Queue* _c_queue
-
- def __cinit__(self):
- self._c_queue = cqueue.queue_new()
- if self._c_queue is NULL:
- raise MemoryError()
+cimport cqueue + + +cdef class Queue: + cdef cqueue.Queue* _c_queue + + def __cinit__(self): + self._c_queue = cqueue.queue_new() + if self._c_queue is NULL: + raise MemoryError() diff --git a/docs/examples/tutorial/clibraries/queue3.py b/docs/examples/tutorial/clibraries/queue3.py new file mode 100644 index 000000000..79f341254 --- /dev/null +++ b/docs/examples/tutorial/clibraries/queue3.py @@ -0,0 +1,68 @@ +from cython.cimports import cqueue +from cython import cast + +@cython.cclass +class Queue: + """A queue class for C integer values. + + >>> q = Queue() + >>> q.append(5) + >>> q.peek() + 5 + >>> q.pop() + 5 + """ + _c_queue = cython.declare(cython.pointer(cqueue.Queue)) + def __cinit__(self): + self._c_queue = cqueue.queue_new() + if self._c_queue is cython.NULL: + raise MemoryError() + + def __dealloc__(self): + if self._c_queue is not cython.NULL: + cqueue.queue_free(self._c_queue) + + @cython.ccall + def append(self, value: cython.int): + if not cqueue.queue_push_tail(self._c_queue, + cast(cython.p_void, cast(cython.Py_ssize_t, value))): + raise MemoryError() + + # The `cpdef` feature is obviously not available for the original "extend()" + # method, as the method signature is incompatible with Python argument + # types (Python does not have pointers). However, we can rename + # the C-ish "extend()" method to e.g. "extend_ints()", and write + # a new "extend()" method that provides a suitable Python interface by + # accepting an arbitrary Python iterable. + @cython.ccall + def extend(self, values): + for value in values: + self.append(value) + + @cython.cfunc + def extend_ints(self, values: cython.p_int, count: cython.size_t): + value: cython.int + for value in values[:count]: # Slicing pointer to limit the iteration boundaries. + self.append(value) + + @cython.ccall + @cython.exceptval(-1, check=True) + def peek(self) -> cython.int: + value: cython.int = cast(cython.Py_ssize_t, cqueue.queue_peek_head(self._c_queue)) + + if value == 0: + # this may mean that the queue is empty, + # or that it happens to contain a 0 value + if cqueue.queue_is_empty(self._c_queue): + raise IndexError("Queue is empty") + return value + + @cython.ccall + @cython.exceptval(-1, check=True) + def pop(self) -> cython.int: + if cqueue.queue_is_empty(self._c_queue): + raise IndexError("Queue is empty") + return cast(cython.Py_ssize_t, cqueue.queue_pop_head(self._c_queue)) + + def __bool__(self): + return not cqueue.queue_is_empty(self._c_queue) diff --git a/docs/examples/tutorial/clibraries/queue3.pyx b/docs/examples/tutorial/clibraries/queue3.pyx index cc84cf172..c15c48e15 100644 --- a/docs/examples/tutorial/clibraries/queue3.pyx +++ b/docs/examples/tutorial/clibraries/queue3.pyx @@ -1,7 +1,7 @@ -# queue.pyx - cimport cqueue + + cdef class Queue: """A queue class for C integer values. @@ -22,6 +22,7 @@ cdef class Queue: if self._c_queue is not NULL: cqueue.queue_free(self._c_queue) + cpdef append(self, int value): if not cqueue.queue_push_tail(self._c_queue, <void*> <Py_ssize_t> value): @@ -33,15 +34,19 @@ cdef class Queue: # the C-ish "extend()" method to e.g. "extend_ints()", and write # a new "extend()" method that provides a suitable Python interface by # accepting an arbitrary Python iterable. + cpdef extend(self, values): for value in values: self.append(value) + cdef extend_ints(self, int* values, size_t count): cdef int value for value in values[:count]: # Slicing pointer to limit the iteration boundaries. self.append(value) + + cpdef int peek(self) except? -1: cdef int value = <Py_ssize_t> cqueue.queue_peek_head(self._c_queue) @@ -52,6 +57,8 @@ cdef class Queue: raise IndexError("Queue is empty") return value + + cpdef int pop(self) except? -1: if cqueue.queue_is_empty(self._c_queue): raise IndexError("Queue is empty") diff --git a/docs/examples/tutorial/clibraries/test_queue.py b/docs/examples/tutorial/clibraries/test_queue.py index 5390a82c1..41b267395 100644 --- a/docs/examples/tutorial/clibraries/test_queue.py +++ b/docs/examples/tutorial/clibraries/test_queue.py @@ -1,36 +1,36 @@ -from __future__ import print_function
-
-import time
-
-import queue
-
-Q = queue.Queue()
-
-Q.append(10)
-Q.append(20)
-print(Q.peek())
-print(Q.pop())
-print(Q.pop())
-try:
- print(Q.pop())
-except IndexError as e:
- print("Error message:", e) # Prints "Queue is empty"
-
-i = 10000
-
-values = range(i)
-
-start_time = time.time()
-
-Q.extend(values)
-
-end_time = time.time() - start_time
-
-print("Adding {} items took {:1.3f} msecs.".format(i, 1000 * end_time))
-
-for i in range(41):
- Q.pop()
-
-Q.pop()
-print("The answer is:")
-print(Q.pop())
+from __future__ import print_function + +import time + +import queue + +Q = queue.Queue() + +Q.append(10) +Q.append(20) +print(Q.peek()) +print(Q.pop()) +print(Q.pop()) +try: + print(Q.pop()) +except IndexError as e: + print("Error message:", e) # Prints "Queue is empty" + +i = 10000 + +values = range(i) + +start_time = time.time() + +Q.extend(values) + +end_time = time.time() - start_time + +print("Adding {} items took {:1.3f} msecs.".format(i, 1000 * end_time)) + +for i in range(41): + Q.pop() + +Q.pop() +print("The answer is:") +print(Q.pop()) |