summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatus Valo <matusvalo@users.noreply.github.com>2021-07-14 16:19:26 +0200
committerGitHub <noreply@github.com>2021-07-14 16:19:26 +0200
commit696a1959b44ca9028d3f9468723b6b24335ad921 (patch)
tree362f699d64a6bf203dfa934c4e555e49d33ebe31
parent8552e3d3ffe9fe4f3f8dab82119ed839990dadda (diff)
downloadcython-696a1959b44ca9028d3f9468723b6b24335ad921.tar.gz
docs: Add Pure Python mode to "Calling C functions" tutorial (GH-4247)
-rw-r--r--docs/examples/tutorial/external/atoi.py6
-rw-r--r--docs/examples/tutorial/external/atoi.pyx1
-rw-r--r--docs/examples/tutorial/external/keyword_args_call.py8
-rw-r--r--docs/examples/tutorial/external/keyword_args_call.pyx1
-rw-r--r--docs/examples/tutorial/external/libc_sin.py5
-rw-r--r--docs/examples/tutorial/external/libc_sin.pyx1
-rw-r--r--docs/examples/tutorial/external/py_version_hex.py4
-rw-r--r--docs/examples/tutorial/external/strstr.pxd2
-rw-r--r--docs/src/tutorial/external.rst55
9 files changed, 79 insertions, 4 deletions
diff --git a/docs/examples/tutorial/external/atoi.py b/docs/examples/tutorial/external/atoi.py
new file mode 100644
index 000000000..250b26a5c
--- /dev/null
+++ b/docs/examples/tutorial/external/atoi.py
@@ -0,0 +1,6 @@
+from cython.cimports.libc.stdlib import atoi
+
+@cython.cfunc
+def parse_charptr_to_py_int(s: cython.p_char):
+ assert s is not cython.NULL, "byte string value is NULL"
+ return atoi(s) # note: atoi() has no error detection!
diff --git a/docs/examples/tutorial/external/atoi.pyx b/docs/examples/tutorial/external/atoi.pyx
index 96a67d73c..ef1219854 100644
--- a/docs/examples/tutorial/external/atoi.pyx
+++ b/docs/examples/tutorial/external/atoi.pyx
@@ -1,5 +1,6 @@
from libc.stdlib cimport atoi
+
cdef parse_charptr_to_py_int(char* s):
assert s is not NULL, "byte string value is NULL"
return atoi(s) # note: atoi() has no error detection!
diff --git a/docs/examples/tutorial/external/keyword_args_call.py b/docs/examples/tutorial/external/keyword_args_call.py
new file mode 100644
index 000000000..af5b06020
--- /dev/null
+++ b/docs/examples/tutorial/external/keyword_args_call.py
@@ -0,0 +1,8 @@
+import cython
+from cython.cimports.strstr import strstr
+
+def main():
+ data: p_char = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh"
+
+ pos: p_char = strstr(needle='akd', haystack=data)
+ print(pos is not cython.NULL)
diff --git a/docs/examples/tutorial/external/keyword_args_call.pyx b/docs/examples/tutorial/external/keyword_args_call.pyx
index de2b6f2b2..3a6b85c8b 100644
--- a/docs/examples/tutorial/external/keyword_args_call.pyx
+++ b/docs/examples/tutorial/external/keyword_args_call.pyx
@@ -1,6 +1,7 @@
cdef extern from "string.h":
char* strstr(const char *haystack, const char *needle)
+
cdef char* data = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh"
cdef char* pos = strstr(needle='akd', haystack=data)
diff --git a/docs/examples/tutorial/external/libc_sin.py b/docs/examples/tutorial/external/libc_sin.py
new file mode 100644
index 000000000..f4223253d
--- /dev/null
+++ b/docs/examples/tutorial/external/libc_sin.py
@@ -0,0 +1,5 @@
+from cython.cimports.libc.math import sin
+
+@cython.cfunc
+def f(x: cython.double) -> cython.double:
+ return sin(x * x)
diff --git a/docs/examples/tutorial/external/libc_sin.pyx b/docs/examples/tutorial/external/libc_sin.pyx
index fb247c03d..2de8444d6 100644
--- a/docs/examples/tutorial/external/libc_sin.pyx
+++ b/docs/examples/tutorial/external/libc_sin.pyx
@@ -1,4 +1,5 @@
from libc.math cimport sin
+
cdef double f(double x):
return sin(x * x)
diff --git a/docs/examples/tutorial/external/py_version_hex.py b/docs/examples/tutorial/external/py_version_hex.py
new file mode 100644
index 000000000..3b19d0d02
--- /dev/null
+++ b/docs/examples/tutorial/external/py_version_hex.py
@@ -0,0 +1,4 @@
+from cython.cimports.cpython.version import PY_VERSION_HEX
+
+# Python version >= 3.2 final ?
+print(PY_VERSION_HEX >= 0x030200F0)
diff --git a/docs/examples/tutorial/external/strstr.pxd b/docs/examples/tutorial/external/strstr.pxd
new file mode 100644
index 000000000..7c2a786cc
--- /dev/null
+++ b/docs/examples/tutorial/external/strstr.pxd
@@ -0,0 +1,2 @@
+cdef extern from "string.h":
+ char* strstr(const char *haystack, const char *needle)
diff --git a/docs/src/tutorial/external.rst b/docs/src/tutorial/external.rst
index 83ec75375..d0c5af0a0 100644
--- a/docs/src/tutorial/external.rst
+++ b/docs/src/tutorial/external.rst
@@ -1,6 +1,9 @@
Calling C functions
====================
+.. include::
+ ../two-syntax-variants-used
+
This tutorial describes shortly what you need to know in order to call
C library functions from Cython code. For a longer and more
comprehensive tutorial about using external C libraries, wrapping them
@@ -15,7 +18,17 @@ For example, let's say you need a low-level way to parse a number from
a ``char*`` value. You could use the ``atoi()`` function, as defined
by the ``stdlib.h`` header file. This can be done as follows:
-.. literalinclude:: ../../examples/tutorial/external/atoi.pyx
+.. tabs::
+
+ .. group-tab:: Pure Python
+
+ .. literalinclude:: ../../examples/tutorial/external/atoi.py
+ :caption: atoi.py
+
+ .. group-tab:: Cython
+
+ .. literalinclude:: ../../examples/tutorial/external/atoi.pyx
+ :caption: atoi.pyx
You can find a complete list of these standard cimport files in
Cython's source package
@@ -28,14 +41,33 @@ Cython also has a complete set of declarations for CPython's C-API.
For example, to test at C compilation time which CPython version
your code is being compiled with, you can do this:
-.. literalinclude:: ../../examples/tutorial/external/py_version_hex.pyx
+.. tabs::
+
+ .. group-tab:: Pure Python
+
+ .. literalinclude:: ../../examples/tutorial/external/py_version_hex.py
+ :caption: py_version_hex.py
+
+ .. group-tab:: Cython
+
+ .. literalinclude:: ../../examples/tutorial/external/py_version_hex.pyx
+ :caption: py_version_hex.pyx
.. _libc.math:
Cython also provides declarations for the C math library:
-.. literalinclude:: ../../examples/tutorial/external/libc_sin.pyx
+.. tabs::
+ .. group-tab:: Pure Python
+
+ .. literalinclude:: ../../examples/tutorial/external/libc_sin.py
+ :caption: libc_sin.py
+
+ .. group-tab:: Cython
+
+ .. literalinclude:: ../../examples/tutorial/external/libc_sin.pyx
+ :caption: libc_sin.pyx
Dynamic linking
---------------
@@ -83,6 +115,9 @@ This allows the C declaration to be reused in other Cython modules,
while still providing an automatically generated Python wrapper in
this specific module.
+.. note:: External declarations must be placed in a ``.pxd`` file in Pure
+ Python mode.
+
Naming parameters
-----------------
@@ -103,7 +138,19 @@ You can now make it clear which of the two arguments does what in
your call, thus avoiding any ambiguities and often making your code
more readable:
-.. literalinclude:: ../../examples/tutorial/external/keyword_args_call.pyx
+.. tabs::
+
+ .. group-tab:: Pure Python
+
+ .. literalinclude:: ../../examples/tutorial/external/keyword_args_call.py
+ :caption: keyword_args_call.py
+ .. literalinclude:: ../../examples/tutorial/external/strstr.pxd
+ :caption: strstr.pxd
+
+ .. group-tab:: Cython
+
+ .. literalinclude:: ../../examples/tutorial/external/keyword_args_call.pyx
+ :caption: keyword_args_call.pyx
Note that changing existing parameter names later is a backwards
incompatible API modification, just as for Python code. Thus, if