diff options
author | gabrieldemarmiesse <gabriel.demarmiesse@teraki.com> | 2018-06-13 15:43:12 +0200 |
---|---|---|
committer | gabrieldemarmiesse <gabriel.demarmiesse@teraki.com> | 2018-06-13 15:43:12 +0200 |
commit | 8e3a8af1a6ddcb4c9b42df962fdc6fb14b0671ea (patch) | |
tree | 89aec458a2647162ad1acc7ccb221cdc0b96499e | |
parent | 5fadf79efd37273873c1be2353969445118ed903 (diff) | |
download | cython-8e3a8af1a6ddcb4c9b42df962fdc6fb14b0671ea.tar.gz |
Added tests for some of the code snippets in "calling C libraries". Fixed a forgotten import.
-rw-r--r-- | docs/examples/tutorial/clibraries/c-algorithms/src/queue.h | 17 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/cqueue.pxd | 19 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/queue.pyx | 9 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/queue2.pyx | 11 | ||||
-rw-r--r-- | docs/examples/tutorial/clibraries/test_queue.py | 36 | ||||
-rw-r--r-- | docs/src/tutorial/clibraries.rst | 104 |
6 files changed, 103 insertions, 93 deletions
diff --git a/docs/examples/tutorial/clibraries/c-algorithms/src/queue.h b/docs/examples/tutorial/clibraries/c-algorithms/src/queue.h new file mode 100644 index 000000000..642bf54af --- /dev/null +++ b/docs/examples/tutorial/clibraries/c-algorithms/src/queue.h @@ -0,0 +1,17 @@ +/* queue.h */
+
+typedef struct _Queue Queue;
+typedef void *QueueValue;
+
+Queue *queue_new(void);
+void queue_free(Queue *queue);
+
+int queue_push_head(Queue *queue, QueueValue data);
+QueueValue queue_pop_head(Queue *queue);
+QueueValue queue_peek_head(Queue *queue);
+
+int queue_push_tail(Queue *queue, QueueValue data);
+QueueValue queue_pop_tail(Queue *queue);
+QueueValue queue_peek_tail(Queue *queue);
+
+int queue_is_empty(Queue *queue);
diff --git a/docs/examples/tutorial/clibraries/cqueue.pxd b/docs/examples/tutorial/clibraries/cqueue.pxd new file mode 100644 index 000000000..13a07d317 --- /dev/null +++ b/docs/examples/tutorial/clibraries/cqueue.pxd @@ -0,0 +1,19 @@ +# cqueue.pxd
+
+cdef extern from "c-algorithms/src/queue.h":
+ ctypedef struct Queue:
+ pass
+ ctypedef void* QueueValue
+
+ Queue* queue_new()
+ void queue_free(Queue* queue)
+
+ int queue_push_head(Queue* queue, QueueValue data)
+ QueueValue queue_pop_head(Queue* queue)
+ QueueValue queue_peek_head(Queue* queue)
+
+ int queue_push_tail(Queue* queue, QueueValue data)
+ QueueValue queue_pop_tail(Queue* queue)
+ QueueValue queue_peek_tail(Queue* queue)
+
+ bint queue_is_empty(Queue* queue)
diff --git a/docs/examples/tutorial/clibraries/queue.pyx b/docs/examples/tutorial/clibraries/queue.pyx new file mode 100644 index 000000000..5363ee4f5 --- /dev/null +++ b/docs/examples/tutorial/clibraries/queue.pyx @@ -0,0 +1,9 @@ +# queue.pyx
+
+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.pyx b/docs/examples/tutorial/clibraries/queue2.pyx new file mode 100644 index 000000000..9278fbf4b --- /dev/null +++ b/docs/examples/tutorial/clibraries/queue2.pyx @@ -0,0 +1,11 @@ +# 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()
diff --git a/docs/examples/tutorial/clibraries/test_queue.py b/docs/examples/tutorial/clibraries/test_queue.py new file mode 100644 index 000000000..5390a82c1 --- /dev/null +++ b/docs/examples/tutorial/clibraries/test_queue.py @@ -0,0 +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())
diff --git a/docs/src/tutorial/clibraries.rst b/docs/src/tutorial/clibraries.rst index 34c4d9bfb..9b779370d 100644 --- a/docs/src/tutorial/clibraries.rst +++ b/docs/src/tutorial/clibraries.rst @@ -33,48 +33,15 @@ Defining external declarations You can download CAlg `here <https://github.com/fragglet/c-algorithms/archive/master.zip>`_. The C API of the queue implementation, which is defined in the header -file ``c-algorithms/src/queue.h``, essentially looks like this:: +file ``c-algorithms/src/queue.h``, essentially looks like this: - /* file: queue.h */ - - typedef struct _Queue Queue; - typedef void *QueueValue; - - Queue *queue_new(void); - void queue_free(Queue *queue); - - int queue_push_head(Queue *queue, QueueValue data); - QueueValue queue_pop_head(Queue *queue); - QueueValue queue_peek_head(Queue *queue); - - int queue_push_tail(Queue *queue, QueueValue data); - QueueValue queue_pop_tail(Queue *queue); - QueueValue queue_peek_tail(Queue *queue); - - int queue_is_empty(Queue *queue); +.. literalinclude:: ../../examples/tutorial/clibraries/c-algorithms/src/queue.h + :language: C To get started, the first step is to redefine the C API in a ``.pxd`` -file, say, ``cqueue.pxd``:: - - # file: cqueue.pxd - - cdef extern from "c-algorithms/src/queue.h": - ctypedef struct Queue: - pass - ctypedef void* QueueValue - - Queue* queue_new() - void queue_free(Queue* queue) - - int queue_push_head(Queue* queue, QueueValue data) - QueueValue queue_pop_head(Queue* queue) - QueueValue queue_peek_head(Queue* queue) - - int queue_push_tail(Queue* queue, QueueValue data) - QueueValue queue_pop_tail(Queue* queue) - QueueValue queue_peek_tail(Queue* queue) +file, say, ``cqueue.pxd``: - bint queue_is_empty(Queue* queue) +.. literalinclude:: ../../examples/tutorial/clibraries/cqueue.pxd Note how these declarations are almost identical to the header file declarations, so you can often just copy them over. However, you do @@ -144,16 +111,9 @@ class that should wrap the C queue. It will live in a file called library, there must not be a ``.pyx`` file with the same name that Cython associates with it. -Here is a first start for the Queue class:: +Here is a first start for the Queue class: - # file: queue.pyx - - cimport cqueue - - cdef class Queue: - cdef cqueue.Queue* _c_queue - def __cinit__(self): - self._c_queue = cqueue.queue_new() +.. literalinclude:: ../../examples/tutorial/clibraries/queue.pyx Note that it says ``__cinit__`` rather than ``__init__``. While ``__init__`` is available as well, it is not guaranteed to be run (for @@ -190,16 +150,9 @@ that case, it will return ``NULL``, whereas it would normally return a pointer to the new queue. The Python way to get out of this is to raise a ``MemoryError`` [#]_. -We can thus change the init function as follows:: - - cimport cqueue +We can thus change the init function as follows: - 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() +.. literalinclude:: ../../examples/tutorial/clibraries/queue2.pyx .. [#] In the specific case of a ``MemoryError``, creating a new exception instance in order to raise it may actually fail because @@ -587,44 +540,9 @@ instead that accepts an arbitrary Python iterable:: Now we can test our Queue implementation using a python script, -for example here :file:`test_queue.py`.:: - - from __future__ import print_function - - 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()) +for example here :file:`test_queue.py`: +.. literalinclude:: ../../examples/tutorial/clibraries/test_queue.py As a quick test with 10000 numbers on the author's machine indicates, using this Queue from Cython code with C ``int`` values is about five |