summaryrefslogtreecommitdiff
path: root/docs/examples/tutorial
diff options
context:
space:
mode:
Diffstat (limited to 'docs/examples/tutorial')
-rw-r--r--docs/examples/tutorial/array/clone.py8
-rw-r--r--docs/examples/tutorial/array/clone.pyx16
-rw-r--r--docs/examples/tutorial/array/overhead.py17
-rw-r--r--docs/examples/tutorial/array/overhead.pyx32
-rw-r--r--docs/examples/tutorial/array/resize.py10
-rw-r--r--docs/examples/tutorial/array/resize.pyx20
-rw-r--r--docs/examples/tutorial/array/safe_usage.py6
-rw-r--r--docs/examples/tutorial/array/safe_usage.pyx12
-rw-r--r--docs/examples/tutorial/array/unsafe_usage.py11
-rw-r--r--docs/examples/tutorial/array/unsafe_usage.pyx22
-rw-r--r--docs/examples/tutorial/cdef_classes/integrate.py17
-rw-r--r--docs/examples/tutorial/cdef_classes/integrate.pyx31
-rw-r--r--docs/examples/tutorial/cdef_classes/math_function.py14
-rw-r--r--docs/examples/tutorial/cdef_classes/math_function_2.py5
-rw-r--r--docs/examples/tutorial/cdef_classes/math_function_2.pyx8
-rw-r--r--docs/examples/tutorial/cdef_classes/nonecheck.py20
-rw-r--r--docs/examples/tutorial/cdef_classes/nonecheck.pyx39
-rw-r--r--docs/examples/tutorial/cdef_classes/sin_of_square.py13
-rw-r--r--docs/examples/tutorial/cdef_classes/sin_of_square.pyx22
-rw-r--r--docs/examples/tutorial/cdef_classes/wave_function.py22
-rw-r--r--docs/examples/tutorial/cdef_classes/wave_function.pyx43
-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
-rw-r--r--docs/examples/tutorial/cython_tutorial/primes.py27
-rw-r--r--docs/examples/tutorial/cython_tutorial/primes.pyx10
-rw-r--r--docs/examples/tutorial/cython_tutorial/primes_cpp.py22
-rw-r--r--docs/examples/tutorial/cython_tutorial/primes_cpp.pyx43
-rw-r--r--docs/examples/tutorial/cython_tutorial/primes_python.py2
-rw-r--r--docs/examples/tutorial/cython_tutorial/setup.py6
-rw-r--r--docs/examples/tutorial/embedding/embedded.pyx12
-rw-r--r--docs/examples/tutorial/embedding/embedded_main.c69
-rw-r--r--docs/examples/tutorial/external/atoi.py6
-rw-r--r--docs/examples/tutorial/external/atoi.pyx11
-rw-r--r--docs/examples/tutorial/external/cpdef_sin.pyx14
-rw-r--r--docs/examples/tutorial/external/keyword_args.pyx4
-rw-r--r--docs/examples/tutorial/external/keyword_args_call.py7
-rw-r--r--docs/examples/tutorial/external/keyword_args_call.pyx14
-rw-r--r--docs/examples/tutorial/external/libc_sin.py5
-rw-r--r--docs/examples/tutorial/external/libc_sin.pyx9
-rw-r--r--docs/examples/tutorial/external/py_version_hex.py4
-rw-r--r--docs/examples/tutorial/external/py_version_hex.pyx8
-rw-r--r--docs/examples/tutorial/external/setup.py25
-rw-r--r--docs/examples/tutorial/external/strstr.pxd2
-rw-r--r--docs/examples/tutorial/memory_allocation/malloc.py24
-rw-r--r--docs/examples/tutorial/memory_allocation/malloc.pyx47
-rw-r--r--docs/examples/tutorial/memory_allocation/some_memory.py27
-rw-r--r--docs/examples/tutorial/memory_allocation/some_memory.pyx52
-rw-r--r--docs/examples/tutorial/numpy/convolve2.pyx8
-rw-r--r--docs/examples/tutorial/numpy/convolve_py.py86
-rw-r--r--docs/examples/tutorial/parallelization/manual_work.py24
-rw-r--r--docs/examples/tutorial/parallelization/manual_work.pyx25
-rw-r--r--docs/examples/tutorial/parallelization/median.py35
-rw-r--r--docs/examples/tutorial/parallelization/median.pyx34
-rw-r--r--docs/examples/tutorial/parallelization/norm.py12
-rw-r--r--docs/examples/tutorial/parallelization/norm.pyx12
-rw-r--r--docs/examples/tutorial/parallelization/normalize.py16
-rw-r--r--docs/examples/tutorial/parallelization/normalize.pyx17
-rw-r--r--docs/examples/tutorial/parallelization/parallel_sin.py16
-rw-r--r--docs/examples/tutorial/parallelization/parallel_sin.pyx16
-rw-r--r--docs/examples/tutorial/parallelization/setup.py29
-rw-r--r--docs/examples/tutorial/profiling_tutorial/calc_pi.py18
-rw-r--r--docs/examples/tutorial/profiling_tutorial/calc_pi_2.py12
-rw-r--r--docs/examples/tutorial/profiling_tutorial/calc_pi_2.pyx24
-rw-r--r--docs/examples/tutorial/profiling_tutorial/calc_pi_3.py15
-rw-r--r--docs/examples/tutorial/profiling_tutorial/calc_pi_3.pyx27
-rw-r--r--docs/examples/tutorial/profiling_tutorial/calc_pi_4.py17
-rw-r--r--docs/examples/tutorial/profiling_tutorial/calc_pi_4.pyx33
-rw-r--r--docs/examples/tutorial/profiling_tutorial/often_called.py5
-rw-r--r--docs/examples/tutorial/profiling_tutorial/often_called.pyx10
-rw-r--r--docs/examples/tutorial/profiling_tutorial/profile.py18
-rw-r--r--docs/examples/tutorial/profiling_tutorial/profile_2.py24
-rw-r--r--docs/examples/tutorial/pure/A.py28
-rw-r--r--docs/examples/tutorial/pure/A_equivalent.pyx30
-rw-r--r--docs/examples/tutorial/pure/annotations.py10
-rw-r--r--docs/examples/tutorial/pure/c_arrays.py30
-rw-r--r--docs/examples/tutorial/pure/cclass.py32
-rw-r--r--docs/examples/tutorial/pure/compiled_switch.py12
-rw-r--r--docs/examples/tutorial/pure/cython_declare.py8
-rw-r--r--docs/examples/tutorial/pure/cython_declare2.py6
-rw-r--r--docs/examples/tutorial/pure/disabled_annotations.py33
-rw-r--r--docs/examples/tutorial/pure/dostuff.py10
-rw-r--r--docs/examples/tutorial/pure/exceptval.py14
-rw-r--r--docs/examples/tutorial/pure/locals.py12
-rw-r--r--docs/examples/tutorial/pure/mymodule.py20
-rw-r--r--docs/examples/tutorial/pure/pep_526.py44
-rw-r--r--docs/examples/tutorial/pure/py_cimport.py5
-rw-r--r--docs/examples/tutorial/string/api_func.pyx10
-rw-r--r--docs/examples/tutorial/string/arg_memview.pyx10
-rw-r--r--docs/examples/tutorial/string/auto_conversion_1.pyx18
-rw-r--r--docs/examples/tutorial/string/auto_conversion_2.pyx24
-rw-r--r--docs/examples/tutorial/string/auto_conversion_3.pyx12
-rw-r--r--docs/examples/tutorial/string/c_func.pyx45
-rw-r--r--docs/examples/tutorial/string/const.pyx8
-rw-r--r--docs/examples/tutorial/string/cpp_string.pyx24
-rw-r--r--docs/examples/tutorial/string/decode.pyx18
-rw-r--r--docs/examples/tutorial/string/decode_cpp_string.pyx20
-rw-r--r--docs/examples/tutorial/string/for_bytes.pyx12
-rw-r--r--docs/examples/tutorial/string/for_char.pyx12
-rw-r--r--docs/examples/tutorial/string/for_unicode.pyx12
-rw-r--r--docs/examples/tutorial/string/if_char_in.pyx10
-rw-r--r--docs/examples/tutorial/string/naive_decode.pyx8
-rw-r--r--docs/examples/tutorial/string/return_memview.pyx18
-rw-r--r--docs/examples/tutorial/string/slicing_c_string.pyx30
-rw-r--r--docs/examples/tutorial/string/to_char.pyx16
-rw-r--r--docs/examples/tutorial/string/to_unicode.pyx44
-rw-r--r--docs/examples/tutorial/string/try_finally.pyx18
-rw-r--r--docs/examples/tutorial/string/utf_eight.pyx28
113 files changed, 1517 insertions, 754 deletions
diff --git a/docs/examples/tutorial/array/clone.py b/docs/examples/tutorial/array/clone.py
new file mode 100644
index 000000000..6736c2f67
--- /dev/null
+++ b/docs/examples/tutorial/array/clone.py
@@ -0,0 +1,8 @@
+from cython.cimports.cpython import array
+import array
+
+int_array_template = cython.declare(array.array, array.array('i', []))
+cython.declare(newarray=array.array)
+
+# create an array with 3 elements with same type as template
+newarray = array.clone(int_array_template, 3, zero=False)
diff --git a/docs/examples/tutorial/array/clone.pyx b/docs/examples/tutorial/array/clone.pyx
index e2bac0e4a..2eb803499 100644
--- a/docs/examples/tutorial/array/clone.pyx
+++ b/docs/examples/tutorial/array/clone.pyx
@@ -1,8 +1,8 @@
-from cpython cimport array
-import array
-
-cdef array.array int_array_template = array.array('i', [])
-cdef array.array newarray
-
-# create an array with 3 elements with same type as template
-newarray = array.clone(int_array_template, 3, zero=False)
+from cpython cimport array
+import array
+
+cdef array.array int_array_template = array.array('i', [])
+cdef array.array newarray
+
+# create an array with 3 elements with same type as template
+newarray = array.clone(int_array_template, 3, zero=False)
diff --git a/docs/examples/tutorial/array/overhead.py b/docs/examples/tutorial/array/overhead.py
new file mode 100644
index 000000000..f60c019ce
--- /dev/null
+++ b/docs/examples/tutorial/array/overhead.py
@@ -0,0 +1,17 @@
+from cython.cimports.cpython import array
+import array
+
+a = cython.declare(array.array, array.array('i', [1, 2, 3]))
+ca = cython.declare(cython.int[:], a)
+
+@cython.cfunc
+def overhead(a: cython.object) -> cython.int:
+ ca: cython.int[:] = a
+ return ca[0]
+
+@cython.cfunc
+def no_overhead(ca: cython.int[:]) -> cython.int:
+ return ca[0]
+
+print(overhead(a)) # new memory view will be constructed, overhead
+print(no_overhead(ca)) # ca is already a memory view, so no overhead
diff --git a/docs/examples/tutorial/array/overhead.pyx b/docs/examples/tutorial/array/overhead.pyx
index e385bff3f..a113e8dc9 100644
--- a/docs/examples/tutorial/array/overhead.pyx
+++ b/docs/examples/tutorial/array/overhead.pyx
@@ -1,15 +1,17 @@
-from cpython cimport array
-import array
-
-cdef array.array a = array.array('i', [1, 2, 3])
-cdef int[:] ca = a
-
-cdef int overhead(object a):
- cdef int[:] ca = a
- return ca[0]
-
-cdef int no_overhead(int[:] ca):
- return ca[0]
-
-print(overhead(a)) # new memory view will be constructed, overhead
-print(no_overhead(ca)) # ca is already a memory view, so no overhead
+from cpython cimport array
+import array
+
+cdef array.array a = array.array('i', [1, 2, 3])
+cdef int[:] ca = a
+
+
+cdef int overhead(object a):
+ cdef int[:] ca = a
+ return ca[0]
+
+
+cdef int no_overhead(int[:] ca):
+ return ca[0]
+
+print(overhead(a)) # new memory view will be constructed, overhead
+print(no_overhead(ca)) # ca is already a memory view, so no overhead
diff --git a/docs/examples/tutorial/array/resize.py b/docs/examples/tutorial/array/resize.py
new file mode 100644
index 000000000..c2e50472f
--- /dev/null
+++ b/docs/examples/tutorial/array/resize.py
@@ -0,0 +1,10 @@
+from cython.cimports.cpython import array
+import array
+
+a = cython.declare(array.array, array.array('i', [1, 2, 3]))
+b = cython.declare(array.array, array.array('i', [4, 5, 6]))
+
+# extend a with b, resize as needed
+array.extend(a, b)
+# resize a, leaving just original three elements
+array.resize(a, len(a) - len(b))
diff --git a/docs/examples/tutorial/array/resize.pyx b/docs/examples/tutorial/array/resize.pyx
index a11fbde7b..7b92958b4 100644
--- a/docs/examples/tutorial/array/resize.pyx
+++ b/docs/examples/tutorial/array/resize.pyx
@@ -1,10 +1,10 @@
-from cpython cimport array
-import array
-
-cdef array.array a = array.array('i', [1, 2, 3])
-cdef array.array b = array.array('i', [4, 5, 6])
-
-# extend a with b, resize as needed
-array.extend(a, b)
-# resize a, leaving just original three elements
-array.resize(a, len(a) - len(b))
+from cpython cimport array
+import array
+
+cdef array.array a = array.array('i', [1, 2, 3])
+cdef array.array b = array.array('i', [4, 5, 6])
+
+# extend a with b, resize as needed
+array.extend(a, b)
+# resize a, leaving just original three elements
+array.resize(a, len(a) - len(b))
diff --git a/docs/examples/tutorial/array/safe_usage.py b/docs/examples/tutorial/array/safe_usage.py
new file mode 100644
index 000000000..8b9ffd42c
--- /dev/null
+++ b/docs/examples/tutorial/array/safe_usage.py
@@ -0,0 +1,6 @@
+from cython.cimports.cpython import array
+import array
+a = cython.declare(array.array, array.array('i', [1, 2, 3]))
+ca = cython.declare(cython.int[:], a)
+
+print(ca[0])
diff --git a/docs/examples/tutorial/array/safe_usage.pyx b/docs/examples/tutorial/array/safe_usage.pyx
index 61d6b39eb..15107ae92 100644
--- a/docs/examples/tutorial/array/safe_usage.pyx
+++ b/docs/examples/tutorial/array/safe_usage.pyx
@@ -1,6 +1,6 @@
-from cpython cimport array
-import array
-cdef array.array a = array.array('i', [1, 2, 3])
-cdef int[:] ca = a
-
-print(ca[0])
+from cpython cimport array
+import array
+cdef array.array a = array.array('i', [1, 2, 3])
+cdef int[:] ca = a
+
+print(ca[0])
diff --git a/docs/examples/tutorial/array/unsafe_usage.py b/docs/examples/tutorial/array/unsafe_usage.py
new file mode 100644
index 000000000..99b2b1690
--- /dev/null
+++ b/docs/examples/tutorial/array/unsafe_usage.py
@@ -0,0 +1,11 @@
+from cython.cimports.cpython import array
+import array
+
+a = cython.declare(array.array, array.array('i', [1, 2, 3]))
+
+# access underlying pointer:
+print(a.data.as_ints[0])
+
+from cython.cimports.libc.string import memset
+
+memset(a.data.as_voidptr, 0, len(a) * cython.sizeof(cython.int))
diff --git a/docs/examples/tutorial/array/unsafe_usage.pyx b/docs/examples/tutorial/array/unsafe_usage.pyx
index 2aefeb102..d1f498c68 100644
--- a/docs/examples/tutorial/array/unsafe_usage.pyx
+++ b/docs/examples/tutorial/array/unsafe_usage.pyx
@@ -1,11 +1,11 @@
-from cpython cimport array
-import array
-
-cdef array.array a = array.array('i', [1, 2, 3])
-
-# access underlying pointer:
-print(a.data.as_ints[0])
-
-from libc.string cimport memset
-
-memset(a.data.as_voidptr, 0, len(a) * sizeof(int))
+from cpython cimport array
+import array
+
+cdef array.array a = array.array('i', [1, 2, 3])
+
+# access underlying pointer:
+print(a.data.as_ints[0])
+
+from libc.string cimport memset
+
+memset(a.data.as_voidptr, 0, len(a) * sizeof(int))
diff --git a/docs/examples/tutorial/cdef_classes/integrate.py b/docs/examples/tutorial/cdef_classes/integrate.py
new file mode 100644
index 000000000..cd02554e5
--- /dev/null
+++ b/docs/examples/tutorial/cdef_classes/integrate.py
@@ -0,0 +1,17 @@
+from cython.cimports.sin_of_square import Function, SinOfSquareFunction
+
+def integrate(f: Function, a: float, b: float, N: cython.int):
+ i: cython.int
+
+ if f is None:
+ raise ValueError("f cannot be None")
+
+ s: float = 0
+ dx: float = (b - a) / N
+
+ for i in range(N):
+ s += f.evaluate(a + i * dx)
+
+ return s * dx
+
+print(integrate(SinOfSquareFunction(), 0, 1, 10000))
diff --git a/docs/examples/tutorial/cdef_classes/integrate.pyx b/docs/examples/tutorial/cdef_classes/integrate.pyx
index a3bbcbfec..ad4c8540b 100644
--- a/docs/examples/tutorial/cdef_classes/integrate.pyx
+++ b/docs/examples/tutorial/cdef_classes/integrate.pyx
@@ -1,14 +1,17 @@
-from sin_of_square cimport Function, SinOfSquareFunction
-
-def integrate(Function f, double a, double b, int N):
- cdef int i
- cdef double s, dx
- if f is None:
- raise ValueError("f cannot be None")
- s = 0
- dx = (b - a) / N
- for i in range(N):
- s += f.evaluate(a + i * dx)
- return s * dx
-
-print(integrate(SinOfSquareFunction(), 0, 1, 10000))
+from sin_of_square cimport Function, SinOfSquareFunction
+
+def integrate(Function f, double a, double b, int N):
+ cdef int i
+ cdef double s, dx
+ if f is None:
+ raise ValueError("f cannot be None")
+
+ s = 0
+ dx = (b - a) / N
+
+ for i in range(N):
+ s += f.evaluate(a + i * dx)
+
+ return s * dx
+
+print(integrate(SinOfSquareFunction(), 0, 1, 10000))
diff --git a/docs/examples/tutorial/cdef_classes/math_function.py b/docs/examples/tutorial/cdef_classes/math_function.py
index 21281cc9b..1a6ee896c 100644
--- a/docs/examples/tutorial/cdef_classes/math_function.py
+++ b/docs/examples/tutorial/cdef_classes/math_function.py
@@ -1,7 +1,7 @@
-class MathFunction(object):
- def __init__(self, name, operator):
- self.name = name
- self.operator = operator
-
- def __call__(self, *operands):
- return self.operator(*operands)
+class MathFunction(object):
+ def __init__(self, name, operator):
+ self.name = name
+ self.operator = operator
+
+ def __call__(self, *operands):
+ return self.operator(*operands)
diff --git a/docs/examples/tutorial/cdef_classes/math_function_2.py b/docs/examples/tutorial/cdef_classes/math_function_2.py
new file mode 100644
index 000000000..ba5917639
--- /dev/null
+++ b/docs/examples/tutorial/cdef_classes/math_function_2.py
@@ -0,0 +1,5 @@
+@cython.cclass
+class Function:
+ @cython.ccall
+ def evaluate(self, x: float) -> float:
+ return 0
diff --git a/docs/examples/tutorial/cdef_classes/math_function_2.pyx b/docs/examples/tutorial/cdef_classes/math_function_2.pyx
index 1793ef689..a4bdb7aa2 100644
--- a/docs/examples/tutorial/cdef_classes/math_function_2.pyx
+++ b/docs/examples/tutorial/cdef_classes/math_function_2.pyx
@@ -1,3 +1,5 @@
-cdef class Function:
- cpdef double evaluate(self, double x) except *:
- return 0
+
+cdef class Function:
+
+ cpdef double evaluate(self, double x) except *:
+ return 0
diff --git a/docs/examples/tutorial/cdef_classes/nonecheck.py b/docs/examples/tutorial/cdef_classes/nonecheck.py
new file mode 100644
index 000000000..dccb97435
--- /dev/null
+++ b/docs/examples/tutorial/cdef_classes/nonecheck.py
@@ -0,0 +1,20 @@
+# cython: nonecheck=True
+# ^^^ Turns on nonecheck globally
+
+import cython
+
+@cython.cclass
+class MyClass:
+ pass
+
+# Turn off nonecheck locally for the function
+@cython.nonecheck(False)
+def func():
+ obj: MyClass = None
+ try:
+ # Turn nonecheck on again for a block
+ with cython.nonecheck(True):
+ print(obj.myfunc()) # Raises exception
+ except AttributeError:
+ pass
+ print(obj.myfunc()) # Hope for a crash!
diff --git a/docs/examples/tutorial/cdef_classes/nonecheck.pyx b/docs/examples/tutorial/cdef_classes/nonecheck.pyx
index b9e12c8d5..92c8fa42b 100644
--- a/docs/examples/tutorial/cdef_classes/nonecheck.pyx
+++ b/docs/examples/tutorial/cdef_classes/nonecheck.pyx
@@ -1,19 +1,20 @@
-# cython: nonecheck=True
-# ^^^ Turns on nonecheck globally
-
-import cython
-
-cdef class MyClass:
- pass
-
-# Turn off nonecheck locally for the function
-@cython.nonecheck(False)
-def func():
- cdef MyClass obj = None
- try:
- # Turn nonecheck on again for a block
- with cython.nonecheck(True):
- print(obj.myfunc()) # Raises exception
- except AttributeError:
- pass
- print(obj.myfunc()) # Hope for a crash!
+# cython: nonecheck=True
+# ^^^ Turns on nonecheck globally
+
+import cython
+
+
+cdef class MyClass:
+ pass
+
+# Turn off nonecheck locally for the function
+@cython.nonecheck(False)
+def func():
+ cdef MyClass obj = None
+ try:
+ # Turn nonecheck on again for a block
+ with cython.nonecheck(True):
+ print(obj.myfunc()) # Raises exception
+ except AttributeError:
+ pass
+ print(obj.myfunc()) # Hope for a crash!
diff --git a/docs/examples/tutorial/cdef_classes/sin_of_square.py b/docs/examples/tutorial/cdef_classes/sin_of_square.py
new file mode 100644
index 000000000..1904ea934
--- /dev/null
+++ b/docs/examples/tutorial/cdef_classes/sin_of_square.py
@@ -0,0 +1,13 @@
+from cython.cimports.libc.math import sin
+
+@cython.cclass
+class Function:
+ @cython.ccall
+ def evaluate(self, x: float) -> float:
+ return 0
+
+@cython.cclass
+class SinOfSquareFunction(Function):
+ @cython.ccall
+ def evaluate(self, x: float) -> float:
+ return sin(x ** 2)
diff --git a/docs/examples/tutorial/cdef_classes/sin_of_square.pyx b/docs/examples/tutorial/cdef_classes/sin_of_square.pyx
index 7aab96056..67af294b5 100644
--- a/docs/examples/tutorial/cdef_classes/sin_of_square.pyx
+++ b/docs/examples/tutorial/cdef_classes/sin_of_square.pyx
@@ -1,9 +1,13 @@
-from libc.math cimport sin
-
-cdef class Function:
- cpdef double evaluate(self, double x) except *:
- return 0
-
-cdef class SinOfSquareFunction(Function):
- cpdef double evaluate(self, double x) except *:
- return sin(x ** 2)
+from libc.math cimport sin
+
+
+cdef class Function:
+
+ cpdef double evaluate(self, double x) except *:
+ return 0
+
+
+cdef class SinOfSquareFunction(Function):
+
+ cpdef double evaluate(self, double x) except *:
+ return sin(x ** 2)
diff --git a/docs/examples/tutorial/cdef_classes/wave_function.py b/docs/examples/tutorial/cdef_classes/wave_function.py
new file mode 100644
index 000000000..7ff59a762
--- /dev/null
+++ b/docs/examples/tutorial/cdef_classes/wave_function.py
@@ -0,0 +1,22 @@
+from cython.cimports.sin_of_square import Function
+
+@cython.cclass
+class WaveFunction(Function):
+
+ # Not available in Python-space:
+ offset: float
+
+ # Available in Python-space:
+ freq = cython.declare(cython.double, visibility='public')
+
+ # Available in Python-space, but only for reading:
+ scale = cython.declare(cython.double, visibility='readonly')
+
+ # Available in Python-space:
+ @property
+ def period(self):
+ return 1.0 / self.freq
+
+ @period.setter
+ def period(self, value):
+ self.freq = 1.0 / value
diff --git a/docs/examples/tutorial/cdef_classes/wave_function.pyx b/docs/examples/tutorial/cdef_classes/wave_function.pyx
index aa35d954e..34b144667 100644
--- a/docs/examples/tutorial/cdef_classes/wave_function.pyx
+++ b/docs/examples/tutorial/cdef_classes/wave_function.pyx
@@ -1,21 +1,22 @@
-from sin_of_square cimport Function
-
-cdef class WaveFunction(Function):
-
- # Not available in Python-space:
- cdef double offset
-
- # Available in Python-space:
- cdef public double freq
-
- # Available in Python-space, but only for reading:
- cdef readonly double scale
-
- # Available in Python-space:
- @property
- def period(self):
- return 1.0 / self.freq
-
- @period.setter
- def period(self, value):
- self.freq = 1.0 / value
+from sin_of_square cimport Function
+
+
+cdef class WaveFunction(Function):
+
+ # Not available in Python-space:
+ cdef double offset
+
+ # Available in Python-space:
+ cdef public double freq
+
+ # Available in Python-space, but only for reading:
+ cdef readonly double scale
+
+ # Available in Python-space:
+ @property
+ def period(self):
+ return 1.0 / self.freq
+
+ @period.setter
+ def period(self, value):
+ self.freq = 1.0 / value
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())
diff --git a/docs/examples/tutorial/cython_tutorial/primes.py b/docs/examples/tutorial/cython_tutorial/primes.py
new file mode 100644
index 000000000..645d9479d
--- /dev/null
+++ b/docs/examples/tutorial/cython_tutorial/primes.py
@@ -0,0 +1,27 @@
+def primes(nb_primes: cython.int):
+ i: cython.int
+ p: cython.int[1000]
+
+ if nb_primes > 1000:
+ nb_primes = 1000
+
+ if not cython.compiled: # Only if regular Python is running
+ p = [0] * 1000 # Make p work almost like a C array
+
+ len_p: cython.int = 0 # The current number of elements in p.
+ n: cython.int = 2
+ while len_p < nb_primes:
+ # Is n prime?
+ for i in p[:len_p]:
+ if n % i == 0:
+ break
+
+ # If no break occurred in the loop, we have a prime.
+ else:
+ p[len_p] = n
+ len_p += 1
+ n += 1
+
+ # Let's copy the result into a Python list:
+ result_as_list = [prime for prime in p[:len_p]]
+ return result_as_list
diff --git a/docs/examples/tutorial/cython_tutorial/primes.pyx b/docs/examples/tutorial/cython_tutorial/primes.pyx
index 96ecdb59a..7707e30dc 100644
--- a/docs/examples/tutorial/cython_tutorial/primes.pyx
+++ b/docs/examples/tutorial/cython_tutorial/primes.pyx
@@ -1,9 +1,13 @@
def primes(int nb_primes):
cdef int n, i, len_p
- cdef int p[1000]
+ cdef int[1000] p
+
if nb_primes > 1000:
nb_primes = 1000
+
+
+
len_p = 0 # The current number of elements in p.
n = 2
while len_p < nb_primes:
@@ -18,6 +22,6 @@ def primes(int nb_primes):
len_p += 1
n += 1
- # Let's return the result in a python list:
- result_as_list = [prime for prime in p[:len_p]]
+ # Let's copy the result into a Python list:
+ result_as_list = [prime for prime in p[:len_p]]
return result_as_list
diff --git a/docs/examples/tutorial/cython_tutorial/primes_cpp.py b/docs/examples/tutorial/cython_tutorial/primes_cpp.py
new file mode 100644
index 000000000..468d00c46
--- /dev/null
+++ b/docs/examples/tutorial/cython_tutorial/primes_cpp.py
@@ -0,0 +1,22 @@
+# distutils: language=c++
+
+import cython
+from cython.cimports.libcpp.vector import vector
+
+def primes(nb_primes: cython.uint):
+ i: cython.int
+ p: vector[cython.int]
+ p.reserve(nb_primes) # allocate memory for 'nb_primes' elements.
+
+ n: cython.int = 2
+ while p.size() < nb_primes: # size() for vectors is similar to len()
+ for i in p:
+ if n % i == 0:
+ break
+ else:
+ p.push_back(n) # push_back is similar to append()
+ n += 1
+
+ # If possible, C values and C++ objects are automatically
+ # converted to Python objects at need.
+ return p # so here, the vector will be copied into a Python list.
diff --git a/docs/examples/tutorial/cython_tutorial/primes_cpp.pyx b/docs/examples/tutorial/cython_tutorial/primes_cpp.pyx
index 57bfe9cc2..afef8bd13 100644
--- a/docs/examples/tutorial/cython_tutorial/primes_cpp.pyx
+++ b/docs/examples/tutorial/cython_tutorial/primes_cpp.pyx
@@ -1,21 +1,22 @@
-# distutils: language=c++
-
-from libcpp.vector cimport vector
-
-def primes(unsigned int nb_primes):
- cdef int n, i
- cdef vector[int] p
- p.reserve(nb_primes) # allocate memory for 'nb_primes' elements.
-
- n = 2
- while p.size() < nb_primes: # size() for vectors is similar to len()
- for i in p:
- if n % i == 0:
- break
- else:
- p.push_back(n) # push_back is similar to append()
- n += 1
-
- # Vectors are automatically converted to Python
- # lists when converted to Python objects.
- return p
+# distutils: language=c++
+
+
+from libcpp.vector cimport vector
+
+def primes(unsigned int nb_primes):
+ cdef int n, i
+ cdef vector[int] p
+ p.reserve(nb_primes) # allocate memory for 'nb_primes' elements.
+
+ n = 2
+ while p.size() < nb_primes: # size() for vectors is similar to len()
+ for i in p:
+ if n % i == 0:
+ break
+ else:
+ p.push_back(n) # push_back is similar to append()
+ n += 1
+
+ # If possible, C values and C++ objects are automatically
+ # converted to Python objects at need.
+ return p # so here, the vector will be copied into a Python list.
diff --git a/docs/examples/tutorial/cython_tutorial/primes_python.py b/docs/examples/tutorial/cython_tutorial/primes_python.py
index f6559d519..845af5bbf 100644
--- a/docs/examples/tutorial/cython_tutorial/primes_python.py
+++ b/docs/examples/tutorial/cython_tutorial/primes_python.py
@@ -1,4 +1,4 @@
-def primes_python(nb_primes):
+def primes(nb_primes):
p = []
n = 2
while len(p) < nb_primes:
diff --git a/docs/examples/tutorial/cython_tutorial/setup.py b/docs/examples/tutorial/cython_tutorial/setup.py
deleted file mode 100644
index 302a08e5f..000000000
--- a/docs/examples/tutorial/cython_tutorial/setup.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from distutils.core import setup
-from Cython.Build import cythonize
-
-setup(
- ext_modules=cythonize("fib.pyx"),
-)
diff --git a/docs/examples/tutorial/embedding/embedded.pyx b/docs/examples/tutorial/embedding/embedded.pyx
new file mode 100644
index 000000000..2ed823945
--- /dev/null
+++ b/docs/examples/tutorial/embedding/embedded.pyx
@@ -0,0 +1,12 @@
+# embedded.pyx
+
+# The following two lines are for test purposes only, please ignore them.
+# distutils: sources = embedded_main.c
+# tag: py3only
+# tag: no-cpp
+
+TEXT_TO_SAY = 'Hello from Python!'
+
+cdef public int say_hello_from_python() except -1:
+ print(TEXT_TO_SAY)
+ return 0
diff --git a/docs/examples/tutorial/embedding/embedded_main.c b/docs/examples/tutorial/embedding/embedded_main.c
new file mode 100644
index 000000000..e14901a5e
--- /dev/null
+++ b/docs/examples/tutorial/embedding/embedded_main.c
@@ -0,0 +1,69 @@
+/* embedded_main.c */
+
+/* This include file is automatically generated by Cython for 'public' functions. */
+#include "embedded.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ PyObject *pmodule;
+ wchar_t *program;
+
+ program = Py_DecodeLocale(argv[0], NULL);
+ if (program == NULL) {
+ fprintf(stderr, "Fatal error: cannot decode argv[0], got %d arguments\n", argc);
+ exit(1);
+ }
+
+ /* Add a built-in module, before Py_Initialize */
+ if (PyImport_AppendInittab("embedded", PyInit_embedded) == -1) {
+ fprintf(stderr, "Error: could not extend in-built modules table\n");
+ exit(1);
+ }
+
+ /* Pass argv[0] to the Python interpreter */
+ Py_SetProgramName(program);
+
+ /* Initialize the Python interpreter. Required.
+ If this step fails, it will be a fatal error. */
+ Py_Initialize();
+
+ /* Optionally import the module; alternatively,
+ import can be deferred until the embedded script
+ imports it. */
+ pmodule = PyImport_ImportModule("embedded");
+ if (!pmodule) {
+ PyErr_Print();
+ fprintf(stderr, "Error: could not import module 'embedded'\n");
+ goto exit_with_error;
+ }
+
+ /* Now call into your module code. */
+ if (say_hello_from_python() < 0) {
+ PyErr_Print();
+ fprintf(stderr, "Error in Python code, exception was printed.\n");
+ goto exit_with_error;
+ }
+
+ /* ... */
+
+ /* Clean up after using CPython. */
+ PyMem_RawFree(program);
+ Py_Finalize();
+
+ return 0;
+
+ /* Clean up in the error cases above. */
+exit_with_error:
+ PyMem_RawFree(program);
+ Py_Finalize();
+ return 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
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 48643bbf2..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!
+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/cpdef_sin.pyx b/docs/examples/tutorial/external/cpdef_sin.pyx
index 47e09f433..eee2326a4 100644
--- a/docs/examples/tutorial/external/cpdef_sin.pyx
+++ b/docs/examples/tutorial/external/cpdef_sin.pyx
@@ -1,7 +1,7 @@
-"""
->>> sin(0)
-0.0
-"""
-
-cdef extern from "math.h":
- cpdef double sin(double x)
+"""
+>>> sin(0)
+0.0
+"""
+
+cdef extern from "math.h":
+ cpdef double sin(double x)
diff --git a/docs/examples/tutorial/external/keyword_args.pyx b/docs/examples/tutorial/external/keyword_args.pyx
index 327e4e08b..7c2a786cc 100644
--- a/docs/examples/tutorial/external/keyword_args.pyx
+++ b/docs/examples/tutorial/external/keyword_args.pyx
@@ -1,2 +1,2 @@
-cdef extern from "string.h":
- char* strstr(const char *haystack, const char *needle)
+cdef extern from "string.h":
+ char* strstr(const char *haystack, const char *needle)
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..b3b3f5049
--- /dev/null
+++ b/docs/examples/tutorial/external/keyword_args_call.py
@@ -0,0 +1,7 @@
+from cython.cimports.strstr import strstr
+
+def main():
+ data: cython.p_char = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh"
+
+ pos = 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 4be5f755d..de2b6f2b2 100644
--- a/docs/examples/tutorial/external/keyword_args_call.pyx
+++ b/docs/examples/tutorial/external/keyword_args_call.pyx
@@ -1,7 +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)
-print(pos is not NULL)
+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)
+print(pos is not NULL)
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 25a4430e3..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)
+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/py_version_hex.pyx b/docs/examples/tutorial/external/py_version_hex.pyx
index d732b00e7..e33f207c1 100644
--- a/docs/examples/tutorial/external/py_version_hex.pyx
+++ b/docs/examples/tutorial/external/py_version_hex.pyx
@@ -1,4 +1,4 @@
-from cpython.version cimport PY_VERSION_HEX
-
-# Python version >= 3.2 final ?
-print(PY_VERSION_HEX >= 0x030200F0)
+from cpython.version cimport PY_VERSION_HEX
+
+# Python version >= 3.2 final ?
+print(PY_VERSION_HEX >= 0x030200F0)
diff --git a/docs/examples/tutorial/external/setup.py b/docs/examples/tutorial/external/setup.py
index 653214c84..289bc9534 100644
--- a/docs/examples/tutorial/external/setup.py
+++ b/docs/examples/tutorial/external/setup.py
@@ -1,13 +1,12 @@
-from distutils.core import setup
-from distutils.extension import Extension
-from Cython.Build import cythonize
-
-ext_modules = [
- Extension("demo",
- sources=["demo.pyx"],
- libraries=["m"] # Unix-like specific
- )
-]
-
-setup(name="Demos",
- ext_modules=cythonize(ext_modules))
+from setuptools import Extension, setup
+from Cython.Build import cythonize
+
+ext_modules = [
+ Extension("demo",
+ sources=["demo.pyx"],
+ libraries=["m"] # Unix-like specific
+ )
+]
+
+setup(name="Demos",
+ ext_modules=cythonize(ext_modules))
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/examples/tutorial/memory_allocation/malloc.py b/docs/examples/tutorial/memory_allocation/malloc.py
new file mode 100644
index 000000000..fb7e82236
--- /dev/null
+++ b/docs/examples/tutorial/memory_allocation/malloc.py
@@ -0,0 +1,24 @@
+import random
+from cython.cimports.libc.stdlib import malloc, free
+
+def random_noise(number: cython.int = 1):
+ i: cython.int
+ # allocate number * sizeof(double) bytes of memory
+ my_array: cython.p_double = cython.cast(cython.p_double, malloc(
+ number * cython.sizeof(cython.double)))
+ if not my_array:
+ raise MemoryError()
+
+ try:
+ ran = random.normalvariate
+ for i in range(number):
+ my_array[i] = ran(0, 1)
+
+ # ... let's just assume we do some more heavy C calculations here to make up
+ # for the work that it takes to pack the C double values into Python float
+ # objects below, right after throwing away the existing objects above.
+
+ return [x for x in my_array[:number]]
+ finally:
+ # return the previously allocated memory to the system
+ free(my_array)
diff --git a/docs/examples/tutorial/memory_allocation/malloc.pyx b/docs/examples/tutorial/memory_allocation/malloc.pyx
index e01a378e3..6aa583aab 100644
--- a/docs/examples/tutorial/memory_allocation/malloc.pyx
+++ b/docs/examples/tutorial/memory_allocation/malloc.pyx
@@ -1,23 +1,24 @@
-import random
-from libc.stdlib cimport malloc, free
-
-def random_noise(int number=1):
- cdef int i
- # allocate number * sizeof(double) bytes of memory
- cdef double *my_array = <double *> malloc(number * sizeof(double))
- if not my_array:
- raise MemoryError()
-
- try:
- ran = random.normalvariate
- for i in range(number):
- my_array[i] = ran(0, 1)
-
- # ... let's just assume we do some more heavy C calculations here to make up
- # for the work that it takes to pack the C double values into Python float
- # objects below, right after throwing away the existing objects above.
-
- return [x for x in my_array[:number]]
- finally:
- # return the previously allocated memory to the system
- free(my_array)
+import random
+from libc.stdlib cimport malloc, free
+
+def random_noise(int number=1):
+ cdef int i
+ # allocate number * sizeof(double) bytes of memory
+ cdef double *my_array = <double *> malloc(
+ number * sizeof(double))
+ if not my_array:
+ raise MemoryError()
+
+ try:
+ ran = random.normalvariate
+ for i in range(number):
+ my_array[i] = ran(0, 1)
+
+ # ... let's just assume we do some more heavy C calculations here to make up
+ # for the work that it takes to pack the C double values into Python float
+ # objects below, right after throwing away the existing objects above.
+
+ return [x for x in my_array[:number]]
+ finally:
+ # return the previously allocated memory to the system
+ free(my_array)
diff --git a/docs/examples/tutorial/memory_allocation/some_memory.py b/docs/examples/tutorial/memory_allocation/some_memory.py
new file mode 100644
index 000000000..31ad63a6e
--- /dev/null
+++ b/docs/examples/tutorial/memory_allocation/some_memory.py
@@ -0,0 +1,27 @@
+from cython.cimports.cpython.mem import PyMem_Malloc, PyMem_Realloc, PyMem_Free
+
+@cython.cclass
+class SomeMemory:
+ data: cython.p_double
+
+ def __cinit__(self, number: cython.size_t):
+ # allocate some memory (uninitialised, may contain arbitrary data)
+ self.data = cython.cast(cython.p_double, PyMem_Malloc(
+ number * cython.sizeof(cython.double)))
+ if not self.data:
+ raise MemoryError()
+
+ def resize(self, new_number: cython.size_t):
+ # Allocates new_number * sizeof(double) bytes,
+ # preserving the current content and making a best-effort to
+ # re-use the original data location.
+ mem = cython.cast(cython.p_double, PyMem_Realloc(
+ self.data, new_number * cython.sizeof(cython.double)))
+ if not mem:
+ raise MemoryError()
+ # Only overwrite the pointer if the memory was really reallocated.
+ # On error (mem is NULL), the originally memory has not been freed.
+ self.data = mem
+
+ def __dealloc__(self):
+ PyMem_Free(self.data) # no-op if self.data is NULL
diff --git a/docs/examples/tutorial/memory_allocation/some_memory.pyx b/docs/examples/tutorial/memory_allocation/some_memory.pyx
index 2e639ac4d..e6bb63b77 100644
--- a/docs/examples/tutorial/memory_allocation/some_memory.pyx
+++ b/docs/examples/tutorial/memory_allocation/some_memory.pyx
@@ -1,25 +1,27 @@
-from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
-
-cdef class SomeMemory:
-
- cdef double* data
-
- def __cinit__(self, size_t number):
- # allocate some memory (uninitialised, may contain arbitrary data)
- self.data = <double*> PyMem_Malloc(number * sizeof(double))
- if not self.data:
- raise MemoryError()
-
- def resize(self, size_t new_number):
- # Allocates new_number * sizeof(double) bytes,
- # preserving the current content and making a best-effort to
- # re-use the original data location.
- mem = <double*> PyMem_Realloc(self.data, new_number * sizeof(double))
- if not mem:
- raise MemoryError()
- # Only overwrite the pointer if the memory was really reallocated.
- # On error (mem is NULL), the originally memory has not been freed.
- self.data = mem
-
- def __dealloc__(self):
- PyMem_Free(self.data) # no-op if self.data is NULL
+from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
+
+
+cdef class SomeMemory:
+ cdef double* data
+
+ def __cinit__(self, size_t number):
+ # allocate some memory (uninitialised, may contain arbitrary data)
+ self.data = <double*> PyMem_Malloc(
+ number * sizeof(double))
+ if not self.data:
+ raise MemoryError()
+
+ def resize(self, size_t new_number):
+ # Allocates new_number * sizeof(double) bytes,
+ # preserving the current content and making a best-effort to
+ # re-use the original data location.
+ mem = <double*> PyMem_Realloc(
+ self.data, new_number * sizeof(double))
+ if not mem:
+ raise MemoryError()
+ # Only overwrite the pointer if the memory was really reallocated.
+ # On error (mem is NULL), the originally memory has not been freed.
+ self.data = mem
+
+ def __dealloc__(self):
+ PyMem_Free(self.data) # no-op if self.data is NULL
diff --git a/docs/examples/tutorial/numpy/convolve2.pyx b/docs/examples/tutorial/numpy/convolve2.pyx
index be7512fe1..b77b92f53 100644
--- a/docs/examples/tutorial/numpy/convolve2.pyx
+++ b/docs/examples/tutorial/numpy/convolve2.pyx
@@ -1,4 +1,4 @@
-# tag: numpy_old
+# tag: numpy
# You can ignore the previous line.
# It's for internal testing of the cython documentation.
@@ -9,6 +9,12 @@ import numpy as np
# currently part of the Cython distribution).
cimport numpy as np
+# It's necessary to call "import_array" if you use any part of the
+# numpy PyArray_* API. From Cython 3, accessing attributes like
+# ".shape" on a typed Numpy array use this API. Therefore we recommend
+# always calling "import_array" whenever you "cimport numpy"
+np.import_array()
+
# We now need to fix a datatype for our arrays. I've used the variable
# DTYPE for this, which is assigned to the usual NumPy runtime
# type info object.
diff --git a/docs/examples/tutorial/numpy/convolve_py.py b/docs/examples/tutorial/numpy/convolve_py.py
index c3cbc5f86..39b276a04 100644
--- a/docs/examples/tutorial/numpy/convolve_py.py
+++ b/docs/examples/tutorial/numpy/convolve_py.py
@@ -1,43 +1,43 @@
-import numpy as np
-
-
-def naive_convolve(f, g):
- # f is an image and is indexed by (v, w)
- # g is a filter kernel and is indexed by (s, t),
- # it needs odd dimensions
- # h is the output image and is indexed by (x, y),
- # it is not cropped
- if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1:
- raise ValueError("Only odd dimensions on filter supported")
- # smid and tmid are number of pixels between the center pixel
- # and the edge, ie for a 5x5 filter they will be 2.
- #
- # The output size is calculated by adding smid, tmid to each
- # side of the dimensions of the input image.
- vmax = f.shape[0]
- wmax = f.shape[1]
- smax = g.shape[0]
- tmax = g.shape[1]
- smid = smax // 2
- tmid = tmax // 2
- xmax = vmax + 2 * smid
- ymax = wmax + 2 * tmid
- # Allocate result image.
- h = np.zeros([xmax, ymax], dtype=f.dtype)
- # Do convolution
- for x in range(xmax):
- for y in range(ymax):
- # Calculate pixel value for h at (x,y). Sum one component
- # for each pixel (s, t) of the filter g.
- s_from = max(smid - x, -smid)
- s_to = min((xmax - x) - smid, smid + 1)
- t_from = max(tmid - y, -tmid)
- t_to = min((ymax - y) - tmid, tmid + 1)
- value = 0
- for s in range(s_from, s_to):
- for t in range(t_from, t_to):
- v = x - smid + s
- w = y - tmid + t
- value += g[smid - s, tmid - t] * f[v, w]
- h[x, y] = value
- return h
+import numpy as np
+
+
+def naive_convolve(f, g):
+ # f is an image and is indexed by (v, w)
+ # g is a filter kernel and is indexed by (s, t),
+ # it needs odd dimensions
+ # h is the output image and is indexed by (x, y),
+ # it is not cropped
+ if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1:
+ raise ValueError("Only odd dimensions on filter supported")
+ # smid and tmid are number of pixels between the center pixel
+ # and the edge, ie for a 5x5 filter they will be 2.
+ #
+ # The output size is calculated by adding smid, tmid to each
+ # side of the dimensions of the input image.
+ vmax = f.shape[0]
+ wmax = f.shape[1]
+ smax = g.shape[0]
+ tmax = g.shape[1]
+ smid = smax // 2
+ tmid = tmax // 2
+ xmax = vmax + 2 * smid
+ ymax = wmax + 2 * tmid
+ # Allocate result image.
+ h = np.zeros([xmax, ymax], dtype=f.dtype)
+ # Do convolution
+ for x in range(xmax):
+ for y in range(ymax):
+ # Calculate pixel value for h at (x,y). Sum one component
+ # for each pixel (s, t) of the filter g.
+ s_from = max(smid - x, -smid)
+ s_to = min((xmax - x) - smid, smid + 1)
+ t_from = max(tmid - y, -tmid)
+ t_to = min((ymax - y) - tmid, tmid + 1)
+ value = 0
+ for s in range(s_from, s_to):
+ for t in range(t_from, t_to):
+ v = x - smid + s
+ w = y - tmid + t
+ value += g[smid - s, tmid - t] * f[v, w]
+ h[x, y] = value
+ return h
diff --git a/docs/examples/tutorial/parallelization/manual_work.py b/docs/examples/tutorial/parallelization/manual_work.py
new file mode 100644
index 000000000..d6b0167d9
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/manual_work.py
@@ -0,0 +1,24 @@
+# tag: openmp
+
+from cython.parallel import parallel
+from cython.cimports.openmp import omp_get_thread_num
+import cython
+
+@cython.cfunc
+@cython.nogil
+def long_running_task1() -> cython.void:
+ pass
+
+@cython.cfunc
+@cython.nogil
+def long_running_task2() -> cython.void:
+ pass
+
+def do_two_tasks():
+ thread_num: cython.int
+ with cython.nogil, parallel(num_threads=2):
+ thread_num = omp_get_thread_num()
+ if thread_num == 0:
+ long_running_task1()
+ elif thread_num == 1:
+ long_running_task2()
diff --git a/docs/examples/tutorial/parallelization/manual_work.pyx b/docs/examples/tutorial/parallelization/manual_work.pyx
new file mode 100644
index 000000000..886015839
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/manual_work.pyx
@@ -0,0 +1,25 @@
+# tag: openmp
+
+from cython.parallel cimport parallel
+from openmp cimport omp_get_thread_num
+
+
+
+
+cdef void long_running_task1() nogil:
+ pass
+
+
+
+cdef void long_running_task2() nogil:
+ pass
+
+def do_two_tasks():
+ cdef int thread_num
+ with nogil, parallel(num_threads=2):
+ thread_num = omp_get_thread_num()
+ if thread_num == 0:
+ long_running_task1()
+ elif thread_num == 1:
+ long_running_task2()
+
diff --git a/docs/examples/tutorial/parallelization/median.py b/docs/examples/tutorial/parallelization/median.py
new file mode 100644
index 000000000..535a2b136
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/median.py
@@ -0,0 +1,35 @@
+# distutils: language = c++
+
+from cython.parallel import parallel, prange
+from cython.cimports.libc.stdlib import malloc, free
+from cython.cimports.libcpp.algorithm import nth_element
+import cython
+from cython.operator import dereference
+
+import numpy as np
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def median_along_axis0(x: cython.double[:,:]):
+ out: cython.double[::1] = np.empty(x.shape[1])
+ i: cython.Py_ssize_t
+ j: cython.Py_ssize_t
+ scratch: cython.pointer(cython.double)
+ median_it: cython.pointer(cython.double)
+ with cython.nogil, parallel():
+ # allocate scratch space per loop
+ scratch = cython.cast(
+ cython.pointer(cython.double),
+ malloc(cython.sizeof(cython.double)*x.shape[0]))
+ try:
+ for i in prange(x.shape[1]):
+ # copy row into scratch space
+ for j in range(x.shape[0]):
+ scratch[j] = x[j, i]
+ median_it = scratch + x.shape[0]//2
+ nth_element(scratch, median_it, scratch + x.shape[0])
+ # for the sake of a simple example, don't handle even lengths...
+ out[i] = dereference(median_it)
+ finally:
+ free(scratch)
+ return np.asarray(out)
diff --git a/docs/examples/tutorial/parallelization/median.pyx b/docs/examples/tutorial/parallelization/median.pyx
new file mode 100644
index 000000000..242cb6091
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/median.pyx
@@ -0,0 +1,34 @@
+# distutils: language = c++
+
+from cython.parallel cimport parallel, prange
+from libcpp.vector cimport vector
+from libcpp.algorithm cimport nth_element
+cimport cython
+from cython.operator cimport dereference
+
+import numpy as np
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def median_along_axis0(const double[:,:] x):
+ cdef double[::1] out = np.empty(x.shape[1])
+ cdef Py_ssize_t i, j
+
+ cdef vector[double] *scratch
+ cdef vector[double].iterator median_it
+ with nogil, parallel():
+ # allocate scratch space per loop
+ scratch = new vector[double](x.shape[0])
+ try:
+ for i in prange(x.shape[1]):
+ # copy row into scratch space
+ for j in range(x.shape[0]):
+ dereference(scratch)[j] = x[j, i]
+ median_it = scratch.begin() + scratch.size()//2
+ nth_element(scratch.begin(), median_it, scratch.end())
+ # for the sake of a simple example, don't handle even lengths...
+ out[i] = dereference(median_it)
+ finally:
+ del scratch
+ return np.asarray(out)
+
diff --git a/docs/examples/tutorial/parallelization/norm.py b/docs/examples/tutorial/parallelization/norm.py
new file mode 100644
index 000000000..1d8c2758a
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/norm.py
@@ -0,0 +1,12 @@
+from cython.parallel import prange
+import cython
+from cython.cimports.libc.math import sqrt
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def l2norm(x: cython.double[:]):
+ total: cython.double = 0
+ i: cython.Py_ssize_t
+ for i in prange(x.shape[0], nogil=True):
+ total += x[i]*x[i]
+ return sqrt(total)
diff --git a/docs/examples/tutorial/parallelization/norm.pyx b/docs/examples/tutorial/parallelization/norm.pyx
new file mode 100644
index 000000000..5a702f975
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/norm.pyx
@@ -0,0 +1,12 @@
+from cython.parallel cimport prange
+cimport cython
+from libc.math cimport sqrt
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def l2norm(double[:] x):
+ cdef double total = 0
+ cdef Py_ssize_t i
+ for i in prange(x.shape[0], nogil=True):
+ total += x[i]*x[i]
+ return sqrt(total)
diff --git a/docs/examples/tutorial/parallelization/normalize.py b/docs/examples/tutorial/parallelization/normalize.py
new file mode 100644
index 000000000..0519be4d4
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/normalize.py
@@ -0,0 +1,16 @@
+from cython.parallel import parallel, prange
+import cython
+from cython.cimports.libc.math import sqrt
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def normalize(x: cython.double[:]):
+ i: cython.Py_ssize_t
+ total: cython.double = 0
+ norm: cython.double
+ with cython.nogil, parallel():
+ for i in prange(x.shape[0]):
+ total += x[i]*x[i]
+ norm = sqrt(total)
+ for i in prange(x.shape[0]):
+ x[i] /= norm
diff --git a/docs/examples/tutorial/parallelization/normalize.pyx b/docs/examples/tutorial/parallelization/normalize.pyx
new file mode 100644
index 000000000..e167ad7ad
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/normalize.pyx
@@ -0,0 +1,17 @@
+from cython.parallel cimport parallel, prange
+cimport cython
+from libc.math cimport sqrt
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def normalize(double[:] x):
+ cdef Py_ssize_t i
+ cdef double total = 0
+ cdef double norm
+ with nogil, parallel():
+ for i in prange(x.shape[0]):
+ total += x[i]*x[i]
+ norm = sqrt(total)
+ for i in prange(x.shape[0]):
+ x[i] /= norm
+
diff --git a/docs/examples/tutorial/parallelization/parallel_sin.py b/docs/examples/tutorial/parallelization/parallel_sin.py
new file mode 100644
index 000000000..be6cbc030
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/parallel_sin.py
@@ -0,0 +1,16 @@
+from cython.parallel import prange
+import cython
+from cython.cimports.libc.math import sin
+
+import numpy as np
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def do_sine(input: cython.double[:,:]):
+ output : cython.double[:,:] = np.empty_like(input)
+ i : cython.Py_ssize_t
+ j : cython.Py_ssize_t
+ for i in prange(input.shape[0], nogil=True):
+ for j in range(input.shape[1]):
+ output[i, j] = sin(input[i, j])
+ return np.asarray(output)
diff --git a/docs/examples/tutorial/parallelization/parallel_sin.pyx b/docs/examples/tutorial/parallelization/parallel_sin.pyx
new file mode 100644
index 000000000..c3091541e
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/parallel_sin.pyx
@@ -0,0 +1,16 @@
+from cython.parallel cimport prange
+cimport cython
+from libc.math cimport sin
+
+import numpy as np
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def do_sine(double[:,:] input):
+ cdef double[:,:] output = np.empty_like(input)
+ cdef Py_ssize_t i, j
+
+ for i in prange(input.shape[0], nogil=True):
+ for j in range(input.shape[1]):
+ output[i, j] = sin(input[i, j])
+ return np.asarray(output)
diff --git a/docs/examples/tutorial/parallelization/setup.py b/docs/examples/tutorial/parallelization/setup.py
new file mode 100644
index 000000000..eb343e5da
--- /dev/null
+++ b/docs/examples/tutorial/parallelization/setup.py
@@ -0,0 +1,29 @@
+from setuptools import Extension, setup
+from Cython.Build import cythonize
+import sys
+
+if sys.platform.startswith("win"):
+ openmp_arg = '/openmp'
+else:
+ openmp_arg = '-fopenmp'
+
+
+ext_modules = [
+ Extension(
+ "*",
+ ["*.pyx"],
+ extra_compile_args=[openmp_arg],
+ extra_link_args=[openmp_arg],
+ ),
+ Extension(
+ "*",
+ ["*.pyx"],
+ extra_compile_args=[openmp_arg],
+ extra_link_args=[openmp_arg],
+ )
+]
+
+setup(
+ name='parallel-tutorial',
+ ext_modules=cythonize(ext_modules),
+)
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi.py b/docs/examples/tutorial/profiling_tutorial/calc_pi.py
index bc265e560..3775eb816 100644
--- a/docs/examples/tutorial/profiling_tutorial/calc_pi.py
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi.py
@@ -1,10 +1,8 @@
-# calc_pi.py
-
-def recip_square(i):
- return 1. / i ** 2
-
-def approx_pi(n=10000000):
- val = 0.
- for k in range(1, n + 1):
- val += recip_square(k)
- return (6 * val) ** .5
+def recip_square(i):
+ return 1. / i ** 2
+
+def approx_pi(n=10000000):
+ val = 0.
+ for k in range(1, n + 1):
+ val += recip_square(k)
+ return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi_2.py b/docs/examples/tutorial/profiling_tutorial/calc_pi_2.py
new file mode 100644
index 000000000..b05eeedb5
--- /dev/null
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi_2.py
@@ -0,0 +1,12 @@
+# cython: profile=True
+import cython
+
+def recip_square(i: cython.longlong):
+ return 1. / i ** 2
+
+def approx_pi(n: cython.int = 10000000):
+ val: cython.double = 0.
+ k: cython.int
+ for k in range(1, n + 1):
+ val += recip_square(k)
+ return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi_2.pyx b/docs/examples/tutorial/profiling_tutorial/calc_pi_2.pyx
index dab8d238d..485bbabf8 100644
--- a/docs/examples/tutorial/profiling_tutorial/calc_pi_2.pyx
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi_2.pyx
@@ -1,13 +1,11 @@
-# cython: profile=True
-
-# calc_pi.pyx
-
-def recip_square(int i):
- return 1. / i ** 2
-
-def approx_pi(int n=10000000):
- cdef double val = 0.
- cdef int k
- for k in range(1, n + 1):
- val += recip_square(k)
- return (6 * val) ** .5
+# cython: profile=True
+
+def recip_square(int i):
+ return 1. / i ** 2
+
+def approx_pi(int n=10000000):
+ cdef double val = 0.
+ cdef int k
+ for k in range(1, n + 1):
+ val += recip_square(k)
+ return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi_3.py b/docs/examples/tutorial/profiling_tutorial/calc_pi_3.py
new file mode 100644
index 000000000..df3dfa3a1
--- /dev/null
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi_3.py
@@ -0,0 +1,15 @@
+# cython: profile=True
+import cython
+
+@cython.cfunc
+@cython.inline
+@cython.exceptval(-1.0)
+def recip_square(i: cython.longlong) -> cython.double:
+ return 1. / (i * i)
+
+def approx_pi(n: cython.int = 10000000):
+ val: cython.double = 0.
+ k: cython.int
+ for k in range(1, n + 1):
+ val += recip_square(k)
+ return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi_3.pyx b/docs/examples/tutorial/profiling_tutorial/calc_pi_3.pyx
index 0f0bdb18a..742991b1a 100644
--- a/docs/examples/tutorial/profiling_tutorial/calc_pi_3.pyx
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi_3.pyx
@@ -1,13 +1,14 @@
-# cython: profile=True
-
-# calc_pi.pyx
-
-cdef inline double recip_square(int i):
- return 1. / (i * i)
-
-def approx_pi(int n=10000000):
- cdef double val = 0.
- cdef int k
- for k in range(1, n + 1):
- val += recip_square(k)
- return (6 * val) ** .5
+# cython: profile=True
+
+
+
+
+cdef inline double recip_square(long long i) except -1.0:
+ return 1. / (i * i)
+
+def approx_pi(int n=10000000):
+ cdef double val = 0.
+ cdef int k
+ for k in range(1, n + 1):
+ val += recip_square(k)
+ return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi_4.py b/docs/examples/tutorial/profiling_tutorial/calc_pi_4.py
new file mode 100644
index 000000000..b457cd99d
--- /dev/null
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi_4.py
@@ -0,0 +1,17 @@
+# cython: profile=True
+
+import cython
+
+@cython.profile(False)
+@cython.cfunc
+@cython.inline
+@cython.exceptval(-1.0)
+def recip_square(i: cython.longlong) -> float:
+ return 1. / (i * i)
+
+def approx_pi(n: cython.int = 10000000):
+ val: cython.double = 0.
+ k: cython.int
+ for k in range(1, n + 1):
+ val += recip_square(k)
+ return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi_4.pyx b/docs/examples/tutorial/profiling_tutorial/calc_pi_4.pyx
index ab3f9ea9f..415ac4a22 100644
--- a/docs/examples/tutorial/profiling_tutorial/calc_pi_4.pyx
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi_4.pyx
@@ -1,16 +1,17 @@
-# cython: profile=True
-
-# calc_pi.pyx
-
-cimport cython
-
-@cython.profile(False)
-cdef inline double recip_square(int i):
- return 1. / (i * i)
-
-def approx_pi(int n=10000000):
- cdef double val = 0.
- cdef int k
- for k in range(1, n + 1):
- val += recip_square(k)
- return (6 * val) ** .5
+# cython: profile=True
+
+cimport cython
+
+
+
+
+@cython.profile(False)
+cdef inline double recip_square(long long i) except -1.0:
+ return 1. / (i * i)
+
+def approx_pi(int n=10000000):
+ cdef double val = 0.
+ cdef int k
+ for k in range(1, n + 1):
+ val += recip_square(k)
+ return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/often_called.py b/docs/examples/tutorial/profiling_tutorial/often_called.py
new file mode 100644
index 000000000..15197cb97
--- /dev/null
+++ b/docs/examples/tutorial/profiling_tutorial/often_called.py
@@ -0,0 +1,5 @@
+import cython
+
+@cython.profile(False)
+def my_often_called_function():
+ pass
diff --git a/docs/examples/tutorial/profiling_tutorial/often_called.pyx b/docs/examples/tutorial/profiling_tutorial/often_called.pyx
index 77c689c9c..3699dce4f 100644
--- a/docs/examples/tutorial/profiling_tutorial/often_called.pyx
+++ b/docs/examples/tutorial/profiling_tutorial/often_called.pyx
@@ -1,5 +1,5 @@
-cimport cython
-
-@cython.profile(False)
-def my_often_called_function():
- pass
+cimport cython
+
+@cython.profile(False)
+def my_often_called_function():
+ pass
diff --git a/docs/examples/tutorial/profiling_tutorial/profile.py b/docs/examples/tutorial/profiling_tutorial/profile.py
index 1c12bf971..c0b76472a 100644
--- a/docs/examples/tutorial/profiling_tutorial/profile.py
+++ b/docs/examples/tutorial/profiling_tutorial/profile.py
@@ -1,10 +1,8 @@
-# profile.py
-
-import pstats, cProfile
-
-import calc_pi
-
-cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
-
-s = pstats.Stats("Profile.prof")
-s.strip_dirs().sort_stats("time").print_stats()
+import pstats, cProfile
+
+import calc_pi
+
+cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
+
+s = pstats.Stats("Profile.prof")
+s.strip_dirs().sort_stats("time").print_stats()
diff --git a/docs/examples/tutorial/profiling_tutorial/profile_2.py b/docs/examples/tutorial/profiling_tutorial/profile_2.py
index 38fb50104..ca5ca514b 100644
--- a/docs/examples/tutorial/profiling_tutorial/profile_2.py
+++ b/docs/examples/tutorial/profiling_tutorial/profile_2.py
@@ -1,13 +1,11 @@
-# profile.py
-
-import pstats, cProfile
-
-import pyximport
-pyximport.install()
-
-import calc_pi
-
-cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
-
-s = pstats.Stats("Profile.prof")
-s.strip_dirs().sort_stats("time").print_stats()
+import pstats, cProfile
+
+import pyximport
+pyximport.install()
+
+import calc_pi
+
+cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
+
+s = pstats.Stats("Profile.prof")
+s.strip_dirs().sort_stats("time").print_stats()
diff --git a/docs/examples/tutorial/pure/A.py b/docs/examples/tutorial/pure/A.py
index 1e0cea950..98d5530c8 100644
--- a/docs/examples/tutorial/pure/A.py
+++ b/docs/examples/tutorial/pure/A.py
@@ -1,14 +1,14 @@
-def myfunction(x, y=2):
- a = x - y
- return a + x * y
-
-def _helper(a):
- return a + 1
-
-class A:
- def __init__(self, b=0):
- self.a = 3
- self.b = b
-
- def foo(self, x):
- print(x + _helper(1.0))
+def myfunction(x, y=2):
+ a = x - y
+ return a + x * y
+
+def _helper(a):
+ return a + 1
+
+class A:
+ def __init__(self, b=0):
+ self.a = 3
+ self.b = b
+
+ def foo(self, x):
+ print(x + _helper(1.0))
diff --git a/docs/examples/tutorial/pure/A_equivalent.pyx b/docs/examples/tutorial/pure/A_equivalent.pyx
index 1b256a010..ab9e0081c 100644
--- a/docs/examples/tutorial/pure/A_equivalent.pyx
+++ b/docs/examples/tutorial/pure/A_equivalent.pyx
@@ -1,15 +1,15 @@
-cpdef int myfunction(int x, int y=2):
- a = x - y
- return a + x * y
-
-cdef double _helper(double a):
- return a + 1
-
-cdef class A:
- cdef public int a, b
- def __init__(self, b=0):
- self.a = 3
- self.b = b
-
- cpdef foo(self, double x):
- print(x + _helper(1.0))
+cpdef int myfunction(int x, int y=2):
+ a = x - y
+ return a + x * y
+
+cdef double _helper(double a):
+ return a + 1
+
+cdef class A:
+ cdef public int a, b
+ def __init__(self, b=0):
+ self.a = 3
+ self.b = b
+
+ cpdef foo(self, double x):
+ print(x + _helper(1.0))
diff --git a/docs/examples/tutorial/pure/annotations.py b/docs/examples/tutorial/pure/annotations.py
index 2b8487c0b..09682c352 100644
--- a/docs/examples/tutorial/pure/annotations.py
+++ b/docs/examples/tutorial/pure/annotations.py
@@ -1,5 +1,5 @@
-import cython
-
-def func(foo: dict, bar: cython.int) -> tuple:
- foo["hello world"] = 3 + bar
- return foo, 5
+import cython
+
+def func(foo: dict, bar: cython.int) -> tuple:
+ foo["hello world"] = 3 + bar
+ return foo, 5
diff --git a/docs/examples/tutorial/pure/c_arrays.py b/docs/examples/tutorial/pure/c_arrays.py
index 33067da68..f221b7ae8 100644
--- a/docs/examples/tutorial/pure/c_arrays.py
+++ b/docs/examples/tutorial/pure/c_arrays.py
@@ -1,15 +1,15 @@
-import cython
-
-
-@cython.locals(counts=cython.int[10], digit=cython.int)
-def count_digits(digits):
- """
- >>> digits = '01112222333334445667788899'
- >>> count_digits(map(int, digits))
- [1, 3, 4, 5, 3, 1, 2, 2, 3, 2]
- """
- counts = [0] * 10
- for digit in digits:
- assert 0 <= digit <= 9
- counts[digit] += 1
- return counts
+import cython
+
+
+@cython.locals(counts=cython.int[10], digit=cython.int)
+def count_digits(digits):
+ """
+ >>> digits = '01112222333334445667788899'
+ >>> count_digits(map(int, digits))
+ [1, 3, 4, 5, 3, 1, 2, 2, 3, 2]
+ """
+ counts = [0] * 10
+ for digit in digits:
+ assert 0 <= digit <= 9
+ counts[digit] += 1
+ return counts
diff --git a/docs/examples/tutorial/pure/cclass.py b/docs/examples/tutorial/pure/cclass.py
index 61c65183d..7f9cb1a04 100644
--- a/docs/examples/tutorial/pure/cclass.py
+++ b/docs/examples/tutorial/pure/cclass.py
@@ -1,16 +1,16 @@
-import cython
-
-
-@cython.cclass
-class A:
- cython.declare(a=cython.int, b=cython.int)
- c = cython.declare(cython.int, visibility='public')
- d = cython.declare(cython.int) # private by default.
- e = cython.declare(cython.int, visibility='readonly')
-
- def __init__(self, a, b, c, d=5, e=3):
- self.a = a
- self.b = b
- self.c = c
- self.d = d
- self.e = e
+import cython
+
+
+@cython.cclass
+class A:
+ cython.declare(a=cython.int, b=cython.int)
+ c = cython.declare(cython.int, visibility='public')
+ d = cython.declare(cython.int) # private by default.
+ e = cython.declare(cython.int, visibility='readonly')
+
+ def __init__(self, a, b, c, d=5, e=3):
+ self.a = a
+ self.b = b
+ self.c = c
+ self.d = d
+ self.e = e
diff --git a/docs/examples/tutorial/pure/compiled_switch.py b/docs/examples/tutorial/pure/compiled_switch.py
index 47d62a3e6..a35cac2c6 100644
--- a/docs/examples/tutorial/pure/compiled_switch.py
+++ b/docs/examples/tutorial/pure/compiled_switch.py
@@ -1,6 +1,6 @@
-import cython
-
-if cython.compiled:
- print("Yep, I'm compiled.")
-else:
- print("Just a lowly interpreted script.")
+import cython
+
+if cython.compiled:
+ print("Yep, I'm compiled.")
+else:
+ print("Just a lowly interpreted script.")
diff --git a/docs/examples/tutorial/pure/cython_declare.py b/docs/examples/tutorial/pure/cython_declare.py
index cf6d58bba..50a4ab8aa 100644
--- a/docs/examples/tutorial/pure/cython_declare.py
+++ b/docs/examples/tutorial/pure/cython_declare.py
@@ -1,4 +1,4 @@
-import cython
-
-x = cython.declare(cython.int) # cdef int x
-y = cython.declare(cython.double, 0.57721) # cdef double y = 0.57721
+import cython
+
+x = cython.declare(cython.int) # cdef int x
+y = cython.declare(cython.double, 0.57721) # cdef double y = 0.57721
diff --git a/docs/examples/tutorial/pure/cython_declare2.py b/docs/examples/tutorial/pure/cython_declare2.py
index 35fae7d7b..ee491d62b 100644
--- a/docs/examples/tutorial/pure/cython_declare2.py
+++ b/docs/examples/tutorial/pure/cython_declare2.py
@@ -1,3 +1,3 @@
-import cython
-
-cython.declare(x=cython.int, y=cython.double) # cdef int x; cdef double y
+import cython
+
+cython.declare(x=cython.int, y=cython.double) # cdef int x; cdef double y
diff --git a/docs/examples/tutorial/pure/disabled_annotations.py b/docs/examples/tutorial/pure/disabled_annotations.py
new file mode 100644
index 000000000..c92b4cf8e
--- /dev/null
+++ b/docs/examples/tutorial/pure/disabled_annotations.py
@@ -0,0 +1,33 @@
+import cython
+
+@cython.annotation_typing(False)
+def function_without_typing(a: int, b: int) -> int:
+ """Cython is ignoring annotations in this function"""
+ c: int = a + b
+ return c * a
+
+
+@cython.annotation_typing(False)
+@cython.cclass
+class NotAnnotatedClass:
+ """Cython is ignoring annotatons in this class except annotated_method"""
+ d: dict
+
+ def __init__(self, dictionary: dict):
+ self.d = dictionary
+
+ @cython.annotation_typing(True)
+ def annotated_method(self, key: str, a: cython.int, b: cython.int):
+ prefixed_key: str = 'prefix_' + key
+ self.d[prefixed_key] = a + b
+
+
+def annotated_function(a: cython.int, b: cython.int):
+ s: cython.int = a + b
+ with cython.annotation_typing(False):
+ # Cython is ignoring annotations within this code block
+ c: list = []
+ c.append(a)
+ c.append(b)
+ c.append(s)
+ return c
diff --git a/docs/examples/tutorial/pure/dostuff.py b/docs/examples/tutorial/pure/dostuff.py
index 748c31b10..7a88533c5 100644
--- a/docs/examples/tutorial/pure/dostuff.py
+++ b/docs/examples/tutorial/pure/dostuff.py
@@ -1,5 +1,5 @@
-def dostuff(n):
- t = 0
- for i in range(n):
- t += i
- return t
+def dostuff(n):
+ t = 0
+ for i in range(n):
+ t += i
+ return t
diff --git a/docs/examples/tutorial/pure/exceptval.py b/docs/examples/tutorial/pure/exceptval.py
index 8bf564040..3d991f7c1 100644
--- a/docs/examples/tutorial/pure/exceptval.py
+++ b/docs/examples/tutorial/pure/exceptval.py
@@ -1,7 +1,7 @@
-import cython
-
-@cython.exceptval(-1)
-def func(x: cython.int) -> cython.int:
- if x < 0:
- raise ValueError("need integer >= 0")
- return x + 1
+import cython
+
+@cython.exceptval(-1)
+def func(x: cython.int) -> cython.int:
+ if x < 0:
+ raise ValueError("need integer >= 0")
+ return x + 1
diff --git a/docs/examples/tutorial/pure/locals.py b/docs/examples/tutorial/pure/locals.py
index 8eda7114a..b273a9ebe 100644
--- a/docs/examples/tutorial/pure/locals.py
+++ b/docs/examples/tutorial/pure/locals.py
@@ -1,6 +1,6 @@
-import cython
-
-@cython.locals(a=cython.long, b=cython.long, n=cython.longlong)
-def foo(a, b, x, y):
- n = a * b
- # ...
+import cython
+
+@cython.locals(a=cython.long, b=cython.long, n=cython.longlong)
+def foo(a, b, x, y):
+ n = a * b
+ # ...
diff --git a/docs/examples/tutorial/pure/mymodule.py b/docs/examples/tutorial/pure/mymodule.py
index 62d4c76ac..83f5cdc28 100644
--- a/docs/examples/tutorial/pure/mymodule.py
+++ b/docs/examples/tutorial/pure/mymodule.py
@@ -1,10 +1,10 @@
-# mymodule.py
-
-import cython
-
-# override with Python import if not in compiled code
-if not cython.compiled:
- from math import sin
-
-# calls sin() from math.h when compiled with Cython and math.sin() in Python
-print(sin(0))
+# mymodule.py
+
+import cython
+
+# override with Python import if not in compiled code
+if not cython.compiled:
+ from math import sin
+
+# calls sin() from math.h when compiled with Cython and math.sin() in Python
+print(sin(0))
diff --git a/docs/examples/tutorial/pure/pep_526.py b/docs/examples/tutorial/pure/pep_526.py
index 163d97859..ecb3bfcdf 100644
--- a/docs/examples/tutorial/pure/pep_526.py
+++ b/docs/examples/tutorial/pure/pep_526.py
@@ -1,22 +1,22 @@
-import cython
-
-def func():
- # Cython types are evaluated as for cdef declarations
- x: cython.int # cdef int x
- y: cython.double = 0.57721 # cdef double y = 0.57721
- z: cython.float = 0.57721 # cdef float z = 0.57721
-
- # Python types shadow Cython types for compatibility reasons
- a: float = 0.54321 # cdef double a = 0.54321
- b: int = 5 # cdef object b = 5
- c: long = 6 # cdef object c = 6
- pass
-
-@cython.cclass
-class A:
- a: cython.int
- b: cython.int
-
- def __init__(self, b=0):
- self.a = 3
- self.b = b
+import cython
+
+def func():
+ # Cython types are evaluated as for cdef declarations
+ x: cython.int # cdef int x
+ y: cython.double = 0.57721 # cdef double y = 0.57721
+ z: cython.float = 0.57721 # cdef float z = 0.57721
+
+ # Python types shadow Cython types for compatibility reasons
+ a: float = 0.54321 # cdef double a = 0.54321
+ b: int = 5 # cdef object b = 5
+ c: long = 6 # cdef object c = 6
+ pass
+
+@cython.cclass
+class A:
+ a: cython.int
+ b: cython.int
+
+ def __init__(self, b=0):
+ self.a = 3
+ self.b = b
diff --git a/docs/examples/tutorial/pure/py_cimport.py b/docs/examples/tutorial/pure/py_cimport.py
new file mode 100644
index 000000000..233ddde7e
--- /dev/null
+++ b/docs/examples/tutorial/pure/py_cimport.py
@@ -0,0 +1,5 @@
+
+from cython.cimports.libc import math
+
+def use_libc_math():
+ return math.ceil(5.5)
diff --git a/docs/examples/tutorial/string/api_func.pyx b/docs/examples/tutorial/string/api_func.pyx
index ec6b27751..c9e05f9e3 100644
--- a/docs/examples/tutorial/string/api_func.pyx
+++ b/docs/examples/tutorial/string/api_func.pyx
@@ -1,5 +1,5 @@
-from to_unicode cimport _text
-
-def api_func(s):
- text_input = _text(s)
- # ...
+from to_unicode cimport _text
+
+def api_func(s):
+ text_input = _text(s)
+ # ...
diff --git a/docs/examples/tutorial/string/arg_memview.pyx b/docs/examples/tutorial/string/arg_memview.pyx
index 63a18f943..e2b6d75be 100644
--- a/docs/examples/tutorial/string/arg_memview.pyx
+++ b/docs/examples/tutorial/string/arg_memview.pyx
@@ -1,5 +1,5 @@
-def process_byte_data(unsigned char[:] data):
- length = data.shape[0]
- first_byte = data[0]
- slice_view = data[1:-1]
- # ...
+def process_byte_data(unsigned char[:] data):
+ length = data.shape[0]
+ first_byte = data[0]
+ slice_view = data[1:-1]
+ # ...
diff --git a/docs/examples/tutorial/string/auto_conversion_1.pyx b/docs/examples/tutorial/string/auto_conversion_1.pyx
index 929c03d68..ee2b116e4 100644
--- a/docs/examples/tutorial/string/auto_conversion_1.pyx
+++ b/docs/examples/tutorial/string/auto_conversion_1.pyx
@@ -1,9 +1,9 @@
-# cython: c_string_type=unicode, c_string_encoding=utf8
-
-cdef char* c_string = 'abcdefg'
-
-# implicit decoding:
-cdef object py_unicode_object = c_string
-
-# explicit conversion to Python bytes:
-py_bytes_object = <bytes>c_string
+# cython: c_string_type=unicode, c_string_encoding=utf8
+
+cdef char* c_string = 'abcdefg'
+
+# implicit decoding:
+cdef object py_unicode_object = c_string
+
+# explicit conversion to Python bytes:
+py_bytes_object = <bytes>c_string
diff --git a/docs/examples/tutorial/string/auto_conversion_2.pyx b/docs/examples/tutorial/string/auto_conversion_2.pyx
index 84436661d..9f7a5ad04 100644
--- a/docs/examples/tutorial/string/auto_conversion_2.pyx
+++ b/docs/examples/tutorial/string/auto_conversion_2.pyx
@@ -1,12 +1,12 @@
-# cython: c_string_type=str, c_string_encoding=ascii
-
-cdef char* c_string = 'abcdefg'
-
-# implicit decoding in Py3, bytes conversion in Py2:
-cdef object py_str_object = c_string
-
-# explicit conversion to Python bytes:
-py_bytes_object = <bytes>c_string
-
-# explicit conversion to Python unicode:
-py_bytes_object = <unicode>c_string
+# cython: c_string_type=str, c_string_encoding=ascii
+
+cdef char* c_string = 'abcdefg'
+
+# implicit decoding in Py3, bytes conversion in Py2:
+cdef object py_str_object = c_string
+
+# explicit conversion to Python bytes:
+py_bytes_object = <bytes>c_string
+
+# explicit conversion to Python unicode:
+py_bytes_object = <unicode>c_string
diff --git a/docs/examples/tutorial/string/auto_conversion_3.pyx b/docs/examples/tutorial/string/auto_conversion_3.pyx
index 509d7e324..b9a1b7517 100644
--- a/docs/examples/tutorial/string/auto_conversion_3.pyx
+++ b/docs/examples/tutorial/string/auto_conversion_3.pyx
@@ -1,6 +1,6 @@
-# cython: c_string_type=unicode, c_string_encoding=ascii
-
-def func():
- ustring = u'abc'
- cdef char* s = ustring
- return s[0] # returns u'a'
+# cython: c_string_type=unicode, c_string_encoding=ascii
+
+def func():
+ ustring = u'abc'
+ cdef char* s = ustring
+ return s[0] # returns u'a'
diff --git a/docs/examples/tutorial/string/c_func.pyx b/docs/examples/tutorial/string/c_func.pyx
index a456b815b..4763f2671 100644
--- a/docs/examples/tutorial/string/c_func.pyx
+++ b/docs/examples/tutorial/string/c_func.pyx
@@ -1,22 +1,23 @@
-from libc.stdlib cimport malloc
-from libc.string cimport strcpy, strlen
-
-cdef char* hello_world = 'hello world'
-cdef Py_ssize_t n = strlen(hello_world)
-
-
-cdef char* c_call_returning_a_c_string():
- cdef char* c_string = <char *> malloc((n + 1) * sizeof(char))
- if not c_string:
- raise MemoryError()
- strcpy(c_string, hello_world)
- return c_string
-
-
-cdef void get_a_c_string(char** c_string_ptr, Py_ssize_t *length):
- c_string_ptr[0] = <char *> malloc((n + 1) * sizeof(char))
- if not c_string_ptr[0]:
- raise MemoryError()
-
- strcpy(c_string_ptr[0], hello_world)
- length[0] = n
+from libc.stdlib cimport malloc
+from libc.string cimport strcpy, strlen
+
+cdef char* hello_world = 'hello world'
+cdef Py_ssize_t n = strlen(hello_world)
+
+
+cdef char* c_call_returning_a_c_string():
+ cdef char* c_string = <char *> malloc((n + 1) * sizeof(char))
+ if not c_string:
+ return NULL # malloc failed
+
+ strcpy(c_string, hello_world)
+ return c_string
+
+
+cdef void get_a_c_string(char** c_string_ptr, Py_ssize_t *length):
+ c_string_ptr[0] = <char *> malloc((n + 1) * sizeof(char))
+ if not c_string_ptr[0]:
+ return # malloc failed
+
+ strcpy(c_string_ptr[0], hello_world)
+ length[0] = n
diff --git a/docs/examples/tutorial/string/const.pyx b/docs/examples/tutorial/string/const.pyx
index e066c77ac..0b89b9e41 100644
--- a/docs/examples/tutorial/string/const.pyx
+++ b/docs/examples/tutorial/string/const.pyx
@@ -1,4 +1,4 @@
-cdef extern from "someheader.h":
- ctypedef const char specialChar
- int process_string(const char* s)
- const unsigned char* look_up_cached_string(const unsigned char* key)
+cdef extern from "someheader.h":
+ ctypedef const char specialChar
+ int process_string(const char* s)
+ const unsigned char* look_up_cached_string(const unsigned char* key)
diff --git a/docs/examples/tutorial/string/cpp_string.pyx b/docs/examples/tutorial/string/cpp_string.pyx
index b6c9e44f9..313e72a67 100644
--- a/docs/examples/tutorial/string/cpp_string.pyx
+++ b/docs/examples/tutorial/string/cpp_string.pyx
@@ -1,12 +1,12 @@
-# distutils: language = c++
-
-from libcpp.string cimport string
-
-def get_bytes():
- py_bytes_object = b'hello world'
- cdef string s = py_bytes_object
-
- s.append('abc')
- py_bytes_object = s
- return py_bytes_object
-
+# distutils: language = c++
+
+from libcpp.string cimport string
+
+def get_bytes():
+ py_bytes_object = b'hello world'
+ cdef string s = py_bytes_object
+
+ s.append('abc')
+ py_bytes_object = s
+ return py_bytes_object
+
diff --git a/docs/examples/tutorial/string/decode.pyx b/docs/examples/tutorial/string/decode.pyx
index c3e2faf68..79fc41835 100644
--- a/docs/examples/tutorial/string/decode.pyx
+++ b/docs/examples/tutorial/string/decode.pyx
@@ -1,9 +1,9 @@
-from c_func cimport get_a_c_string
-
-cdef char* c_string = NULL
-cdef Py_ssize_t length = 0
-
-# get pointer and length from a C function
-get_a_c_string(&c_string, &length)
-
-ustring = c_string[:length].decode('UTF-8')
+from c_func cimport get_a_c_string
+
+cdef char* c_string = NULL
+cdef Py_ssize_t length = 0
+
+# get pointer and length from a C function
+get_a_c_string(&c_string, &length)
+
+ustring = c_string[:length].decode('UTF-8')
diff --git a/docs/examples/tutorial/string/decode_cpp_string.pyx b/docs/examples/tutorial/string/decode_cpp_string.pyx
index 8f1d01af8..52861c209 100644
--- a/docs/examples/tutorial/string/decode_cpp_string.pyx
+++ b/docs/examples/tutorial/string/decode_cpp_string.pyx
@@ -1,10 +1,10 @@
-# distutils: language = c++
-
-from libcpp.string cimport string
-
-def get_ustrings():
- cdef string s = string(b'abcdefg')
-
- ustring1 = s.decode('UTF-8')
- ustring2 = s[2:-2].decode('UTF-8')
- return ustring1, ustring2
+# distutils: language = c++
+
+from libcpp.string cimport string
+
+def get_ustrings():
+ cdef string s = string(b'abcdefg')
+
+ ustring1 = s.decode('UTF-8')
+ ustring2 = s[2:-2].decode('UTF-8')
+ return ustring1, ustring2
diff --git a/docs/examples/tutorial/string/for_bytes.pyx b/docs/examples/tutorial/string/for_bytes.pyx
index 69e9202ae..d4d3e1f81 100644
--- a/docs/examples/tutorial/string/for_bytes.pyx
+++ b/docs/examples/tutorial/string/for_bytes.pyx
@@ -1,6 +1,6 @@
-cdef bytes bytes_string = b"hello to A bytes' world"
-
-cdef char c
-for c in bytes_string:
- if c == 'A':
- print("Found the letter A")
+cdef bytes bytes_string = b"hello to A bytes' world"
+
+cdef char c
+for c in bytes_string:
+ if c == 'A':
+ print("Found the letter A")
diff --git a/docs/examples/tutorial/string/for_char.pyx b/docs/examples/tutorial/string/for_char.pyx
index adc16bcd8..81abae97c 100644
--- a/docs/examples/tutorial/string/for_char.pyx
+++ b/docs/examples/tutorial/string/for_char.pyx
@@ -1,6 +1,6 @@
-cdef char* c_string = "Hello to A C-string's world"
-
-cdef char c
-for c in c_string[:11]:
- if c == 'A':
- print("Found the letter A")
+cdef char* c_string = "Hello to A C-string's world"
+
+cdef char c
+for c in c_string[:11]:
+ if c == 'A':
+ print("Found the letter A")
diff --git a/docs/examples/tutorial/string/for_unicode.pyx b/docs/examples/tutorial/string/for_unicode.pyx
index aabd562e4..0f8ab0c7d 100644
--- a/docs/examples/tutorial/string/for_unicode.pyx
+++ b/docs/examples/tutorial/string/for_unicode.pyx
@@ -1,6 +1,6 @@
-cdef unicode ustring = u'Hello world'
-
-# NOTE: no typing required for 'uchar' !
-for uchar in ustring:
- if uchar == u'A':
- print("Found the letter A")
+cdef unicode ustring = u'Hello world'
+
+# NOTE: no typing required for 'uchar' !
+for uchar in ustring:
+ if uchar == u'A':
+ print("Found the letter A")
diff --git a/docs/examples/tutorial/string/if_char_in.pyx b/docs/examples/tutorial/string/if_char_in.pyx
index 73521b2de..e33e18d59 100644
--- a/docs/examples/tutorial/string/if_char_in.pyx
+++ b/docs/examples/tutorial/string/if_char_in.pyx
@@ -1,5 +1,5 @@
-cpdef void is_in(Py_UCS4 uchar_val):
- if uchar_val in u'abcABCxY':
- print("The character is in the string.")
- else:
- print("The character is not in the string")
+cpdef void is_in(Py_UCS4 uchar_val):
+ if uchar_val in u'abcABCxY':
+ print("The character is in the string.")
+ else:
+ print("The character is not in the string")
diff --git a/docs/examples/tutorial/string/naive_decode.pyx b/docs/examples/tutorial/string/naive_decode.pyx
index 186d2affa..b3c44d9af 100644
--- a/docs/examples/tutorial/string/naive_decode.pyx
+++ b/docs/examples/tutorial/string/naive_decode.pyx
@@ -1,4 +1,4 @@
-from c_func cimport c_call_returning_a_c_string
-
-cdef char* some_c_string = c_call_returning_a_c_string()
-ustring = some_c_string.decode('UTF-8')
+from c_func cimport c_call_returning_a_c_string
+
+cdef char* some_c_string = c_call_returning_a_c_string()
+ustring = some_c_string.decode('UTF-8')
diff --git a/docs/examples/tutorial/string/return_memview.pyx b/docs/examples/tutorial/string/return_memview.pyx
index f6233436a..be9b597a4 100644
--- a/docs/examples/tutorial/string/return_memview.pyx
+++ b/docs/examples/tutorial/string/return_memview.pyx
@@ -1,9 +1,9 @@
-def process_byte_data(unsigned char[:] data):
- # ... process the data, here, dummy processing.
- cdef bint return_all = (data[0] == 108)
-
- if return_all:
- return bytes(data)
- else:
- # example for returning a slice
- return bytes(data[5:7])
+def process_byte_data(unsigned char[:] data):
+ # ... process the data, here, dummy processing.
+ cdef bint return_all = (data[0] == 108)
+
+ if return_all:
+ return bytes(data)
+ else:
+ # example for returning a slice
+ return bytes(data[5:7])
diff --git a/docs/examples/tutorial/string/slicing_c_string.pyx b/docs/examples/tutorial/string/slicing_c_string.pyx
index 2e937430e..f8d272e32 100644
--- a/docs/examples/tutorial/string/slicing_c_string.pyx
+++ b/docs/examples/tutorial/string/slicing_c_string.pyx
@@ -1,15 +1,15 @@
-from libc.stdlib cimport free
-from c_func cimport get_a_c_string
-
-
-def main():
- cdef char* c_string = NULL
- cdef Py_ssize_t length = 0
-
- # get pointer and length from a C function
- get_a_c_string(&c_string, &length)
-
- try:
- py_bytes_string = c_string[:length] # Performs a copy of the data
- finally:
- free(c_string)
+from libc.stdlib cimport free
+from c_func cimport get_a_c_string
+
+
+def main():
+ cdef char* c_string = NULL
+ cdef Py_ssize_t length = 0
+
+ # get pointer and length from a C function
+ get_a_c_string(&c_string, &length)
+
+ try:
+ py_bytes_string = c_string[:length] # Performs a copy of the data
+ finally:
+ free(c_string)
diff --git a/docs/examples/tutorial/string/to_char.pyx b/docs/examples/tutorial/string/to_char.pyx
index 5e4a16161..7912ea485 100644
--- a/docs/examples/tutorial/string/to_char.pyx
+++ b/docs/examples/tutorial/string/to_char.pyx
@@ -1,8 +1,8 @@
-# define a global name for whatever char type is used in the module
-ctypedef unsigned char char_type
-
-cdef char_type[:] _chars(s):
- if isinstance(s, unicode):
- # encode to the specific encoding used inside of the module
- s = (<unicode>s).encode('utf8')
- return s
+# define a global name for whatever char type is used in the module
+ctypedef unsigned char char_type
+
+cdef char_type[:] _chars(s):
+ if isinstance(s, unicode):
+ # encode to the specific encoding used inside of the module
+ s = (<unicode>s).encode('utf8')
+ return s
diff --git a/docs/examples/tutorial/string/to_unicode.pyx b/docs/examples/tutorial/string/to_unicode.pyx
index 8ab8f2662..188a8776e 100644
--- a/docs/examples/tutorial/string/to_unicode.pyx
+++ b/docs/examples/tutorial/string/to_unicode.pyx
@@ -1,22 +1,22 @@
-# to_unicode.pyx
-
-from cpython.version cimport PY_MAJOR_VERSION
-
-cdef unicode _text(s):
- if type(s) is unicode:
- # Fast path for most common case(s).
- return <unicode>s
-
- elif PY_MAJOR_VERSION < 3 and isinstance(s, bytes):
- # Only accept byte strings as text input in Python 2.x, not in Py3.
- return (<bytes>s).decode('ascii')
-
- elif isinstance(s, unicode):
- # We know from the fast path above that 's' can only be a subtype here.
- # An evil cast to <unicode> might still work in some(!) cases,
- # depending on what the further processing does. To be safe,
- # we can always create a copy instead.
- return unicode(s)
-
- else:
- raise TypeError("Could not convert to unicode.")
+# to_unicode.pyx
+
+from cpython.version cimport PY_MAJOR_VERSION
+
+cdef unicode _text(s):
+ if type(s) is unicode:
+ # Fast path for most common case(s).
+ return <unicode>s
+
+ elif PY_MAJOR_VERSION < 3 and isinstance(s, bytes):
+ # Only accept byte strings as text input in Python 2.x, not in Py3.
+ return (<bytes>s).decode('ascii')
+
+ elif isinstance(s, unicode):
+ # We know from the fast path above that 's' can only be a subtype here.
+ # An evil cast to <unicode> might still work in some(!) cases,
+ # depending on what the further processing does. To be safe,
+ # we can always create a copy instead.
+ return unicode(s)
+
+ else:
+ raise TypeError("Could not convert to unicode.")
diff --git a/docs/examples/tutorial/string/try_finally.pyx b/docs/examples/tutorial/string/try_finally.pyx
index aea786f5b..4cf943e56 100644
--- a/docs/examples/tutorial/string/try_finally.pyx
+++ b/docs/examples/tutorial/string/try_finally.pyx
@@ -1,9 +1,9 @@
-from libc.stdlib cimport free
-from c_func cimport c_call_returning_a_c_string
-
-cdef bytes py_string
-cdef char* c_string = c_call_returning_a_c_string()
-try:
- py_string = c_string
-finally:
- free(c_string)
+from libc.stdlib cimport free
+from c_func cimport c_call_returning_a_c_string
+
+cdef bytes py_string
+cdef char* c_string = c_call_returning_a_c_string()
+try:
+ py_string = c_string
+finally:
+ free(c_string)
diff --git a/docs/examples/tutorial/string/utf_eight.pyx b/docs/examples/tutorial/string/utf_eight.pyx
index 7113947f4..654c51ae8 100644
--- a/docs/examples/tutorial/string/utf_eight.pyx
+++ b/docs/examples/tutorial/string/utf_eight.pyx
@@ -1,15 +1,15 @@
-from libc.stdlib cimport free
-
-cdef unicode tounicode(char* s):
- return s.decode('UTF-8', 'strict')
-
-cdef unicode tounicode_with_length(
- char* s, size_t length):
- return s[:length].decode('UTF-8', 'strict')
-
-cdef unicode tounicode_with_length_and_free(
- char* s, size_t length):
- try:
- return s[:length].decode('UTF-8', 'strict')
- finally:
+from libc.stdlib cimport free
+
+cdef unicode tounicode(char* s):
+ return s.decode('UTF-8', 'strict')
+
+cdef unicode tounicode_with_length(
+ char* s, size_t length):
+ return s[:length].decode('UTF-8', 'strict')
+
+cdef unicode tounicode_with_length_and_free(
+ char* s, size_t length):
+ try:
+ return s[:length].decode('UTF-8', 'strict')
+ finally:
free(s) \ No newline at end of file