summaryrefslogtreecommitdiff
path: root/docs/src/tutorial/clibraries.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/src/tutorial/clibraries.rst')
-rw-r--r--docs/src/tutorial/clibraries.rst37
1 files changed, 10 insertions, 27 deletions
diff --git a/docs/src/tutorial/clibraries.rst b/docs/src/tutorial/clibraries.rst
index ddc02f443..3542dbe8e 100644
--- a/docs/src/tutorial/clibraries.rst
+++ b/docs/src/tutorial/clibraries.rst
@@ -125,9 +125,6 @@ Here is a first start for the Queue class:
.. literalinclude:: ../../examples/tutorial/clibraries/queue.py
:caption: queue.py
- .. note:: Currently, Cython contains a bug not allowing using
- annotations with types containing pointers (GitHub issue :issue:`4293`).
-
.. group-tab:: Cython
.. literalinclude:: ../../examples/tutorial/clibraries/queue.pyx
@@ -584,7 +581,6 @@ and check if the queue really is empty or not:
.. code-block:: python
@cython.cfunc
- @cython.exceptval(-1, check=True)
def peek(self) -> cython.int:
value: cython.int = cython.cast(cython.Py_ssize_t, cqueue.queue_peek_head(self._c_queue))
if value == 0:
@@ -598,7 +594,7 @@ and check if the queue really is empty or not:
.. code-block:: cython
- cdef int peek(self) except? -1:
+ cdef int peek(self):
cdef int value = <Py_ssize_t>cqueue.queue_peek_head(self._c_queue)
if value == 0:
# this may mean that the queue is empty, or
@@ -611,39 +607,27 @@ Note how we have effectively created a fast path through the method in
the hopefully common cases that the return value is not ``0``. Only
that specific case needs an additional check if the queue is empty.
-The ``except? -1`` or ``@cython.exceptval(-1, check=True)`` declaration
-in the method signature falls into the
-same category. If the function was a Python function returning a
+If the ``peek`` function was a Python function returning a
Python object value, CPython would simply return ``NULL`` internally
instead of a Python object to indicate an exception, which would
immediately be propagated by the surrounding code. The problem is
that the return type is ``int`` and any ``int`` value is a valid queue
item value, so there is no way to explicitly signal an error to the
-calling code. In fact, without such a declaration, there is no
-obvious way for Cython to know what to return on exceptions and for
-calling code to even know that this method *may* exit with an
-exception.
+calling code.
The only way calling code can deal with this situation is to call
``PyErr_Occurred()`` when returning from a function to check if an
exception was raised, and if so, propagate the exception. This
-obviously has a performance penalty. Cython therefore allows you to
-declare which value it should implicitly return in the case of an
+obviously has a performance penalty. Cython therefore uses a dedicated value
+that it implicitly returns in the case of an
exception, so that the surrounding code only needs to check for an
exception when receiving this exact value.
-We chose to use ``-1`` as the exception return value as we expect it
-to be an unlikely value to be put into the queue. The question mark
-in the ``except? -1`` declaration and ``check=True`` in ``@cython.exceptval``
-indicates that the return value is
-ambiguous (there *may* be a ``-1`` value in the queue, after all) and
-that an additional exception check using ``PyErr_Occurred()`` is
-needed in calling code. Without it, Cython code that calls this
-method and receives the exception return value would silently (and
-sometimes incorrectly) assume that an exception has been raised. In
-any case, all other return values will be passed through almost
+By default, the value ``-1`` is used as the exception return value.
+All other return values will be passed through almost
without a penalty, thus again creating a fast path for 'normal'
-values.
+values. See :ref:`error_return_values` for more details.
+
Now that the ``peek()`` method is implemented, the ``pop()`` method
also needs adaptation. Since it removes a value from the queue,
@@ -657,7 +641,6 @@ removal. Instead, we must test it on entry:
.. code-block:: python
@cython.cfunc
- @cython.exceptval(-1, check=True)
def pop(self) -> cython.int:
if cqueue.queue_is_empty(self._c_queue):
raise IndexError("Queue is empty")
@@ -667,7 +650,7 @@ removal. Instead, we must test it on entry:
.. code-block:: cython
- cdef int pop(self) except? -1:
+ cdef int pop(self):
if cqueue.queue_is_empty(self._c_queue):
raise IndexError("Queue is empty")
return <Py_ssize_t>cqueue.queue_pop_head(self._c_queue)