summaryrefslogtreecommitdiff
path: root/docs/examples/tutorial/clibraries
diff options
context:
space:
mode:
Diffstat (limited to 'docs/examples/tutorial/clibraries')
-rw-r--r--docs/examples/tutorial/clibraries/cqueue.pxd2
-rw-r--r--docs/examples/tutorial/clibraries/queue.py8
-rw-r--r--docs/examples/tutorial/clibraries/queue.pyx17
-rw-r--r--docs/examples/tutorial/clibraries/queue2.py10
-rw-r--r--docs/examples/tutorial/clibraries/queue2.pyx21
-rw-r--r--docs/examples/tutorial/clibraries/queue3.py68
-rw-r--r--docs/examples/tutorial/clibraries/queue3.pyx11
-rw-r--r--docs/examples/tutorial/clibraries/test_queue.py72
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())