summaryrefslogtreecommitdiff
path: root/docs/examples/userguide
diff options
context:
space:
mode:
Diffstat (limited to 'docs/examples/userguide')
-rw-r--r--docs/examples/userguide/buffer/matrix.py15
-rw-r--r--docs/examples/userguide/buffer/matrix.pyx31
-rw-r--r--docs/examples/userguide/buffer/matrix_with_buffer.py48
-rw-r--r--docs/examples/userguide/buffer/matrix_with_buffer.pyx93
-rw-r--r--docs/examples/userguide/buffer/view_count.py30
-rw-r--r--docs/examples/userguide/buffer/view_count.pyx59
-rw-r--r--docs/examples/userguide/early_binding_for_speed/rectangle.py22
-rw-r--r--docs/examples/userguide/early_binding_for_speed/rectangle.pyx41
-rw-r--r--docs/examples/userguide/early_binding_for_speed/rectangle_cdef.py26
-rw-r--r--docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx48
-rw-r--r--docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.py23
-rw-r--r--docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx42
-rw-r--r--docs/examples/userguide/extension_types/c_property.pyx20
-rw-r--r--docs/examples/userguide/extension_types/cheesy.py36
-rw-r--r--docs/examples/userguide/extension_types/cheesy.pyx36
-rw-r--r--docs/examples/userguide/extension_types/dataclass.py21
-rw-r--r--docs/examples/userguide/extension_types/dataclass.pyx21
-rw-r--r--docs/examples/userguide/extension_types/dict_animal.py12
-rw-r--r--docs/examples/userguide/extension_types/dict_animal.pyx23
-rw-r--r--docs/examples/userguide/extension_types/extendable_animal.py15
-rw-r--r--docs/examples/userguide/extension_types/extendable_animal.pyx29
-rw-r--r--docs/examples/userguide/extension_types/my_module.pyx22
-rw-r--r--docs/examples/userguide/extension_types/owned_pointer.py17
-rw-r--r--docs/examples/userguide/extension_types/owned_pointer.pyx17
-rw-r--r--docs/examples/userguide/extension_types/penguin.py14
-rw-r--r--docs/examples/userguide/extension_types/penguin.pyx14
-rw-r--r--docs/examples/userguide/extension_types/penguin2.py12
-rw-r--r--docs/examples/userguide/extension_types/penguin2.pyx12
-rw-r--r--docs/examples/userguide/extension_types/pets.py22
-rw-r--r--docs/examples/userguide/extension_types/pets.pyx22
-rw-r--r--docs/examples/userguide/extension_types/python_access.py7
-rw-r--r--docs/examples/userguide/extension_types/python_access.pyx10
-rw-r--r--docs/examples/userguide/extension_types/shrubbery.py12
-rw-r--r--docs/examples/userguide/extension_types/shrubbery.pyx24
-rw-r--r--docs/examples/userguide/extension_types/shrubbery_2.py10
-rw-r--r--docs/examples/userguide/extension_types/shrubbery_2.pyx18
-rw-r--r--docs/examples/userguide/extension_types/widen_shrubbery.py6
-rw-r--r--docs/examples/userguide/extension_types/widen_shrubbery.pyx10
-rw-r--r--docs/examples/userguide/extension_types/wrapper_class.py65
-rw-r--r--docs/examples/userguide/extension_types/wrapper_class.pyx65
-rw-r--r--docs/examples/userguide/external_C_code/delorean.pyx18
-rw-r--r--docs/examples/userguide/external_C_code/marty.c27
-rw-r--r--docs/examples/userguide/external_C_code/platform_adaptation.pyx14
-rw-r--r--docs/examples/userguide/external_C_code/struct_field_adaptation.h13
-rw-r--r--docs/examples/userguide/external_C_code/struct_field_adaptation.pyx31
-rw-r--r--docs/examples/userguide/external_C_code/verbatim_c_code.pyx (renamed from docs/examples/userguide/external_C_code/c_code_docstring.pyx)18
-rw-r--r--docs/examples/userguide/fusedtypes/char_or_float.py17
-rw-r--r--docs/examples/userguide/fusedtypes/char_or_float.pyx34
-rw-r--r--docs/examples/userguide/fusedtypes/conditional_gil.pyx15
-rw-r--r--docs/examples/userguide/fusedtypes/indexing.py25
-rw-r--r--docs/examples/userguide/fusedtypes/indexing.pyx25
-rw-r--r--docs/examples/userguide/fusedtypes/pointer.py13
-rw-r--r--docs/examples/userguide/fusedtypes/pointer.pyx13
-rw-r--r--docs/examples/userguide/fusedtypes/type_checking.py28
-rw-r--r--docs/examples/userguide/fusedtypes/type_checking.pyx28
-rw-r--r--docs/examples/userguide/language_basics/casting_python.pxd2
-rw-r--r--docs/examples/userguide/language_basics/casting_python.py22
-rw-r--r--docs/examples/userguide/language_basics/casting_python.pyx38
-rw-r--r--docs/examples/userguide/language_basics/cdef_block.pyx24
-rw-r--r--docs/examples/userguide/language_basics/compile_time.pyx18
-rw-r--r--docs/examples/userguide/language_basics/enum.pyx (renamed from docs/examples/userguide/language_basics/struct_union_enum.pyx)27
-rw-r--r--docs/examples/userguide/language_basics/function_pointer.pyx8
-rw-r--r--docs/examples/userguide/language_basics/function_pointer_struct.pyx9
-rw-r--r--docs/examples/userguide/language_basics/kwargs_1.pyx12
-rw-r--r--docs/examples/userguide/language_basics/kwargs_2.pyx10
-rw-r--r--docs/examples/userguide/language_basics/open_file.py19
-rw-r--r--docs/examples/userguide/language_basics/open_file.pyx36
-rw-r--r--docs/examples/userguide/language_basics/optional_subclassing.py19
-rw-r--r--docs/examples/userguide/language_basics/optional_subclassing.pyx32
-rw-r--r--docs/examples/userguide/language_basics/override.py17
-rw-r--r--docs/examples/userguide/language_basics/override.pyx30
-rw-r--r--docs/examples/userguide/language_basics/parameter_refcount.py23
-rw-r--r--docs/examples/userguide/language_basics/parameter_refcount.pyx23
-rw-r--r--docs/examples/userguide/language_basics/struct.py7
-rw-r--r--docs/examples/userguide/language_basics/struct.pyx7
-rw-r--r--docs/examples/userguide/language_basics/union.py9
-rw-r--r--docs/examples/userguide/language_basics/union.pyx9
-rw-r--r--docs/examples/userguide/memoryviews/add_one.pyx24
-rw-r--r--docs/examples/userguide/memoryviews/copy.pyx24
-rw-r--r--docs/examples/userguide/memoryviews/custom_dtype.pyx26
-rw-r--r--docs/examples/userguide/memoryviews/memory_layout.pyx22
-rw-r--r--docs/examples/userguide/memoryviews/memory_layout_2.pyx12
-rw-r--r--docs/examples/userguide/memoryviews/memview_to_c.pyx56
-rw-r--r--docs/examples/userguide/memoryviews/not_none.pyx22
-rw-r--r--docs/examples/userguide/memoryviews/np_flag_const.pyx14
-rw-r--r--docs/examples/userguide/memoryviews/quickstart.pyx2
-rw-r--r--docs/examples/userguide/memoryviews/slicing.pyx20
-rw-r--r--docs/examples/userguide/memoryviews/transpose.pyx12
-rw-r--r--docs/examples/userguide/memoryviews/view_string.pyx18
-rw-r--r--docs/examples/userguide/numpy_tutorial/compute_fused_types.pyx88
-rw-r--r--docs/examples/userguide/numpy_tutorial/compute_infer_types.pyx68
-rw-r--r--docs/examples/userguide/numpy_tutorial/compute_memview.pyx68
-rw-r--r--docs/examples/userguide/numpy_tutorial/compute_prange.pyx106
-rw-r--r--docs/examples/userguide/numpy_tutorial/compute_py.py56
-rw-r--r--docs/examples/userguide/numpy_tutorial/compute_typed.pyx100
-rw-r--r--docs/examples/userguide/numpy_ufuncs/ufunc.py8
-rw-r--r--docs/examples/userguide/numpy_ufuncs/ufunc.pyx8
-rw-r--r--docs/examples/userguide/numpy_ufuncs/ufunc_ctuple.py7
-rw-r--r--docs/examples/userguide/numpy_ufuncs/ufunc_ctuple.pyx7
-rw-r--r--docs/examples/userguide/numpy_ufuncs/ufunc_fused.py7
-rw-r--r--docs/examples/userguide/numpy_ufuncs/ufunc_fused.pyx7
-rw-r--r--docs/examples/userguide/parallelism/breaking_loop.py15
-rw-r--r--docs/examples/userguide/parallelism/breaking_loop.pyx28
-rw-r--r--docs/examples/userguide/parallelism/cimport_openmp.py11
-rw-r--r--docs/examples/userguide/parallelism/cimport_openmp.pyx24
-rw-r--r--docs/examples/userguide/parallelism/memoryview_sum.py7
-rw-r--r--docs/examples/userguide/parallelism/memoryview_sum.pyx7
-rw-r--r--docs/examples/userguide/parallelism/parallel.py30
-rw-r--r--docs/examples/userguide/parallelism/parallel.pyx30
-rw-r--r--docs/examples/userguide/parallelism/setup_py.py16
-rw-r--r--docs/examples/userguide/parallelism/setup_pyx.py (renamed from docs/examples/userguide/parallelism/setup.py)33
-rw-r--r--docs/examples/userguide/parallelism/simple_sum.py10
-rw-r--r--docs/examples/userguide/parallelism/simple_sum.pyx20
-rw-r--r--docs/examples/userguide/sharing_declarations/landscaping.py7
-rw-r--r--docs/examples/userguide/sharing_declarations/landscaping.pyx14
-rw-r--r--docs/examples/userguide/sharing_declarations/lunch.py5
-rw-r--r--docs/examples/userguide/sharing_declarations/lunch.pyx9
-rw-r--r--docs/examples/userguide/sharing_declarations/restaurant.py12
-rw-r--r--docs/examples/userguide/sharing_declarations/restaurant.pyx24
-rw-r--r--docs/examples/userguide/sharing_declarations/setup_py.py4
-rw-r--r--docs/examples/userguide/sharing_declarations/setup_pyx.py (renamed from docs/examples/userguide/sharing_declarations/setup.py)8
-rw-r--r--docs/examples/userguide/sharing_declarations/shrubbing.py10
-rw-r--r--docs/examples/userguide/sharing_declarations/shrubbing.pyx17
-rw-r--r--docs/examples/userguide/sharing_declarations/spammery.py10
-rw-r--r--docs/examples/userguide/sharing_declarations/spammery.pyx21
-rw-r--r--docs/examples/userguide/sharing_declarations/volume.pxd2
-rw-r--r--docs/examples/userguide/sharing_declarations/volume.py2
-rw-r--r--docs/examples/userguide/sharing_declarations/volume.pyx4
-rw-r--r--docs/examples/userguide/special_methods/total_ordering.py13
-rw-r--r--docs/examples/userguide/special_methods/total_ordering.pyx13
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/Rectangle.pxd2
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/cython_usage.pyx24
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/function_templates.pyx14
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/iterate.pyx24
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/nested_class.pyx34
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/python_to_cpp.pyx38
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/rect.pyx2
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/rect_ptr.pyx30
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/rect_with_attributes.pyx2
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/setup.py2
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/templates.pyx60
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/vector_demo.pyx30
-rw-r--r--docs/examples/userguide/wrapping_CPlusPlus/wrapper_vector.pyx34
143 files changed, 2300 insertions, 974 deletions
diff --git a/docs/examples/userguide/buffer/matrix.py b/docs/examples/userguide/buffer/matrix.py
new file mode 100644
index 000000000..0e431163d
--- /dev/null
+++ b/docs/examples/userguide/buffer/matrix.py
@@ -0,0 +1,15 @@
+# distutils: language = c++
+
+from cython.cimports.libcpp.vector import vector
+
+@cython.cclass
+class Matrix:
+ ncols: cython.uint
+ v: vector[cython.float]
+
+ def __cinit__(self, ncols: cython.uint):
+ self.ncols = ncols
+
+ def add_row(self):
+ """Adds a row, initially zero-filled."""
+ self.v.resize(self.v.size() + self.ncols)
diff --git a/docs/examples/userguide/buffer/matrix.pyx b/docs/examples/userguide/buffer/matrix.pyx
index abdb2d3c7..f2547f6c3 100644
--- a/docs/examples/userguide/buffer/matrix.pyx
+++ b/docs/examples/userguide/buffer/matrix.pyx
@@ -1,16 +1,15 @@
-# distutils: language = c++
-
-# matrix.pyx
-
-from libcpp.vector cimport vector
-
-cdef class Matrix:
- cdef unsigned ncols
- cdef vector[float] v
-
- def __cinit__(self, unsigned ncols):
- self.ncols = ncols
-
- def add_row(self):
- """Adds a row, initially zero-filled."""
- self.v.resize(self.v.size() + self.ncols)
+# distutils: language = c++
+
+from libcpp.vector cimport vector
+
+
+cdef class Matrix:
+ cdef unsigned ncols
+ cdef vector[float] v
+
+ def __cinit__(self, unsigned ncols):
+ self.ncols = ncols
+
+ def add_row(self):
+ """Adds a row, initially zero-filled."""
+ self.v.resize(self.v.size() + self.ncols)
diff --git a/docs/examples/userguide/buffer/matrix_with_buffer.py b/docs/examples/userguide/buffer/matrix_with_buffer.py
new file mode 100644
index 000000000..34ccc6591
--- /dev/null
+++ b/docs/examples/userguide/buffer/matrix_with_buffer.py
@@ -0,0 +1,48 @@
+# distutils: language = c++
+from cython.cimports.cpython import Py_buffer
+from cython.cimports.libcpp.vector import vector
+
+@cython.cclass
+class Matrix:
+ ncols: cython.Py_ssize_t
+ shape: cython.Py_ssize_t[2]
+ strides: cython.Py_ssize_t[2]
+ v: vector[cython.float]
+
+ def __cinit__(self, ncols: cython.Py_ssize_t):
+ self.ncols = ncols
+
+ def add_row(self):
+ """Adds a row, initially zero-filled."""
+ self.v.resize(self.v.size() + self.ncols)
+
+ def __getbuffer__(self, buffer: cython.pointer(Py_buffer), flags: cython.int):
+ itemsize: cython.Py_ssize_t = cython.sizeof(self.v[0])
+
+ self.shape[0] = self.v.size() // self.ncols
+ self.shape[1] = self.ncols
+
+ # Stride 1 is the distance, in bytes, between two items in a row;
+ # this is the distance between two adjacent items in the vector.
+ # Stride 0 is the distance between the first elements of adjacent rows.
+ self.strides[1] = cython.cast(cython.Py_ssize_t, (
+ cython.cast(cython.p_char, cython.address(self.v[1]))
+ - cython.cast(cython.p_char, cython.address(self.v[0]))
+ )
+ )
+ self.strides[0] = self.ncols * self.strides[1]
+
+ buffer.buf = cython.cast(cython.p_char, cython.address(self.v[0]))
+ buffer.format = 'f' # float
+ buffer.internal = cython.NULL # see References
+ buffer.itemsize = itemsize
+ buffer.len = self.v.size() * itemsize # product(shape) * itemsize
+ buffer.ndim = 2
+ buffer.obj = self
+ buffer.readonly = 0
+ buffer.shape = self.shape
+ buffer.strides = self.strides
+ buffer.suboffsets = cython.NULL # for pointer arrays only
+
+ def __releasebuffer__(self, buffer: cython.pointer(Py_buffer)):
+ pass
diff --git a/docs/examples/userguide/buffer/matrix_with_buffer.pyx b/docs/examples/userguide/buffer/matrix_with_buffer.pyx
index 985991cbe..fc2c160f3 100644
--- a/docs/examples/userguide/buffer/matrix_with_buffer.pyx
+++ b/docs/examples/userguide/buffer/matrix_with_buffer.pyx
@@ -1,45 +1,48 @@
-# distutils: language = c++
-
-from cpython cimport Py_buffer
-from libcpp.vector cimport vector
-
-cdef class Matrix:
- cdef Py_ssize_t ncols
- cdef Py_ssize_t shape[2]
- cdef Py_ssize_t strides[2]
- cdef vector[float] v
-
- def __cinit__(self, Py_ssize_t ncols):
- self.ncols = ncols
-
- def add_row(self):
- """Adds a row, initially zero-filled."""
- self.v.resize(self.v.size() + self.ncols)
-
- def __getbuffer__(self, Py_buffer *buffer, int flags):
- cdef Py_ssize_t itemsize = sizeof(self.v[0])
-
- self.shape[0] = self.v.size() / self.ncols
- self.shape[1] = self.ncols
-
- # Stride 1 is the distance, in bytes, between two items in a row;
- # this is the distance between two adjacent items in the vector.
- # Stride 0 is the distance between the first elements of adjacent rows.
- self.strides[1] = <Py_ssize_t>( <char *>&(self.v[1])
- - <char *>&(self.v[0]))
- self.strides[0] = self.ncols * self.strides[1]
-
- buffer.buf = <char *>&(self.v[0])
- buffer.format = 'f' # float
- buffer.internal = NULL # see References
- buffer.itemsize = itemsize
- buffer.len = self.v.size() * itemsize # product(shape) * itemsize
- buffer.ndim = 2
- buffer.obj = self
- buffer.readonly = 0
- buffer.shape = self.shape
- buffer.strides = self.strides
- buffer.suboffsets = NULL # for pointer arrays only
-
- def __releasebuffer__(self, Py_buffer *buffer):
- pass
+# distutils: language = c++
+from cpython cimport Py_buffer
+from libcpp.vector cimport vector
+
+
+cdef class Matrix:
+ cdef Py_ssize_t ncols
+ cdef Py_ssize_t[2] shape
+ cdef Py_ssize_t[2] strides
+ cdef vector[float] v
+
+ def __cinit__(self, Py_ssize_t ncols):
+ self.ncols = ncols
+
+ def add_row(self):
+ """Adds a row, initially zero-filled."""
+ self.v.resize(self.v.size() + self.ncols)
+
+ def __getbuffer__(self, Py_buffer *buffer, int flags):
+ cdef Py_ssize_t itemsize = sizeof(self.v[0])
+
+ self.shape[0] = self.v.size() // self.ncols
+ self.shape[1] = self.ncols
+
+ # Stride 1 is the distance, in bytes, between two items in a row;
+ # this is the distance between two adjacent items in the vector.
+ # Stride 0 is the distance between the first elements of adjacent rows.
+ self.strides[1] = <Py_ssize_t>( <char *>&(self.v[1])
+ - <char *>&(self.v[0]))
+
+
+
+ self.strides[0] = self.ncols * self.strides[1]
+
+ buffer.buf = <char *>&(self.v[0])
+ buffer.format = 'f' # float
+ buffer.internal = NULL # see References
+ buffer.itemsize = itemsize
+ buffer.len = self.v.size() * itemsize # product(shape) * itemsize
+ buffer.ndim = 2
+ buffer.obj = self
+ buffer.readonly = 0
+ buffer.shape = self.shape
+ buffer.strides = self.strides
+ buffer.suboffsets = NULL # for pointer arrays only
+
+ def __releasebuffer__(self, Py_buffer *buffer):
+ pass
diff --git a/docs/examples/userguide/buffer/view_count.py b/docs/examples/userguide/buffer/view_count.py
new file mode 100644
index 000000000..6a0554abc
--- /dev/null
+++ b/docs/examples/userguide/buffer/view_count.py
@@ -0,0 +1,30 @@
+# distutils: language = c++
+
+from cython.cimports.cpython import Py_buffer
+from cython.cimports.libcpp.vector import vector
+
+@cython.cclass
+class Matrix:
+
+ view_count: cython.int
+
+ ncols: cython.Py_ssize_t
+ v: vector[cython.float]
+ # ...
+
+ def __cinit__(self, ncols: cython.Py_ssize_t):
+ self.ncols = ncols
+ self.view_count = 0
+
+ def add_row(self):
+ if self.view_count > 0:
+ raise ValueError("can't add row while being viewed")
+ self.v.resize(self.v.size() + self.ncols)
+
+ def __getbuffer__(self, buffer: cython.pointer(Py_buffer), flags: cython.int):
+ # ... as before
+
+ self.view_count += 1
+
+ def __releasebuffer__(self, buffer: cython.pointer(Py_buffer)):
+ self.view_count -= 1
diff --git a/docs/examples/userguide/buffer/view_count.pyx b/docs/examples/userguide/buffer/view_count.pyx
index ee8d5085d..8c4b1d524 100644
--- a/docs/examples/userguide/buffer/view_count.pyx
+++ b/docs/examples/userguide/buffer/view_count.pyx
@@ -1,29 +1,30 @@
-# distutils: language = c++
-
-from cpython cimport Py_buffer
-from libcpp.vector cimport vector
-
-cdef class Matrix:
-
- cdef int view_count
-
- cdef Py_ssize_t ncols
- cdef vector[float] v
- # ...
-
- def __cinit__(self, Py_ssize_t ncols):
- self.ncols = ncols
- self.view_count = 0
-
- def add_row(self):
- if self.view_count > 0:
- raise ValueError("can't add row while being viewed")
- self.v.resize(self.v.size() + self.ncols)
-
- def __getbuffer__(self, Py_buffer *buffer, int flags):
- # ... as before
-
- self.view_count += 1
-
- def __releasebuffer__(self, Py_buffer *buffer):
- self.view_count -= 1 \ No newline at end of file
+# distutils: language = c++
+
+from cpython cimport Py_buffer
+from libcpp.vector cimport vector
+
+
+cdef class Matrix:
+
+ cdef int view_count
+
+ cdef Py_ssize_t ncols
+ cdef vector[float] v
+ # ...
+
+ def __cinit__(self, Py_ssize_t ncols):
+ self.ncols = ncols
+ self.view_count = 0
+
+ def add_row(self):
+ if self.view_count > 0:
+ raise ValueError("can't add row while being viewed")
+ self.v.resize(self.v.size() + self.ncols)
+
+ def __getbuffer__(self, Py_buffer *buffer, int flags):
+ # ... as before
+
+ self.view_count += 1
+
+ def __releasebuffer__(self, Py_buffer *buffer):
+ self.view_count -= 1
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle.py b/docs/examples/userguide/early_binding_for_speed/rectangle.py
new file mode 100644
index 000000000..cd534d051
--- /dev/null
+++ b/docs/examples/userguide/early_binding_for_speed/rectangle.py
@@ -0,0 +1,22 @@
+@cython.cclass
+class Rectangle:
+ x0: cython.int
+ y0: cython.int
+ x1: cython.int
+ y1: cython.int
+
+ def __init__(self, x0: cython.int, y0: cython.int, x1: cython.int, y1: cython.int):
+ self.x0 = x0
+ self.y0 = y0
+ self.x1 = x1
+ self.y1 = y1
+
+ def area(self):
+ area = (self.x1 - self.x0) * (self.y1 - self.y0)
+ if area < 0:
+ area = -area
+ return area
+
+def rectArea(x0, y0, x1, y1):
+ rect = Rectangle(x0, y0, x1, y1)
+ return rect.area()
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle.pyx b/docs/examples/userguide/early_binding_for_speed/rectangle.pyx
index ffc5593b0..b58f6534b 100644
--- a/docs/examples/userguide/early_binding_for_speed/rectangle.pyx
+++ b/docs/examples/userguide/early_binding_for_speed/rectangle.pyx
@@ -1,19 +1,22 @@
-cdef class Rectangle:
- cdef int x0, y0
- cdef int x1, y1
-
- def __init__(self, int x0, int y0, int x1, int y1):
- self.x0 = x0
- self.y0 = y0
- self.x1 = x1
- self.y1 = y1
-
- def area(self):
- area = (self.x1 - self.x0) * (self.y1 - self.y0)
- if area < 0:
- area = -area
- return area
-
-def rectArea(x0, y0, x1, y1):
- rect = Rectangle(x0, y0, x1, y1)
- return rect.area()
+
+cdef class Rectangle:
+ cdef int x0, y0
+ cdef int x1, y1
+
+
+
+ def __init__(self, int x0, int y0, int x1, int y1):
+ self.x0 = x0
+ self.y0 = y0
+ self.x1 = x1
+ self.y1 = y1
+
+ def area(self):
+ area = (self.x1 - self.x0) * (self.y1 - self.y0)
+ if area < 0:
+ area = -area
+ return area
+
+def rectArea(x0, y0, x1, y1):
+ rect = Rectangle(x0, y0, x1, y1)
+ return rect.area()
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.py b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.py
new file mode 100644
index 000000000..ee2a14fb8
--- /dev/null
+++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.py
@@ -0,0 +1,26 @@
+@cython.cclass
+class Rectangle:
+ x0: cython.int
+ y0: cython.int
+ x1: cython.int
+ y1: cython.int
+
+ def __init__(self, x0: cython.int, y0: cython.int, x1: cython.int, y1: cython.int):
+ self.x0 = x0
+ self.y0 = y0
+ self.x1 = x1
+ self.y1 = y1
+
+ @cython.cfunc
+ def _area(self) -> cython.int:
+ area: cython.int = (self.x1 - self.x0) * (self.y1 - self.y0)
+ if area < 0:
+ area = -area
+ return area
+
+ def area(self):
+ return self._area()
+
+def rectArea(x0, y0, x1, y1):
+ rect: Rectangle = Rectangle(x0, y0, x1, y1)
+ return rect._area()
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx
index 5502b4568..3b64d766b 100644
--- a/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx
+++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx
@@ -1,22 +1,26 @@
-cdef class Rectangle:
- cdef int x0, y0
- cdef int x1, y1
-
- def __init__(self, int x0, int y0, int x1, int y1):
- self.x0 = x0
- self.y0 = y0
- self.x1 = x1
- self.y1 = y1
-
- cdef int _area(self):
- area = (self.x1 - self.x0) * (self.y1 - self.y0)
- if area < 0:
- area = -area
- return area
-
- def area(self):
- return self._area()
-
-def rectArea(x0, y0, x1, y1):
- rect = Rectangle(x0, y0, x1, y1)
- return rect.area()
+
+cdef class Rectangle:
+ cdef int x0, y0
+ cdef int x1, y1
+
+
+
+ def __init__(self, int x0, int y0, int x1, int y1):
+ self.x0 = x0
+ self.y0 = y0
+ self.x1 = x1
+ self.y1 = y1
+
+
+ cdef int _area(self):
+ cdef int area = (self.x1 - self.x0) * (self.y1 - self.y0)
+ if area < 0:
+ area = -area
+ return area
+
+ def area(self):
+ return self._area()
+
+def rectArea(x0, y0, x1, y1):
+ cdef Rectangle rect = Rectangle(x0, y0, x1, y1)
+ return rect._area()
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.py b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.py
new file mode 100644
index 000000000..670f340a4
--- /dev/null
+++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.py
@@ -0,0 +1,23 @@
+@cython.cclass
+class Rectangle:
+ x0: cython.int
+ y0: cython.int
+ x1: cython.int
+ y1: cython.int
+
+ def __init__(self, x0: cython.int, y0: cython.int, x1: cython.int, y1: cython.int):
+ self.x0 = x0
+ self.y0 = y0
+ self.x1 = x1
+ self.y1 = y1
+
+ @cython.ccall
+ def area(self)-> cython.int:
+ area: cython.int = (self.x1 - self.x0) * (self.y1 - self.y0)
+ if area < 0:
+ area = -area
+ return area
+
+def rectArea(x0, y0, x1, y1):
+ rect: Rectangle = Rectangle(x0, y0, x1, y1)
+ return rect.area()
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx
index 01df3759f..53f2a8ad2 100644
--- a/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx
+++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx
@@ -1,19 +1,23 @@
-cdef class Rectangle:
- cdef int x0, y0
- cdef int x1, y1
-
- def __init__(self, int x0, int y0, int x1, int y1):
- self.x0 = x0
- self.y0 = y0
- self.x1 = x1
- self.y1 = y1
-
- cpdef int area(self):
- area = (self.x1 - self.x0) * (self.y1 - self.y0)
- if area < 0:
- area = -area
- return area
-
-def rectArea(x0, y0, x1, y1):
- rect = Rectangle(x0, y0, x1, y1)
- return rect.area()
+
+cdef class Rectangle:
+ cdef int x0, y0
+ cdef int x1, y1
+
+
+
+ def __init__(self, int x0, int y0, int x1, int y1):
+ self.x0 = x0
+ self.y0 = y0
+ self.x1 = x1
+ self.y1 = y1
+
+
+ cpdef int area(self):
+ cdef int area = (self.x1 - self.x0) * (self.y1 - self.y0)
+ if area < 0:
+ area = -area
+ return area
+
+def rectArea(x0, y0, x1, y1):
+ cdef Rectangle rect = Rectangle(x0, y0, x1, y1)
+ return rect.area()
diff --git a/docs/examples/userguide/extension_types/c_property.pyx b/docs/examples/userguide/extension_types/c_property.pyx
new file mode 100644
index 000000000..b759ceec1
--- /dev/null
+++ b/docs/examples/userguide/extension_types/c_property.pyx
@@ -0,0 +1,20 @@
+cdef extern from "complexobject.h":
+
+ struct Py_complex:
+ double real
+ double imag
+
+ ctypedef class __builtin__.complex [object PyComplexObject]:
+ cdef Py_complex cval
+
+ @property
+ cdef inline double real(self):
+ return self.cval.real
+
+ @property
+ cdef inline double imag(self):
+ return self.cval.imag
+
+
+def cprint(complex c):
+ print(f"{c.real :.4f}{c.imag :+.4f}j") # uses C calls to the above property methods.
diff --git a/docs/examples/userguide/extension_types/cheesy.py b/docs/examples/userguide/extension_types/cheesy.py
new file mode 100644
index 000000000..0995c3993
--- /dev/null
+++ b/docs/examples/userguide/extension_types/cheesy.py
@@ -0,0 +1,36 @@
+import cython
+
+@cython.cclass
+class CheeseShop:
+
+ cheeses: object
+
+ def __cinit__(self):
+ self.cheeses = []
+
+ @property
+ def cheese(self):
+ return "We don't have: %s" % self.cheeses
+
+ @cheese.setter
+ def cheese(self, value):
+ self.cheeses.append(value)
+
+ @cheese.deleter
+ def cheese(self):
+ del self.cheeses[:]
+
+# Test input
+from cheesy import CheeseShop
+
+shop = CheeseShop()
+print(shop.cheese)
+
+shop.cheese = "camembert"
+print(shop.cheese)
+
+shop.cheese = "cheddar"
+print(shop.cheese)
+
+del shop.cheese
+print(shop.cheese)
diff --git a/docs/examples/userguide/extension_types/cheesy.pyx b/docs/examples/userguide/extension_types/cheesy.pyx
new file mode 100644
index 000000000..2859d848f
--- /dev/null
+++ b/docs/examples/userguide/extension_types/cheesy.pyx
@@ -0,0 +1,36 @@
+
+
+
+cdef class CheeseShop:
+
+ cdef object cheeses
+
+ def __cinit__(self):
+ self.cheeses = []
+
+ @property
+ def cheese(self):
+ return "We don't have: %s" % self.cheeses
+
+ @cheese.setter
+ def cheese(self, value):
+ self.cheeses.append(value)
+
+ @cheese.deleter
+ def cheese(self):
+ del self.cheeses[:]
+
+# Test input
+from cheesy import CheeseShop
+
+shop = CheeseShop()
+print(shop.cheese)
+
+shop.cheese = "camembert"
+print(shop.cheese)
+
+shop.cheese = "cheddar"
+print(shop.cheese)
+
+del shop.cheese
+print(shop.cheese)
diff --git a/docs/examples/userguide/extension_types/dataclass.py b/docs/examples/userguide/extension_types/dataclass.py
new file mode 100644
index 000000000..d8ed68666
--- /dev/null
+++ b/docs/examples/userguide/extension_types/dataclass.py
@@ -0,0 +1,21 @@
+import cython
+try:
+ import typing
+ import dataclasses
+except ImportError:
+ pass # The modules don't actually have to exists for Cython to use them as annotations
+
+@cython.dataclasses.dataclass
+@cython.cclass
+class MyDataclass:
+ # fields can be declared using annotations
+ a: cython.int = 0
+ b: double = cython.dataclasses.field(default_factory = lambda: 10, repr=False)
+
+
+ c: str = 'hello'
+
+
+ # typing.InitVar and typing.ClassVar also work
+ d: dataclasses.InitVar[double] = 5
+ e: typing.ClassVar[list] = []
diff --git a/docs/examples/userguide/extension_types/dataclass.pyx b/docs/examples/userguide/extension_types/dataclass.pyx
new file mode 100644
index 000000000..b03d5f7b1
--- /dev/null
+++ b/docs/examples/userguide/extension_types/dataclass.pyx
@@ -0,0 +1,21 @@
+cimport cython
+try:
+ import typing
+ import dataclasses
+except ImportError:
+ pass # The modules don't actually have to exists for Cython to use them as annotations
+
+
+@cython.dataclasses.dataclass
+cdef class MyDataclass:
+ # fields can be declared using annotations
+ a: cython.int = 0
+ b: double = cython.dataclasses.field(default_factory = lambda: 10, repr=False)
+
+ # fields can also be declared using `cdef`:
+ cdef str c
+ c = "hello" # assignment of default value on a separate line
+
+ # typing.InitVar and typing.ClassVar also work
+ d: dataclasses.InitVar[cython.double] = 5
+ e: typing.ClassVar[list] = []
diff --git a/docs/examples/userguide/extension_types/dict_animal.py b/docs/examples/userguide/extension_types/dict_animal.py
new file mode 100644
index 000000000..a36dd3f89
--- /dev/null
+++ b/docs/examples/userguide/extension_types/dict_animal.py
@@ -0,0 +1,12 @@
+@cython.cclass
+class Animal:
+
+ number_of_legs: cython.int
+ __dict__: dict
+
+ def __cinit__(self, number_of_legs: cython.int):
+ self.number_of_legs = number_of_legs
+
+
+dog = Animal(4)
+dog.has_tail = True
diff --git a/docs/examples/userguide/extension_types/dict_animal.pyx b/docs/examples/userguide/extension_types/dict_animal.pyx
index ab66900fe..575b835e9 100644
--- a/docs/examples/userguide/extension_types/dict_animal.pyx
+++ b/docs/examples/userguide/extension_types/dict_animal.pyx
@@ -1,11 +1,12 @@
-cdef class Animal:
-
- cdef int number_of_legs
- cdef dict __dict__
-
- def __cinit__(self, int number_of_legs):
- self.number_of_legs = number_of_legs
-
-
-dog = Animal(4)
-dog.has_tail = True
+
+cdef class Animal:
+
+ cdef int number_of_legs
+ cdef dict __dict__
+
+ def __init__(self, int number_of_legs):
+ self.number_of_legs = number_of_legs
+
+
+dog = Animal(4)
+dog.has_tail = True
diff --git a/docs/examples/userguide/extension_types/extendable_animal.py b/docs/examples/userguide/extension_types/extendable_animal.py
new file mode 100644
index 000000000..2eef69460
--- /dev/null
+++ b/docs/examples/userguide/extension_types/extendable_animal.py
@@ -0,0 +1,15 @@
+@cython.cclass
+class Animal:
+
+ number_of_legs: cython.int
+
+ def __cinit__(self, number_of_legs: cython.int):
+ self.number_of_legs = number_of_legs
+
+
+class ExtendableAnimal(Animal): # Note that we use class, not cdef class
+ pass
+
+
+dog = ExtendableAnimal(4)
+dog.has_tail = True
diff --git a/docs/examples/userguide/extension_types/extendable_animal.pyx b/docs/examples/userguide/extension_types/extendable_animal.pyx
index fe53218b5..2ec165421 100644
--- a/docs/examples/userguide/extension_types/extendable_animal.pyx
+++ b/docs/examples/userguide/extension_types/extendable_animal.pyx
@@ -1,14 +1,15 @@
-cdef class Animal:
-
- cdef int number_of_legs
-
- def __cinit__(self, int number_of_legs):
- self.number_of_legs = number_of_legs
-
-
-class ExtendableAnimal(Animal): # Note that we use class, not cdef class
- pass
-
-
-dog = ExtendableAnimal(4)
-dog.has_tail = True \ No newline at end of file
+
+cdef class Animal:
+
+ cdef int number_of_legs
+
+ def __init__(self, int number_of_legs):
+ self.number_of_legs = number_of_legs
+
+
+class ExtendableAnimal(Animal): # Note that we use class, not cdef class
+ pass
+
+
+dog = ExtendableAnimal(4)
+dog.has_tail = True
diff --git a/docs/examples/userguide/extension_types/my_module.pyx b/docs/examples/userguide/extension_types/my_module.pyx
index 6ceb057ca..fb0701c12 100644
--- a/docs/examples/userguide/extension_types/my_module.pyx
+++ b/docs/examples/userguide/extension_types/my_module.pyx
@@ -1,11 +1,11 @@
-from __future__ import print_function
-
-cdef class Shrubbery:
-
- def __init__(self, w, h):
- self.width = w
- self.height = h
-
- def describe(self):
- print("This shrubbery is", self.width,
- "by", self.height, "cubits.")
+from __future__ import print_function
+
+cdef class Shrubbery:
+
+ def __init__(self, w, h):
+ self.width = w
+ self.height = h
+
+ def describe(self):
+ print("This shrubbery is", self.width,
+ "by", self.height, "cubits.")
diff --git a/docs/examples/userguide/extension_types/owned_pointer.py b/docs/examples/userguide/extension_types/owned_pointer.py
new file mode 100644
index 000000000..1c235a883
--- /dev/null
+++ b/docs/examples/userguide/extension_types/owned_pointer.py
@@ -0,0 +1,17 @@
+import cython
+from cython.cimports.libc.stdlib import free
+
+@cython.cclass
+class OwnedPointer:
+ ptr: cython.pointer(cython.void)
+
+ def __dealloc__(self):
+ if self.ptr is not cython.NULL:
+ free(self.ptr)
+
+ @staticmethod
+ @cython.cfunc
+ def create(ptr: cython.pointer(cython.void)):
+ p = OwnedPointer()
+ p.ptr = ptr
+ return p
diff --git a/docs/examples/userguide/extension_types/owned_pointer.pyx b/docs/examples/userguide/extension_types/owned_pointer.pyx
new file mode 100644
index 000000000..98b61d91c
--- /dev/null
+++ b/docs/examples/userguide/extension_types/owned_pointer.pyx
@@ -0,0 +1,17 @@
+
+from libc.stdlib cimport free
+
+
+cdef class OwnedPointer:
+ cdef void* ptr
+
+ def __dealloc__(self):
+ if self.ptr is not NULL:
+ free(self.ptr)
+
+
+ @staticmethod
+ cdef create(void* ptr):
+ p = OwnedPointer()
+ p.ptr = ptr
+ return p
diff --git a/docs/examples/userguide/extension_types/penguin.py b/docs/examples/userguide/extension_types/penguin.py
new file mode 100644
index 000000000..6db8eba16
--- /dev/null
+++ b/docs/examples/userguide/extension_types/penguin.py
@@ -0,0 +1,14 @@
+import cython
+
+@cython.cclass
+class Penguin:
+ food: object
+
+ def __cinit__(self, food):
+ self.food = food
+
+ def __init__(self, food):
+ print("eating!")
+
+normal_penguin = Penguin('fish')
+fast_penguin = Penguin.__new__(Penguin, 'wheat') # note: not calling __init__() !
diff --git a/docs/examples/userguide/extension_types/penguin.pyx b/docs/examples/userguide/extension_types/penguin.pyx
new file mode 100644
index 000000000..b890c9ffd
--- /dev/null
+++ b/docs/examples/userguide/extension_types/penguin.pyx
@@ -0,0 +1,14 @@
+
+
+
+cdef class Penguin:
+ cdef object food
+
+ def __cinit__(self, food):
+ self.food = food
+
+ def __init__(self, food):
+ print("eating!")
+
+normal_penguin = Penguin('fish')
+fast_penguin = Penguin.__new__(Penguin, 'wheat') # note: not calling __init__() !
diff --git a/docs/examples/userguide/extension_types/penguin2.py b/docs/examples/userguide/extension_types/penguin2.py
new file mode 100644
index 000000000..063563d16
--- /dev/null
+++ b/docs/examples/userguide/extension_types/penguin2.py
@@ -0,0 +1,12 @@
+import cython
+
+@cython.freelist(8)
+@cython.cclass
+class Penguin:
+ food: object
+ def __cinit__(self, food):
+ self.food = food
+
+penguin = Penguin('fish 1')
+penguin = None
+penguin = Penguin('fish 2') # does not need to allocate memory!
diff --git a/docs/examples/userguide/extension_types/penguin2.pyx b/docs/examples/userguide/extension_types/penguin2.pyx
new file mode 100644
index 000000000..726aeef8e
--- /dev/null
+++ b/docs/examples/userguide/extension_types/penguin2.pyx
@@ -0,0 +1,12 @@
+cimport cython
+
+
+@cython.freelist(8)
+cdef class Penguin:
+ cdef object food
+ def __cinit__(self, food):
+ self.food = food
+
+penguin = Penguin('fish 1')
+penguin = None
+penguin = Penguin('fish 2') # does not need to allocate memory!
diff --git a/docs/examples/userguide/extension_types/pets.py b/docs/examples/userguide/extension_types/pets.py
new file mode 100644
index 000000000..fc6497cb0
--- /dev/null
+++ b/docs/examples/userguide/extension_types/pets.py
@@ -0,0 +1,22 @@
+import cython
+
+@cython.cclass
+class Parrot:
+
+ @cython.cfunc
+ def describe(self) -> cython.void:
+ print("This parrot is resting.")
+
+@cython.cclass
+class Norwegian(Parrot):
+
+ @cython.cfunc
+ def describe(self) -> cython.void:
+ Parrot.describe(self)
+ print("Lovely plumage!")
+
+cython.declare(p1=Parrot, p2=Parrot)
+p1 = Parrot()
+p2 = Norwegian()
+print("p2:")
+p2.describe()
diff --git a/docs/examples/userguide/extension_types/pets.pyx b/docs/examples/userguide/extension_types/pets.pyx
new file mode 100644
index 000000000..bb06e059d
--- /dev/null
+++ b/docs/examples/userguide/extension_types/pets.pyx
@@ -0,0 +1,22 @@
+
+
+cdef class Parrot:
+
+
+
+ cdef void describe(self):
+ print("This parrot is resting.")
+
+
+cdef class Norwegian(Parrot):
+
+
+ cdef void describe(self):
+ Parrot.describe(self)
+ print("Lovely plumage!")
+
+cdef Parrot p1, p2
+p1 = Parrot()
+p2 = Norwegian()
+print("p2:")
+p2.describe()
diff --git a/docs/examples/userguide/extension_types/python_access.py b/docs/examples/userguide/extension_types/python_access.py
new file mode 100644
index 000000000..27478f50c
--- /dev/null
+++ b/docs/examples/userguide/extension_types/python_access.py
@@ -0,0 +1,7 @@
+import cython
+
+@cython.cclass
+class Shrubbery:
+ width = cython.declare(cython.int, visibility='public')
+ height = cython.declare(cython.int, visibility='public')
+ depth = cython.declare(cython.float, visibility='readonly')
diff --git a/docs/examples/userguide/extension_types/python_access.pyx b/docs/examples/userguide/extension_types/python_access.pyx
index 13e19091e..db11de63c 100644
--- a/docs/examples/userguide/extension_types/python_access.pyx
+++ b/docs/examples/userguide/extension_types/python_access.pyx
@@ -1,3 +1,7 @@
-cdef class Shrubbery:
- cdef public int width, height
- cdef readonly float depth
+
+
+
+cdef class Shrubbery:
+ cdef public int width, height
+
+ cdef readonly float depth
diff --git a/docs/examples/userguide/extension_types/shrubbery.py b/docs/examples/userguide/extension_types/shrubbery.py
new file mode 100644
index 000000000..0e624a1d2
--- /dev/null
+++ b/docs/examples/userguide/extension_types/shrubbery.py
@@ -0,0 +1,12 @@
+@cython.cclass
+class Shrubbery:
+ width: cython.int
+ height: cython.int
+
+ def __init__(self, w, h):
+ self.width = w
+ self.height = h
+
+ def describe(self):
+ print("This shrubbery is", self.width,
+ "by", self.height, "cubits.")
diff --git a/docs/examples/userguide/extension_types/shrubbery.pyx b/docs/examples/userguide/extension_types/shrubbery.pyx
index 9d2a5481a..8c4e58776 100644
--- a/docs/examples/userguide/extension_types/shrubbery.pyx
+++ b/docs/examples/userguide/extension_types/shrubbery.pyx
@@ -1,12 +1,12 @@
-from __future__ import print_function
-
-cdef class Shrubbery:
- cdef int width, height
-
- def __init__(self, w, h):
- self.width = w
- self.height = h
-
- def describe(self):
- print("This shrubbery is", self.width,
- "by", self.height, "cubits.")
+from __future__ import print_function
+cdef class Shrubbery:
+ cdef int width
+ cdef int height
+
+ def __init__(self, w, h):
+ self.width = w
+ self.height = h
+
+ def describe(self):
+ print("This shrubbery is", self.width,
+ "by", self.height, "cubits.")
diff --git a/docs/examples/userguide/extension_types/shrubbery_2.py b/docs/examples/userguide/extension_types/shrubbery_2.py
new file mode 100644
index 000000000..d6b722500
--- /dev/null
+++ b/docs/examples/userguide/extension_types/shrubbery_2.py
@@ -0,0 +1,10 @@
+import cython
+from cython.cimports.my_module import Shrubbery
+
+@cython.cfunc
+def another_shrubbery(sh1: Shrubbery) -> Shrubbery:
+ sh2: Shrubbery
+ sh2 = Shrubbery()
+ sh2.width = sh1.width
+ sh2.height = sh1.height
+ return sh2
diff --git a/docs/examples/userguide/extension_types/shrubbery_2.pyx b/docs/examples/userguide/extension_types/shrubbery_2.pyx
index e0d8c45b5..4a7782735 100644
--- a/docs/examples/userguide/extension_types/shrubbery_2.pyx
+++ b/docs/examples/userguide/extension_types/shrubbery_2.pyx
@@ -1,8 +1,10 @@
-from my_module cimport Shrubbery
-
-cdef Shrubbery another_shrubbery(Shrubbery sh1):
- cdef Shrubbery sh2
- sh2 = Shrubbery()
- sh2.width = sh1.width
- sh2.height = sh1.height
- return sh2
+
+from my_module cimport Shrubbery
+
+
+cdef Shrubbery another_shrubbery(Shrubbery sh1):
+ cdef Shrubbery sh2
+ sh2 = Shrubbery()
+ sh2.width = sh1.width
+ sh2.height = sh1.height
+ return sh2
diff --git a/docs/examples/userguide/extension_types/widen_shrubbery.py b/docs/examples/userguide/extension_types/widen_shrubbery.py
new file mode 100644
index 000000000..f69f4dc96
--- /dev/null
+++ b/docs/examples/userguide/extension_types/widen_shrubbery.py
@@ -0,0 +1,6 @@
+import cython
+from cython.cimports.my_module import Shrubbery
+
+@cython.cfunc
+def widen_shrubbery(sh: Shrubbery, extra_width):
+ sh.width = sh.width + extra_width
diff --git a/docs/examples/userguide/extension_types/widen_shrubbery.pyx b/docs/examples/userguide/extension_types/widen_shrubbery.pyx
index aff3bd116..c6f58f00c 100644
--- a/docs/examples/userguide/extension_types/widen_shrubbery.pyx
+++ b/docs/examples/userguide/extension_types/widen_shrubbery.pyx
@@ -1,4 +1,6 @@
-from my_module cimport Shrubbery
-
-cdef widen_shrubbery(Shrubbery sh, extra_width):
- sh.width = sh.width + extra_width
+
+from my_module cimport Shrubbery
+
+
+cdef widen_shrubbery(Shrubbery sh, extra_width):
+ sh.width = sh.width + extra_width
diff --git a/docs/examples/userguide/extension_types/wrapper_class.py b/docs/examples/userguide/extension_types/wrapper_class.py
new file mode 100644
index 000000000..b625ffebd
--- /dev/null
+++ b/docs/examples/userguide/extension_types/wrapper_class.py
@@ -0,0 +1,65 @@
+import cython
+from cython.cimports.libc.stdlib import malloc, free
+
+# Example C struct
+my_c_struct = cython.struct(
+ a = cython.int,
+ b = cython.int,
+)
+
+@cython.cclass
+class WrapperClass:
+ """A wrapper class for a C/C++ data structure"""
+ _ptr: cython.pointer(my_c_struct)
+ ptr_owner: cython.bint
+
+ def __cinit__(self):
+ self.ptr_owner = False
+
+ def __dealloc__(self):
+ # De-allocate if not null and flag is set
+ if self._ptr is not cython.NULL and self.ptr_owner is True:
+ free(self._ptr)
+ self._ptr = cython.NULL
+
+ def __init__(self):
+ # Prevent accidental instantiation from normal Python code
+ # since we cannot pass a struct pointer into a Python constructor.
+ raise TypeError("This class cannot be instantiated directly.")
+
+ # Extension class properties
+ @property
+ def a(self):
+ return self._ptr.a if self._ptr is not cython.NULL else None
+
+ @property
+ def b(self):
+ return self._ptr.b if self._ptr is not cython.NULL else None
+
+ @staticmethod
+ @cython.cfunc
+ def from_ptr(_ptr: cython.pointer(my_c_struct), owner: cython.bint=False) -> WrapperClass:
+ """Factory function to create WrapperClass objects from
+ given my_c_struct pointer.
+
+ Setting ``owner`` flag to ``True`` causes
+ the extension type to ``free`` the structure pointed to by ``_ptr``
+ when the wrapper object is deallocated."""
+ # Fast call to __new__() that bypasses the __init__() constructor.
+ wrapper: WrapperClass = WrapperClass.__new__(WrapperClass)
+ wrapper._ptr = _ptr
+ wrapper.ptr_owner = owner
+ return wrapper
+
+ @staticmethod
+ @cython.cfunc
+ def new_struct() -> WrapperClass:
+ """Factory function to create WrapperClass objects with
+ newly allocated my_c_struct"""
+ _ptr: cython.pointer(my_c_struct) = cython.cast(
+ cython.pointer(my_c_struct), malloc(cython.sizeof(my_c_struct)))
+ if _ptr is cython.NULL:
+ raise MemoryError
+ _ptr.a = 0
+ _ptr.b = 0
+ return WrapperClass.from_ptr(_ptr, owner=True)
diff --git a/docs/examples/userguide/extension_types/wrapper_class.pyx b/docs/examples/userguide/extension_types/wrapper_class.pyx
new file mode 100644
index 000000000..e2a0c3ff2
--- /dev/null
+++ b/docs/examples/userguide/extension_types/wrapper_class.pyx
@@ -0,0 +1,65 @@
+
+from libc.stdlib cimport malloc, free
+
+# Example C struct
+ctypedef struct my_c_struct:
+ int a
+ int b
+
+
+
+cdef class WrapperClass:
+ """A wrapper class for a C/C++ data structure"""
+ cdef my_c_struct *_ptr
+ cdef bint ptr_owner
+
+ def __cinit__(self):
+ self.ptr_owner = False
+
+ def __dealloc__(self):
+ # De-allocate if not null and flag is set
+ if self._ptr is not NULL and self.ptr_owner is True:
+ free(self._ptr)
+ self._ptr = NULL
+
+ def __init__(self):
+ # Prevent accidental instantiation from normal Python code
+ # since we cannot pass a struct pointer into a Python constructor.
+ raise TypeError("This class cannot be instantiated directly.")
+
+ # Extension class properties
+ @property
+ def a(self):
+ return self._ptr.a if self._ptr is not NULL else None
+
+ @property
+ def b(self):
+ return self._ptr.b if self._ptr is not NULL else None
+
+
+ @staticmethod
+ cdef WrapperClass from_ptr(my_c_struct *_ptr, bint owner=False):
+ """Factory function to create WrapperClass objects from
+ given my_c_struct pointer.
+
+ Setting ``owner`` flag to ``True`` causes
+ the extension type to ``free`` the structure pointed to by ``_ptr``
+ when the wrapper object is deallocated."""
+ # Fast call to __new__() that bypasses the __init__() constructor.
+ cdef WrapperClass wrapper = WrapperClass.__new__(WrapperClass)
+ wrapper._ptr = _ptr
+ wrapper.ptr_owner = owner
+ return wrapper
+
+
+ @staticmethod
+ cdef WrapperClass new_struct():
+ """Factory function to create WrapperClass objects with
+ newly allocated my_c_struct"""
+ cdef my_c_struct *_ptr = <my_c_struct *>malloc(sizeof(my_c_struct))
+
+ if _ptr is NULL:
+ raise MemoryError
+ _ptr.a = 0
+ _ptr.b = 0
+ return WrapperClass.from_ptr(_ptr, owner=True)
diff --git a/docs/examples/userguide/external_C_code/delorean.pyx b/docs/examples/userguide/external_C_code/delorean.pyx
index 52c713616..9c6af9f87 100644
--- a/docs/examples/userguide/external_C_code/delorean.pyx
+++ b/docs/examples/userguide/external_C_code/delorean.pyx
@@ -1,9 +1,9 @@
-# delorean.pyx
-
-cdef public struct Vehicle:
- int speed
- float power
-
-cdef api void activate(Vehicle *v):
- if v.speed >= 88 and v.power >= 1.21:
- print("Time travel achieved") \ No newline at end of file
+# delorean.pyx
+
+cdef public struct Vehicle:
+ int speed
+ float power
+
+cdef api void activate(Vehicle *v) except *:
+ if v.speed >= 88 and v.power >= 1.21:
+ print("Time travel achieved")
diff --git a/docs/examples/userguide/external_C_code/marty.c b/docs/examples/userguide/external_C_code/marty.c
index 8096ab19a..d7f5117f7 100644
--- a/docs/examples/userguide/external_C_code/marty.c
+++ b/docs/examples/userguide/external_C_code/marty.c
@@ -1,13 +1,14 @@
-# marty.c
-#include "delorean_api.h"
-
-Vehicle car;
-
-int main(int argc, char *argv[]) {
- Py_Initialize();
- import_delorean();
- car.speed = atoi(argv[1]);
- car.power = atof(argv[2]);
- activate(&car);
- Py_Finalize();
-}
+# marty.c
+#include "delorean_api.h"
+
+Vehicle car;
+
+int main(int argc, char *argv[]) {
+ Py_Initialize();
+ import_delorean();
+ car.speed = atoi(argv[1]);
+ car.power = atof(argv[2]);
+ activate(&car);
+ /* Error handling left out - call PyErr_Occurred() to test for Python exceptions. */
+ Py_Finalize();
+}
diff --git a/docs/examples/userguide/external_C_code/platform_adaptation.pyx b/docs/examples/userguide/external_C_code/platform_adaptation.pyx
new file mode 100644
index 000000000..0beece8f4
--- /dev/null
+++ b/docs/examples/userguide/external_C_code/platform_adaptation.pyx
@@ -0,0 +1,14 @@
+cdef extern from *:
+ """
+ #if defined(_WIN32) || defined(MS_WINDOWS) || defined(_MSC_VER)
+ #include "stdlib.h"
+ #define myapp_sleep(m) _sleep(m)
+ #else
+ #include <unistd.h>
+ #define myapp_sleep(m) ((void) usleep((m) * 1000))
+ #endif
+ """
+ # using "myapp_" prefix in the C code to prevent C naming conflicts
+ void msleep "myapp_sleep"(int milliseconds) nogil
+
+msleep(milliseconds=1)
diff --git a/docs/examples/userguide/external_C_code/struct_field_adaptation.h b/docs/examples/userguide/external_C_code/struct_field_adaptation.h
new file mode 100644
index 000000000..ca55460f4
--- /dev/null
+++ b/docs/examples/userguide/external_C_code/struct_field_adaptation.h
@@ -0,0 +1,13 @@
+typedef struct {
+ int field1;
+ int field2;
+ int newly_added_field;
+} StructType;
+
+static StructType global_struct;
+
+static StructType *get_struct_ptr() {
+ return &global_struct;
+}
+
+#define C_LIB_VERSION 20
diff --git a/docs/examples/userguide/external_C_code/struct_field_adaptation.pyx b/docs/examples/userguide/external_C_code/struct_field_adaptation.pyx
new file mode 100644
index 000000000..cff6bbdc2
--- /dev/null
+++ b/docs/examples/userguide/external_C_code/struct_field_adaptation.pyx
@@ -0,0 +1,31 @@
+cdef extern from "struct_field_adaptation.h":
+ """
+ #define HAS_NEWLY_ADDED_FIELD (C_LIB_VERSION >= 20)
+
+ #if HAS_NEWLY_ADDED_FIELD
+ #define _mylib_get_newly_added_field(a_struct_ptr) ((a_struct_ptr)->newly_added_field)
+ #define _mylib_set_newly_added_field(a_struct_ptr, value) ((a_struct_ptr)->newly_added_field) = (value)
+ #else
+ #define _mylib_get_newly_added_field(a_struct_ptr) (0)
+ #define _mylib_set_newly_added_field(a_struct_ptr, value) ((void) (value))
+ #endif
+ """
+
+ # Normal declarations provided by the C header file:
+ ctypedef struct StructType:
+ int field1
+ int field2
+
+ StructType *get_struct_ptr()
+
+ # Special declarations conditionally provided above:
+ bint HAS_NEWLY_ADDED_FIELD
+ int get_newly_added_field "_mylib_get_newly_added_field" (StructType *struct_ptr)
+ void set_newly_added_field "_mylib_set_newly_added_field" (StructType *struct_ptr, int value)
+
+
+cdef StructType *some_struct_ptr = get_struct_ptr()
+
+print(some_struct_ptr.field1)
+if HAS_NEWLY_ADDED_FIELD:
+ print(get_newly_added_field(some_struct_ptr))
diff --git a/docs/examples/userguide/external_C_code/c_code_docstring.pyx b/docs/examples/userguide/external_C_code/verbatim_c_code.pyx
index 430e89c48..fb1937166 100644
--- a/docs/examples/userguide/external_C_code/c_code_docstring.pyx
+++ b/docs/examples/userguide/external_C_code/verbatim_c_code.pyx
@@ -1,9 +1,9 @@
-cdef extern from *:
- """
- /* This is C code which will be put
- * in the .c file output by Cython */
- static long square(long x) {return x * x;}
- #define assign(x, y) ((x) = (y))
- """
- long square(long x)
- void assign(long& x, long y)
+cdef extern from *:
+ """
+ /* This is C code which will be put
+ * in the .c file output by Cython */
+ static long square(long x) {return x * x;}
+ #define assign(x, y) ((x) = (y))
+ """
+ long square(long x)
+ void assign(long& x, long y)
diff --git a/docs/examples/userguide/fusedtypes/char_or_float.py b/docs/examples/userguide/fusedtypes/char_or_float.py
new file mode 100644
index 000000000..4930bf065
--- /dev/null
+++ b/docs/examples/userguide/fusedtypes/char_or_float.py
@@ -0,0 +1,17 @@
+from __future__ import print_function
+
+char_or_float = cython.fused_type(cython.char, cython.float)
+
+
+
+@cython.ccall
+def plus_one(var: char_or_float) -> char_or_float:
+ return var + 1
+
+
+def show_me():
+
+ a: cython.char = 127
+ b: cython.float = 127
+ print('char', plus_one(a))
+ print('float', plus_one(b))
diff --git a/docs/examples/userguide/fusedtypes/char_or_float.pyx b/docs/examples/userguide/fusedtypes/char_or_float.pyx
index 6db746831..5a525431f 100644
--- a/docs/examples/userguide/fusedtypes/char_or_float.pyx
+++ b/docs/examples/userguide/fusedtypes/char_or_float.pyx
@@ -1,17 +1,17 @@
-from __future__ import print_function
-
-ctypedef fused char_or_float:
- char
- float
-
-
-cpdef char_or_float plus_one(char_or_float var):
- return var + 1
-
-
-def show_me():
- cdef:
- char a = 127
- float b = 127
- print('char', plus_one(a))
- print('float', plus_one(b))
+from __future__ import print_function
+
+ctypedef fused char_or_float:
+ char
+ float
+
+
+cpdef char_or_float plus_one(char_or_float var):
+ return var + 1
+
+
+def show_me():
+ cdef:
+ char a = 127
+ float b = 127
+ print('char', plus_one(a))
+ print('float', plus_one(b))
diff --git a/docs/examples/userguide/fusedtypes/conditional_gil.pyx b/docs/examples/userguide/fusedtypes/conditional_gil.pyx
new file mode 100644
index 000000000..473132f2e
--- /dev/null
+++ b/docs/examples/userguide/fusedtypes/conditional_gil.pyx
@@ -0,0 +1,15 @@
+cimport cython
+
+ctypedef fused double_or_object:
+ double
+ object
+
+def increment(double_or_object x):
+ with nogil(double_or_object is not object):
+ # Same code handles both cython.double (GIL is released)
+ # and python object (GIL is not released).
+ x = x + 1
+ return x
+
+increment(5.0) # GIL is released during increment
+increment(5) # GIL is acquired during increment
diff --git a/docs/examples/userguide/fusedtypes/indexing.py b/docs/examples/userguide/fusedtypes/indexing.py
new file mode 100644
index 000000000..054f6a742
--- /dev/null
+++ b/docs/examples/userguide/fusedtypes/indexing.py
@@ -0,0 +1,25 @@
+import cython
+
+fused_type1 = cython.fused_type(cython.double, cython.float)
+
+
+
+fused_type2 = cython.fused_type(cython.double, cython.float)
+
+
+@cython.cfunc
+def cfunc(arg1: fused_type1, arg2: fused_type1):
+ print("cfunc called:", cython.typeof(arg1), arg1, cython.typeof(arg2), arg2)
+
+@cython.ccall
+def cpfunc(a: fused_type1, b: fused_type2):
+ print("cpfunc called:", cython.typeof(a), a, cython.typeof(b), b)
+
+def func(a: fused_type1, b: fused_type2):
+ print("func called:", cython.typeof(a), a, cython.typeof(b), b)
+
+# called from Cython space
+cfunc[cython.double](5.0, 1.0)
+cpfunc[cython.float, cython.double](1.0, 2.0)
+# Indexing def functions in Cython code requires string names
+func["float", "double"](1.0, 2.0)
diff --git a/docs/examples/userguide/fusedtypes/indexing.pyx b/docs/examples/userguide/fusedtypes/indexing.pyx
new file mode 100644
index 000000000..16c7395f0
--- /dev/null
+++ b/docs/examples/userguide/fusedtypes/indexing.pyx
@@ -0,0 +1,25 @@
+cimport cython
+
+ctypedef fused fused_type1:
+ double
+ float
+
+ctypedef fused fused_type2:
+ double
+ float
+
+cdef cfunc(fused_type1 arg1, fused_type1 arg2):
+ print("cfunc called:", cython.typeof(arg1), arg1, cython.typeof(arg2), arg2)
+
+
+cpdef cpfunc(fused_type1 a, fused_type2 b):
+ print("cpfunc called:", cython.typeof(a), a, cython.typeof(b), b)
+
+def func(fused_type1 a, fused_type2 b):
+ print("func called:", cython.typeof(a), a, cython.typeof(b), b)
+
+# called from Cython space
+cfunc[double](5.0, 1.0)
+cpfunc[float, double](1.0, 2.0)
+# Indexing def function in Cython code requires string names
+func["float", "double"](1.0, 2.0)
diff --git a/docs/examples/userguide/fusedtypes/pointer.py b/docs/examples/userguide/fusedtypes/pointer.py
new file mode 100644
index 000000000..043074c79
--- /dev/null
+++ b/docs/examples/userguide/fusedtypes/pointer.py
@@ -0,0 +1,13 @@
+my_fused_type = cython.fused_type(cython.int, cython.float)
+
+
+@cython.cfunc
+def func(a: cython.pointer(my_fused_type)):
+ print(a[0])
+
+def main():
+ a: cython.int = 3
+ b: cython.float = 5.0
+
+ func(cython.address(a))
+ func(cython.address(b))
diff --git a/docs/examples/userguide/fusedtypes/pointer.pyx b/docs/examples/userguide/fusedtypes/pointer.pyx
new file mode 100644
index 000000000..ad7758c16
--- /dev/null
+++ b/docs/examples/userguide/fusedtypes/pointer.pyx
@@ -0,0 +1,13 @@
+ctypedef fused my_fused_type:
+ int
+ double
+
+cdef func(my_fused_type *a):
+ print(a[0])
+
+
+cdef int b = 3
+cdef double c = 3.0
+
+func(&b)
+func(&c)
diff --git a/docs/examples/userguide/fusedtypes/type_checking.py b/docs/examples/userguide/fusedtypes/type_checking.py
new file mode 100644
index 000000000..bffe4b328
--- /dev/null
+++ b/docs/examples/userguide/fusedtypes/type_checking.py
@@ -0,0 +1,28 @@
+bunch_of_types = cython.fused_type(bytes, cython.int, cython.float)
+
+
+
+
+
+
+string_t = cython.fused_type(cython.p_char, bytes, unicode)
+
+
+
+@cython.cfunc
+def myfunc(i: cython.integral, s: bunch_of_types) -> cython.integral:
+ # Only one of these branches will be compiled for each specialization!
+ if cython.integral is int:
+ print('i is an int')
+ elif cython.integral is long:
+ print('i is a long')
+ else:
+ print('i is a short')
+
+ if bunch_of_types in string_t:
+ print("s is a string!")
+ return i * 2
+
+myfunc(cython.cast(cython.int, 5), b'm') # will print "i is an int" and "s is a string"
+myfunc(cython.cast(cython.long, 5), 3) # will print "i is a long"
+myfunc(cython.cast(cython.short, 5), 3) # will print "i is a short"
diff --git a/docs/examples/userguide/fusedtypes/type_checking.pyx b/docs/examples/userguide/fusedtypes/type_checking.pyx
new file mode 100644
index 000000000..7bd359739
--- /dev/null
+++ b/docs/examples/userguide/fusedtypes/type_checking.pyx
@@ -0,0 +1,28 @@
+cimport cython
+
+ctypedef fused bunch_of_types:
+ bytes
+ int
+ float
+
+ctypedef fused string_t:
+ cython.p_char
+ bytes
+ unicode
+
+cdef cython.integral myfunc(cython.integral i, bunch_of_types s):
+ # Only one of these branches will be compiled for each specialization!
+ if cython.integral is int:
+ print('i is int')
+ elif cython.integral is long:
+ print('i is long')
+ else:
+ print('i is short')
+
+ if bunch_of_types in string_t:
+ print("s is a string!")
+ return i * 2
+
+myfunc(<int> 5, b'm') # will print "i is an int" and "s is a string"
+myfunc(<long> 5, 3) # will print "i is a long"
+myfunc(<short> 5, 3) # will print "i is a short"
diff --git a/docs/examples/userguide/language_basics/casting_python.pxd b/docs/examples/userguide/language_basics/casting_python.pxd
new file mode 100644
index 000000000..fa3d46030
--- /dev/null
+++ b/docs/examples/userguide/language_basics/casting_python.pxd
@@ -0,0 +1,2 @@
+cdef extern from *:
+ ctypedef Py_ssize_t Py_intptr_t
diff --git a/docs/examples/userguide/language_basics/casting_python.py b/docs/examples/userguide/language_basics/casting_python.py
new file mode 100644
index 000000000..1c02c461c
--- /dev/null
+++ b/docs/examples/userguide/language_basics/casting_python.py
@@ -0,0 +1,22 @@
+from cython.cimports.cpython.ref import PyObject
+
+def main():
+
+ python_string = "foo"
+
+ # Note that the variables below are automatically inferred
+ # as the correct pointer type that is assigned to them.
+ # They do not need to be typed explicitly.
+
+ ptr = cython.cast(cython.p_void, python_string)
+ adress_in_c = cython.cast(Py_intptr_t, ptr)
+ address_from_void = adress_in_c # address_from_void is a python int
+
+ ptr2 = cython.cast(cython.pointer(PyObject), python_string)
+ address_in_c2 = cython.cast(Py_intptr_t, ptr2)
+ address_from_PyObject = address_in_c2 # address_from_PyObject is a python int
+
+ assert address_from_void == address_from_PyObject == id(python_string)
+
+ print(cython.cast(object, ptr)) # Prints "foo"
+ print(cython.cast(object, ptr2)) # prints "foo"
diff --git a/docs/examples/userguide/language_basics/casting_python.pyx b/docs/examples/userguide/language_basics/casting_python.pyx
index fe84acde2..4cc819ae3 100644
--- a/docs/examples/userguide/language_basics/casting_python.pyx
+++ b/docs/examples/userguide/language_basics/casting_python.pyx
@@ -1,19 +1,19 @@
-from cpython.ref cimport PyObject
-
-cdef extern from *:
- ctypedef Py_ssize_t Py_intptr_t
-
-python_string = "foo"
-
-cdef void* ptr = <void*>python_string
-cdef Py_intptr_t adress_in_c = <Py_intptr_t>ptr
-address_from_void = adress_in_c # address_from_void is a python int
-
-cdef PyObject* ptr2 = <PyObject*>python_string
-cdef Py_intptr_t address_in_c2 = <Py_intptr_t>ptr2
-address_from_PyObject = address_in_c2 # address_from_PyObject is a python int
-
-assert address_from_void == address_from_PyObject == id(python_string)
-
-print(<object>ptr) # Prints "foo"
-print(<object>ptr2) # prints "foo"
+from cpython.ref cimport PyObject
+
+cdef extern from *:
+ ctypedef Py_ssize_t Py_intptr_t
+
+python_string = "foo"
+
+cdef void* ptr = <void*>python_string
+cdef Py_intptr_t adress_in_c = <Py_intptr_t>ptr
+address_from_void = adress_in_c # address_from_void is a python int
+
+cdef PyObject* ptr2 = <PyObject*>python_string
+cdef Py_intptr_t address_in_c2 = <Py_intptr_t>ptr2
+address_from_PyObject = address_in_c2 # address_from_PyObject is a python int
+
+assert address_from_void == address_from_PyObject == id(python_string)
+
+print(<object>ptr) # Prints "foo"
+print(<object>ptr2) # prints "foo"
diff --git a/docs/examples/userguide/language_basics/cdef_block.pyx b/docs/examples/userguide/language_basics/cdef_block.pyx
index 4132aeee1..c0c303029 100644
--- a/docs/examples/userguide/language_basics/cdef_block.pyx
+++ b/docs/examples/userguide/language_basics/cdef_block.pyx
@@ -1,12 +1,12 @@
-from __future__ import print_function
-
-cdef:
- struct Spam:
- int tons
-
- int i
- float a
- Spam *p
-
- void f(Spam *s):
- print(s.tons, "Tons of spam")
+from __future__ import print_function
+
+cdef:
+ struct Spam:
+ int tons
+
+ int i
+ float a
+ Spam *p
+
+ void f(Spam *s) except *:
+ print(s.tons, "Tons of spam")
diff --git a/docs/examples/userguide/language_basics/compile_time.pyx b/docs/examples/userguide/language_basics/compile_time.pyx
index fcaf75f29..f302dd241 100644
--- a/docs/examples/userguide/language_basics/compile_time.pyx
+++ b/docs/examples/userguide/language_basics/compile_time.pyx
@@ -1,9 +1,9 @@
-from __future__ import print_function
-
-DEF FavouriteFood = u"spam"
-DEF ArraySize = 42
-DEF OtherArraySize = 2 * ArraySize + 17
-
-cdef int a1[ArraySize]
-cdef int a2[OtherArraySize]
-print("I like", FavouriteFood) \ No newline at end of file
+from __future__ import print_function
+
+DEF FavouriteFood = u"spam"
+DEF ArraySize = 42
+DEF OtherArraySize = 2 * ArraySize + 17
+
+cdef int[ArraySize] a1
+cdef int[OtherArraySize] a2
+print("I like", FavouriteFood)
diff --git a/docs/examples/userguide/language_basics/struct_union_enum.pyx b/docs/examples/userguide/language_basics/enum.pyx
index ccbc28d42..1b5f5d614 100644
--- a/docs/examples/userguide/language_basics/struct_union_enum.pyx
+++ b/docs/examples/userguide/language_basics/enum.pyx
@@ -1,16 +1,11 @@
-cdef struct Grail:
- int age
- float volume
-
-cdef union Food:
- char *spam
- float *eggs
-
-cdef enum CheeseType:
- cheddar, edam,
- camembert
-
-cdef enum CheeseState:
- hard = 1
- soft = 2
- runny = 3
+cdef enum CheeseType:
+ cheddar, edam,
+ camembert
+
+cdef enum CheeseState:
+ hard = 1
+ soft = 2
+ runny = 3
+
+print(CheeseType.cheddar)
+print(CheeseState.hard)
diff --git a/docs/examples/userguide/language_basics/function_pointer.pyx b/docs/examples/userguide/language_basics/function_pointer.pyx
new file mode 100644
index 000000000..b345c62b4
--- /dev/null
+++ b/docs/examples/userguide/language_basics/function_pointer.pyx
@@ -0,0 +1,8 @@
+cdef int(*ptr_add)(int, int)
+
+cdef int add(int a, int b):
+ return a + b
+
+ptr_add = add
+
+print(ptr_add(1, 3))
diff --git a/docs/examples/userguide/language_basics/function_pointer_struct.pyx b/docs/examples/userguide/language_basics/function_pointer_struct.pyx
new file mode 100644
index 000000000..5ef618961
--- /dev/null
+++ b/docs/examples/userguide/language_basics/function_pointer_struct.pyx
@@ -0,0 +1,9 @@
+cdef struct Bar:
+ int sum(int a, int b)
+
+cdef int add(int a, int b):
+ return a + b
+
+cdef Bar bar = Bar(add)
+
+print(bar.sum(1, 2))
diff --git a/docs/examples/userguide/language_basics/kwargs_1.pyx b/docs/examples/userguide/language_basics/kwargs_1.pyx
index e5e18c008..1117c967c 100644
--- a/docs/examples/userguide/language_basics/kwargs_1.pyx
+++ b/docs/examples/userguide/language_basics/kwargs_1.pyx
@@ -1,6 +1,6 @@
-def f(a, b, *args, c, d = 42, e, **kwds):
- ...
-
-
-# We cannot call f with less verbosity than this.
-foo = f(4, "bar", c=68, e=1.0)
+def f(a, b, *args, c, d = 42, e, **kwds):
+ ...
+
+
+# We cannot call f with less verbosity than this.
+foo = f(4, "bar", c=68, e=1.0)
diff --git a/docs/examples/userguide/language_basics/kwargs_2.pyx b/docs/examples/userguide/language_basics/kwargs_2.pyx
index a2c639ea6..902df694c 100644
--- a/docs/examples/userguide/language_basics/kwargs_2.pyx
+++ b/docs/examples/userguide/language_basics/kwargs_2.pyx
@@ -1,5 +1,5 @@
-def g(a, b, *, c, d):
- ...
-
-# We cannot call g with less verbosity than this.
-foo = g(4.0, "something", c=68, d="other")
+def g(a, b, *, c, d):
+ ...
+
+# We cannot call g with less verbosity than this.
+foo = g(4.0, "something", c=68, d="other")
diff --git a/docs/examples/userguide/language_basics/open_file.py b/docs/examples/userguide/language_basics/open_file.py
new file mode 100644
index 000000000..ad3ae0374
--- /dev/null
+++ b/docs/examples/userguide/language_basics/open_file.py
@@ -0,0 +1,19 @@
+from cython.cimports.libc.stdio import FILE, fopen
+from cython.cimports.libc.stdlib import malloc, free
+from cython.cimports.cpython.exc import PyErr_SetFromErrnoWithFilenameObject
+
+def open_file():
+ p = fopen("spam.txt", "r") # The type of "p" is "FILE*", as returned by fopen().
+
+ if p is cython.NULL:
+ PyErr_SetFromErrnoWithFilenameObject(OSError, "spam.txt")
+ ...
+
+
+def allocating_memory(number=10):
+ # Note that the type of the variable "my_array" is automatically inferred from the assignment.
+ my_array = cython.cast(p_double, malloc(number * cython.sizeof(double)))
+ if not my_array: # same as 'is NULL' above
+ raise MemoryError()
+ ...
+ free(my_array)
diff --git a/docs/examples/userguide/language_basics/open_file.pyx b/docs/examples/userguide/language_basics/open_file.pyx
index 19eac104e..ad45fc8c4 100644
--- a/docs/examples/userguide/language_basics/open_file.pyx
+++ b/docs/examples/userguide/language_basics/open_file.pyx
@@ -1,18 +1,18 @@
-from libc.stdio cimport FILE, fopen
-from libc.stdlib cimport malloc, free
-from cpython.exc cimport PyErr_SetFromErrnoWithFilenameObject
-
-def open_file():
- cdef FILE* p
- p = fopen("spam.txt", "r")
- if p is NULL:
- PyErr_SetFromErrnoWithFilenameObject(OSError, "spam.txt")
- ...
-
-
-def allocating_memory(number=10):
- cdef double *my_array = <double *> malloc(number * sizeof(double))
- if not my_array: # same as 'is NULL' above
- raise MemoryError()
- ...
- free(my_array)
+from libc.stdio cimport FILE, fopen
+from libc.stdlib cimport malloc, free
+from cpython.exc cimport PyErr_SetFromErrnoWithFilenameObject
+
+def open_file():
+ cdef FILE* p
+ p = fopen("spam.txt", "r")
+ if p is NULL:
+ PyErr_SetFromErrnoWithFilenameObject(OSError, "spam.txt")
+ ...
+
+
+def allocating_memory(number=10):
+ cdef double *my_array = <double *> malloc(number * sizeof(double))
+ if not my_array: # same as 'is NULL' above
+ raise MemoryError()
+ ...
+ free(my_array)
diff --git a/docs/examples/userguide/language_basics/optional_subclassing.py b/docs/examples/userguide/language_basics/optional_subclassing.py
new file mode 100644
index 000000000..480ae100b
--- /dev/null
+++ b/docs/examples/userguide/language_basics/optional_subclassing.py
@@ -0,0 +1,19 @@
+from __future__ import print_function
+
+@cython.cclass
+class A:
+ @cython.cfunc
+ def foo(self):
+ print("A")
+
+@cython.cclass
+class B(A):
+ @cython.cfunc
+ def foo(self, x=None):
+ print("B", x)
+
+@cython.cclass
+class C(B):
+ @cython.ccall
+ def foo(self, x=True, k:cython.int = 3):
+ print("C", x, k)
diff --git a/docs/examples/userguide/language_basics/optional_subclassing.pyx b/docs/examples/userguide/language_basics/optional_subclassing.pyx
index f655cadf3..b2a3d4dec 100644
--- a/docs/examples/userguide/language_basics/optional_subclassing.pyx
+++ b/docs/examples/userguide/language_basics/optional_subclassing.pyx
@@ -1,13 +1,19 @@
-from __future__ import print_function
-
-cdef class A:
- cdef foo(self):
- print("A")
-
-cdef class B(A):
- cdef foo(self, x=None):
- print("B", x)
-
-cdef class C(B):
- cpdef foo(self, x=True, int k=3):
- print("C", x, k)
+from __future__ import print_function
+
+
+cdef class A:
+
+ cdef foo(self):
+ print("A")
+
+
+cdef class B(A):
+
+ cdef foo(self, x=None):
+ print("B", x)
+
+
+cdef class C(B):
+
+ cpdef foo(self, x=True, int k=3):
+ print("C", x, k)
diff --git a/docs/examples/userguide/language_basics/override.py b/docs/examples/userguide/language_basics/override.py
new file mode 100644
index 000000000..f9e0be83f
--- /dev/null
+++ b/docs/examples/userguide/language_basics/override.py
@@ -0,0 +1,17 @@
+from __future__ import print_function
+
+@cython.cclass
+class A:
+ @cython.cfunc
+ def foo(self):
+ print("A")
+
+@cython.cclass
+class B(A):
+ @cython.ccall
+ def foo(self):
+ print("B")
+
+class C(B): # NOTE: no cclass decorator
+ def foo(self):
+ print("C")
diff --git a/docs/examples/userguide/language_basics/override.pyx b/docs/examples/userguide/language_basics/override.pyx
index 873a7ec6e..1a7ceefb7 100644
--- a/docs/examples/userguide/language_basics/override.pyx
+++ b/docs/examples/userguide/language_basics/override.pyx
@@ -1,13 +1,17 @@
-from __future__ import print_function
-
-cdef class A:
- cdef foo(self):
- print("A")
-
-cdef class B(A):
- cpdef foo(self):
- print("B")
-
-class C(B): # NOTE: not cdef class
- def foo(self):
- print("C")
+from __future__ import print_function
+
+
+cdef class A:
+
+ cdef foo(self):
+ print("A")
+
+
+cdef class B(A):
+
+ cpdef foo(self):
+ print("B")
+
+class C(B): # NOTE: not cdef class
+ def foo(self):
+ print("C")
diff --git a/docs/examples/userguide/language_basics/parameter_refcount.py b/docs/examples/userguide/language_basics/parameter_refcount.py
new file mode 100644
index 000000000..2b25915ba
--- /dev/null
+++ b/docs/examples/userguide/language_basics/parameter_refcount.py
@@ -0,0 +1,23 @@
+from __future__ import print_function
+
+from cython.cimports.cpython.ref import PyObject
+
+import sys
+
+python_dict = {"abc": 123}
+python_dict_refcount = sys.getrefcount(python_dict)
+
+@cython.cfunc
+def owned_reference(obj: object):
+ refcount = sys.getrefcount(python_dict)
+ print('Inside owned_reference: {refcount}'.format(refcount=refcount))
+
+@cython.cfunc
+def borrowed_reference(obj: cython.pointer(PyObject)):
+ refcount = obj.ob_refcnt
+ print('Inside borrowed_reference: {refcount}'.format(refcount=refcount))
+
+def main():
+ print('Initial refcount: {refcount}'.format(refcount=python_dict_refcount))
+ owned_reference(python_dict)
+ borrowed_reference(cython.cast(cython.pointer(PyObject), python_dict))
diff --git a/docs/examples/userguide/language_basics/parameter_refcount.pyx b/docs/examples/userguide/language_basics/parameter_refcount.pyx
new file mode 100644
index 000000000..6fe3ffadd
--- /dev/null
+++ b/docs/examples/userguide/language_basics/parameter_refcount.pyx
@@ -0,0 +1,23 @@
+from __future__ import print_function
+
+from cpython.ref cimport PyObject
+
+import sys
+
+python_dict = {"abc": 123}
+python_dict_refcount = sys.getrefcount(python_dict)
+
+
+cdef owned_reference(object obj):
+ refcount = sys.getrefcount(python_dict)
+ print('Inside owned_reference: {refcount}'.format(refcount=refcount))
+
+
+cdef borrowed_reference(PyObject * obj):
+ refcount = obj.ob_refcnt
+ print('Inside borrowed_reference: {refcount}'.format(refcount=refcount))
+
+
+print('Initial refcount: {refcount}'.format(refcount=python_dict_refcount))
+owned_reference(python_dict)
+borrowed_reference(<PyObject *>python_dict)
diff --git a/docs/examples/userguide/language_basics/struct.py b/docs/examples/userguide/language_basics/struct.py
new file mode 100644
index 000000000..32b6b252a
--- /dev/null
+++ b/docs/examples/userguide/language_basics/struct.py
@@ -0,0 +1,7 @@
+Grail = cython.struct(
+ age=cython.int,
+ volume=cython.float)
+
+def main():
+ grail: Grail = Grail(5, 3.0)
+ print(grail.age, grail.volume)
diff --git a/docs/examples/userguide/language_basics/struct.pyx b/docs/examples/userguide/language_basics/struct.pyx
new file mode 100644
index 000000000..3ef79172b
--- /dev/null
+++ b/docs/examples/userguide/language_basics/struct.pyx
@@ -0,0 +1,7 @@
+cdef struct Grail:
+ int age
+ float volume
+
+def main():
+ cdef Grail grail = Grail(5, 3.0)
+ print(grail.age, grail.volume)
diff --git a/docs/examples/userguide/language_basics/union.py b/docs/examples/userguide/language_basics/union.py
new file mode 100644
index 000000000..efcda358b
--- /dev/null
+++ b/docs/examples/userguide/language_basics/union.py
@@ -0,0 +1,9 @@
+Food = cython.union(
+ spam=cython.p_char,
+ eggs=cython.p_float)
+
+def main():
+ arr: cython.p_float = [1.0, 2.0]
+ spam: Food = Food(spam='b')
+ eggs: Food = Food(eggs=arr)
+ print(spam.spam, eggs.eggs[0])
diff --git a/docs/examples/userguide/language_basics/union.pyx b/docs/examples/userguide/language_basics/union.pyx
new file mode 100644
index 000000000..e05f63fcc
--- /dev/null
+++ b/docs/examples/userguide/language_basics/union.pyx
@@ -0,0 +1,9 @@
+cdef union Food:
+ char *spam
+ float *eggs
+
+def main():
+ cdef float *arr = [1.0, 2.0]
+ cdef Food spam = Food(spam='b')
+ cdef Food eggs = Food(eggs=arr)
+ print(spam.spam, eggs.eggs[0])
diff --git a/docs/examples/userguide/memoryviews/add_one.pyx b/docs/examples/userguide/memoryviews/add_one.pyx
index cbe65b069..7de7a1274 100644
--- a/docs/examples/userguide/memoryviews/add_one.pyx
+++ b/docs/examples/userguide/memoryviews/add_one.pyx
@@ -1,12 +1,12 @@
-import numpy as np
-
-def add_one(int[:,:] buf):
- for x in range(buf.shape[0]):
- for y in range(buf.shape[1]):
- buf[x, y] += 1
-
-# exporting_object must be a Python object
-# implementing the buffer interface, e.g. a numpy array.
-exporting_object = np.zeros((10, 20), dtype=np.intc)
-
-add_one(exporting_object)
+import numpy as np
+
+def add_one(int[:,:] buf):
+ for x in range(buf.shape[0]):
+ for y in range(buf.shape[1]):
+ buf[x, y] += 1
+
+# exporting_object must be a Python object
+# implementing the buffer interface, e.g. a numpy array.
+exporting_object = np.zeros((10, 20), dtype=np.intc)
+
+add_one(exporting_object)
diff --git a/docs/examples/userguide/memoryviews/copy.pyx b/docs/examples/userguide/memoryviews/copy.pyx
index 9f000a3b4..9eb1307bf 100644
--- a/docs/examples/userguide/memoryviews/copy.pyx
+++ b/docs/examples/userguide/memoryviews/copy.pyx
@@ -1,12 +1,12 @@
-import numpy as np
-
-cdef int[:, :, :] to_view, from_view
-to_view = np.empty((20, 15, 30), dtype=np.intc)
-from_view = np.ones((20, 15, 30), dtype=np.intc)
-
-# copy the elements in from_view to to_view
-to_view[...] = from_view
-# or
-to_view[:] = from_view
-# or
-to_view[:, :, :] = from_view
+import numpy as np
+
+cdef int[:, :, :] to_view, from_view
+to_view = np.empty((20, 15, 30), dtype=np.intc)
+from_view = np.ones((20, 15, 30), dtype=np.intc)
+
+# copy the elements in from_view to to_view
+to_view[...] = from_view
+# or
+to_view[:] = from_view
+# or
+to_view[:, :, :] = from_view
diff --git a/docs/examples/userguide/memoryviews/custom_dtype.pyx b/docs/examples/userguide/memoryviews/custom_dtype.pyx
new file mode 100644
index 000000000..d54d7bbc4
--- /dev/null
+++ b/docs/examples/userguide/memoryviews/custom_dtype.pyx
@@ -0,0 +1,26 @@
+import numpy as np
+
+CUSTOM_DTYPE = np.dtype([
+ ('x', np.uint8),
+ ('y', np.float32),
+])
+
+a = np.zeros(100, dtype=CUSTOM_DTYPE)
+
+cdef packed struct custom_dtype_struct:
+ # The struct needs to be packed since by default numpy dtypes aren't
+ # aligned
+ unsigned char x
+ float y
+
+def sum(custom_dtype_struct [:] a):
+
+ cdef:
+ unsigned char sum_x = 0
+ float sum_y = 0.
+
+ for i in range(a.shape[0]):
+ sum_x += a[i].x
+ sum_y += a[i].y
+
+ return sum_x, sum_y
diff --git a/docs/examples/userguide/memoryviews/memory_layout.pyx b/docs/examples/userguide/memoryviews/memory_layout.pyx
index 5c2818dc0..8f9d8a23c 100644
--- a/docs/examples/userguide/memoryviews/memory_layout.pyx
+++ b/docs/examples/userguide/memoryviews/memory_layout.pyx
@@ -1,11 +1,11 @@
-from cython cimport view
-
-# direct access in both dimensions, strided in the first dimension, contiguous in the last
-cdef int[:, ::view.contiguous] a
-
-# contiguous list of pointers to contiguous lists of ints
-cdef int[::view.indirect_contiguous, ::1] b
-
-# direct or indirect in the first dimension, direct in the second dimension
-# strided in both dimensions
-cdef int[::view.generic, :] c
+from cython cimport view
+
+# direct access in both dimensions, strided in the first dimension, contiguous in the last
+cdef int[:, ::view.contiguous] a
+
+# contiguous list of pointers to contiguous lists of ints
+cdef int[::view.indirect_contiguous, ::1] b
+
+# direct or indirect in the first dimension, direct in the second dimension
+# strided in both dimensions
+cdef int[::view.generic, :] c
diff --git a/docs/examples/userguide/memoryviews/memory_layout_2.pyx b/docs/examples/userguide/memoryviews/memory_layout_2.pyx
index 1cb039dd4..71d2cceb2 100644
--- a/docs/examples/userguide/memoryviews/memory_layout_2.pyx
+++ b/docs/examples/userguide/memoryviews/memory_layout_2.pyx
@@ -1,6 +1,6 @@
-from cython cimport view
-
-# VALID
-cdef int[::view.indirect, ::1, :] a
-cdef int[::view.indirect, :, ::1] b
-cdef int[::view.indirect_contiguous, ::1, :] c
+from cython cimport view
+
+# VALID
+cdef int[::view.indirect, ::1, :] a
+cdef int[::view.indirect, :, ::1] b
+cdef int[::view.indirect_contiguous, ::1, :] c
diff --git a/docs/examples/userguide/memoryviews/memview_to_c.pyx b/docs/examples/userguide/memoryviews/memview_to_c.pyx
index c5abc19ac..ad6190cc7 100644
--- a/docs/examples/userguide/memoryviews/memview_to_c.pyx
+++ b/docs/examples/userguide/memoryviews/memview_to_c.pyx
@@ -1,28 +1,28 @@
-cdef extern from "C_func_file.c":
- # C is include here so that it doesn't need to be compiled externally
- pass
-
-cdef extern from "C_func_file.h":
- void multiply_by_10_in_C(double *, unsigned int)
-
-import numpy as np
-
-def multiply_by_10(arr): # 'arr' is a one-dimensional numpy array
-
- if not arr.flags['C_CONTIGUOUS']:
- arr = np.ascontiguousarray(arr) # Makes a contiguous copy of the numpy array.
-
- cdef double[::1] arr_memview = arr
-
- multiply_by_10_in_C(&arr_memview[0], arr_memview.shape[0])
-
- return arr
-
-
-a = np.ones(5, dtype=np.double)
-print(multiply_by_10(a))
-
-b = np.ones(10, dtype=np.double)
-b = b[::2] # b is not contiguous.
-
-print(multiply_by_10(b)) # but our function still works as expected.
+cdef extern from "C_func_file.c":
+ # C is include here so that it doesn't need to be compiled externally
+ pass
+
+cdef extern from "C_func_file.h":
+ void multiply_by_10_in_C(double *, unsigned int)
+
+import numpy as np
+
+def multiply_by_10(arr): # 'arr' is a one-dimensional numpy array
+
+ if not arr.flags['C_CONTIGUOUS']:
+ arr = np.ascontiguousarray(arr) # Makes a contiguous copy of the numpy array.
+
+ cdef double[::1] arr_memview = arr
+
+ multiply_by_10_in_C(&arr_memview[0], arr_memview.shape[0])
+
+ return arr
+
+
+a = np.ones(5, dtype=np.double)
+print(multiply_by_10(a))
+
+b = np.ones(10, dtype=np.double)
+b = b[::2] # b is not contiguous.
+
+print(multiply_by_10(b)) # but our function still works as expected.
diff --git a/docs/examples/userguide/memoryviews/not_none.pyx b/docs/examples/userguide/memoryviews/not_none.pyx
index ae3b6c936..f6c0fed8a 100644
--- a/docs/examples/userguide/memoryviews/not_none.pyx
+++ b/docs/examples/userguide/memoryviews/not_none.pyx
@@ -1,11 +1,11 @@
-import numpy as np
-
-def process_buffer(int[:,:] input_view not None,
- int[:,:] output_view=None):
-
- if output_view is None:
- # Creating a default view, e.g.
- output_view = np.empty_like(input_view)
-
- # process 'input_view' into 'output_view'
- return output_view
+import numpy as np
+
+def process_buffer(int[:,:] input_view not None,
+ int[:,:] output_view=None):
+
+ if output_view is None:
+ # Creating a default view, e.g.
+ output_view = np.empty_like(input_view)
+
+ # process 'input_view' into 'output_view'
+ return output_view
diff --git a/docs/examples/userguide/memoryviews/np_flag_const.pyx b/docs/examples/userguide/memoryviews/np_flag_const.pyx
index 03f0ea4a3..54eb3d338 100644
--- a/docs/examples/userguide/memoryviews/np_flag_const.pyx
+++ b/docs/examples/userguide/memoryviews/np_flag_const.pyx
@@ -1,7 +1,7 @@
-import numpy as np
-
-cdef const double[:] myslice # const item type => read-only view
-
-a = np.linspace(0, 10, num=50)
-a.setflags(write=False)
-myslice = a
+import numpy as np
+
+cdef const double[:] myslice # const item type => read-only view
+
+a = np.linspace(0, 10, num=50)
+a.setflags(write=False)
+myslice = a
diff --git a/docs/examples/userguide/memoryviews/quickstart.pyx b/docs/examples/userguide/memoryviews/quickstart.pyx
index 58335c0cf..a313859d9 100644
--- a/docs/examples/userguide/memoryviews/quickstart.pyx
+++ b/docs/examples/userguide/memoryviews/quickstart.pyx
@@ -6,7 +6,7 @@ narr = np.arange(27, dtype=np.dtype("i")).reshape((3, 3, 3))
cdef int [:, :, :] narr_view = narr
# Memoryview on a C array
-cdef int carr[3][3][3]
+cdef int[3][3][3] carr
cdef int [:, :, :] carr_view = carr
# Memoryview on a Cython array
diff --git a/docs/examples/userguide/memoryviews/slicing.pyx b/docs/examples/userguide/memoryviews/slicing.pyx
index a6134aae2..d7bd896e6 100644
--- a/docs/examples/userguide/memoryviews/slicing.pyx
+++ b/docs/examples/userguide/memoryviews/slicing.pyx
@@ -1,10 +1,10 @@
-import numpy as np
-
-exporting_object = np.arange(0, 15 * 10 * 20, dtype=np.intc).reshape((15, 10, 20))
-
-cdef int[:, :, :] my_view = exporting_object
-
-# These are all equivalent
-my_view[10]
-my_view[10, :, :]
-my_view[10, ...]
+import numpy as np
+
+exporting_object = np.arange(0, 15 * 10 * 20, dtype=np.intc).reshape((15, 10, 20))
+
+cdef int[:, :, :] my_view = exporting_object
+
+# These are all equivalent
+my_view[10]
+my_view[10, :, :]
+my_view[10, ...]
diff --git a/docs/examples/userguide/memoryviews/transpose.pyx b/docs/examples/userguide/memoryviews/transpose.pyx
index 7611529c2..8a53f7140 100644
--- a/docs/examples/userguide/memoryviews/transpose.pyx
+++ b/docs/examples/userguide/memoryviews/transpose.pyx
@@ -1,6 +1,6 @@
-import numpy as np
-
-array = np.arange(20, dtype=np.intc).reshape((2, 10))
-
-cdef int[:, ::1] c_contig = array
-cdef int[::1, :] f_contig = c_contig.T
+import numpy as np
+
+array = np.arange(20, dtype=np.intc).reshape((2, 10))
+
+cdef int[:, ::1] c_contig = array
+cdef int[::1, :] f_contig = c_contig.T
diff --git a/docs/examples/userguide/memoryviews/view_string.pyx b/docs/examples/userguide/memoryviews/view_string.pyx
index 7aace3ea5..9fdeae053 100644
--- a/docs/examples/userguide/memoryviews/view_string.pyx
+++ b/docs/examples/userguide/memoryviews/view_string.pyx
@@ -1,9 +1,9 @@
-cdef bint is_y_in(const unsigned char[:] string_view):
- cdef int i
- for i in range(string_view.shape[0]):
- if string_view[i] == b'y':
- return True
- return False
-
-print(is_y_in(b'hello world')) # False
-print(is_y_in(b'hello Cython')) # True
+cdef bint is_y_in(const unsigned char[:] string_view):
+ cdef int i
+ for i in range(string_view.shape[0]):
+ if string_view[i] == b'y':
+ return True
+ return False
+
+print(is_y_in(b'hello world')) # False
+print(is_y_in(b'hello Cython')) # True
diff --git a/docs/examples/userguide/numpy_tutorial/compute_fused_types.pyx b/docs/examples/userguide/numpy_tutorial/compute_fused_types.pyx
index 2fc87907d..af5ef9071 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_fused_types.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_fused_types.pyx
@@ -1,44 +1,44 @@
-# cython: infer_types=True
-import numpy as np
-cimport cython
-
-ctypedef fused my_type:
- int
- double
- long long
-
-
-cdef my_type clip(my_type a, my_type min_value, my_type max_value):
- return min(max(a, min_value), max_value)
-
-
-@cython.boundscheck(False)
-@cython.wraparound(False)
-def compute(my_type[:, ::1] array_1, my_type[:, ::1] array_2, my_type a, my_type b, my_type c):
-
- x_max = array_1.shape[0]
- y_max = array_1.shape[1]
-
- assert tuple(array_1.shape) == tuple(array_2.shape)
-
- if my_type is int:
- dtype = np.intc
- elif my_type is double:
- dtype = np.double
- elif my_type is cython.longlong:
- dtype = np.longlong
-
- result = np.zeros((x_max, y_max), dtype=dtype)
- cdef my_type[:, ::1] result_view = result
-
- cdef my_type tmp
- cdef Py_ssize_t x, y
-
- for x in range(x_max):
- for y in range(y_max):
-
- tmp = clip(array_1[x, y], 2, 10)
- tmp = tmp * a + array_2[x, y] * b
- result_view[x, y] = tmp + c
-
- return result
+# cython: infer_types=True
+import numpy as np
+cimport cython
+
+ctypedef fused my_type:
+ int
+ double
+ long long
+
+
+cdef my_type clip(my_type a, my_type min_value, my_type max_value):
+ return min(max(a, min_value), max_value)
+
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def compute(my_type[:, ::1] array_1, my_type[:, ::1] array_2, my_type a, my_type b, my_type c):
+
+ x_max = array_1.shape[0]
+ y_max = array_1.shape[1]
+
+ assert tuple(array_1.shape) == tuple(array_2.shape)
+
+ if my_type is int:
+ dtype = np.intc
+ elif my_type is double:
+ dtype = np.double
+ elif my_type is cython.longlong:
+ dtype = np.longlong
+
+ result = np.zeros((x_max, y_max), dtype=dtype)
+ cdef my_type[:, ::1] result_view = result
+
+ cdef my_type tmp
+ cdef Py_ssize_t x, y
+
+ for x in range(x_max):
+ for y in range(y_max):
+
+ tmp = clip(array_1[x, y], 2, 10)
+ tmp = tmp * a + array_2[x, y] * b
+ result_view[x, y] = tmp + c
+
+ return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_infer_types.pyx b/docs/examples/userguide/numpy_tutorial/compute_infer_types.pyx
index 98a683de7..3882c289d 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_infer_types.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_infer_types.pyx
@@ -1,34 +1,34 @@
-# cython: infer_types=True
-import numpy as np
-cimport cython
-
-DTYPE = np.intc
-
-
-cdef int clip(int a, int min_value, int max_value):
- return min(max(a, min_value), max_value)
-
-
-@cython.boundscheck(False)
-@cython.wraparound(False)
-def compute(int[:, ::1] array_1, int[:, ::1] array_2, int a, int b, int c):
-
- x_max = array_1.shape[0]
- y_max = array_1.shape[1]
-
- assert tuple(array_1.shape) == tuple(array_2.shape)
-
- result = np.zeros((x_max, y_max), dtype=DTYPE)
- cdef int[:, ::1] result_view = result
-
- cdef int tmp
- cdef Py_ssize_t x, y
-
- for x in range(x_max):
- for y in range(y_max):
-
- tmp = clip(array_1[x, y], 2, 10)
- tmp = tmp * a + array_2[x, y] * b
- result_view[x, y] = tmp + c
-
- return result
+# cython: infer_types=True
+import numpy as np
+cimport cython
+
+DTYPE = np.intc
+
+
+cdef int clip(int a, int min_value, int max_value):
+ return min(max(a, min_value), max_value)
+
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def compute(int[:, ::1] array_1, int[:, ::1] array_2, int a, int b, int c):
+
+ x_max = array_1.shape[0]
+ y_max = array_1.shape[1]
+
+ assert tuple(array_1.shape) == tuple(array_2.shape)
+
+ result = np.zeros((x_max, y_max), dtype=DTYPE)
+ cdef int[:, ::1] result_view = result
+
+ cdef int tmp
+ cdef Py_ssize_t x, y
+
+ for x in range(x_max):
+ for y in range(y_max):
+
+ tmp = clip(array_1[x, y], 2, 10)
+ tmp = tmp * a + array_2[x, y] * b
+ result_view[x, y] = tmp + c
+
+ return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_memview.pyx b/docs/examples/userguide/numpy_tutorial/compute_memview.pyx
index d264e773a..166cd6df3 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_memview.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_memview.pyx
@@ -1,34 +1,34 @@
-import numpy as np
-
-DTYPE = np.intc
-
-
-cdef int clip(int a, int min_value, int max_value):
- return min(max(a, min_value), max_value)
-
-
-def compute(int[:, :] array_1, int[:, :] array_2, int a, int b, int c):
-
- cdef Py_ssize_t x_max = array_1.shape[0]
- cdef Py_ssize_t y_max = array_1.shape[1]
-
- # array_1.shape is now a C array, no it's not possible
- # to compare it simply by using == without a for-loop.
- # To be able to compare it to array_2.shape easily,
- # we convert them both to Python tuples.
- assert tuple(array_1.shape) == tuple(array_2.shape)
-
- result = np.zeros((x_max, y_max), dtype=DTYPE)
- cdef int[:, :] result_view = result
-
- cdef int tmp
- cdef Py_ssize_t x, y
-
- for x in range(x_max):
- for y in range(y_max):
-
- tmp = clip(array_1[x, y], 2, 10)
- tmp = tmp * a + array_2[x, y] * b
- result_view[x, y] = tmp + c
-
- return result
+import numpy as np
+
+DTYPE = np.intc
+
+
+cdef int clip(int a, int min_value, int max_value):
+ return min(max(a, min_value), max_value)
+
+
+def compute(int[:, :] array_1, int[:, :] array_2, int a, int b, int c):
+
+ cdef Py_ssize_t x_max = array_1.shape[0]
+ cdef Py_ssize_t y_max = array_1.shape[1]
+
+ # array_1.shape is now a C array, no it's not possible
+ # to compare it simply by using == without a for-loop.
+ # To be able to compare it to array_2.shape easily,
+ # we convert them both to Python tuples.
+ assert tuple(array_1.shape) == tuple(array_2.shape)
+
+ result = np.zeros((x_max, y_max), dtype=DTYPE)
+ cdef int[:, :] result_view = result
+
+ cdef int tmp
+ cdef Py_ssize_t x, y
+
+ for x in range(x_max):
+ for y in range(y_max):
+
+ tmp = clip(array_1[x, y], 2, 10)
+ tmp = tmp * a + array_2[x, y] * b
+ result_view[x, y] = tmp + c
+
+ return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_prange.pyx b/docs/examples/userguide/numpy_tutorial/compute_prange.pyx
index c00d2261b..562c73070 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_prange.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_prange.pyx
@@ -1,53 +1,53 @@
-# tag: openmp
-# You can ignore the previous line.
-# It's for internal testing of the cython documentation.
-
-# distutils: extra_compile_args=-fopenmp
-# distutils: extra_link_args=-fopenmp
-
-import numpy as np
-cimport cython
-from cython.parallel import prange
-
-ctypedef fused my_type:
- int
- double
- long long
-
-
-# We declare our plain c function nogil
-cdef my_type clip(my_type a, my_type min_value, my_type max_value) nogil:
- return min(max(a, min_value), max_value)
-
-
-@cython.boundscheck(False)
-@cython.wraparound(False)
-def compute(my_type[:, ::1] array_1, my_type[:, ::1] array_2, my_type a, my_type b, my_type c):
-
- cdef Py_ssize_t x_max = array_1.shape[0]
- cdef Py_ssize_t y_max = array_1.shape[1]
-
- assert tuple(array_1.shape) == tuple(array_2.shape)
-
- if my_type is int:
- dtype = np.intc
- elif my_type is double:
- dtype = np.double
- elif my_type is cython.longlong:
- dtype = np.longlong
-
- result = np.zeros((x_max, y_max), dtype=dtype)
- cdef my_type[:, ::1] result_view = result
-
- cdef my_type tmp
- cdef Py_ssize_t x, y
-
- # We use prange here.
- for x in prange(x_max, nogil=True):
- for y in range(y_max):
-
- tmp = clip(array_1[x, y], 2, 10)
- tmp = tmp * a + array_2[x, y] * b
- result_view[x, y] = tmp + c
-
- return result
+# tag: openmp
+# You can ignore the previous line.
+# It's for internal testing of the cython documentation.
+
+# distutils: extra_compile_args=-fopenmp
+# distutils: extra_link_args=-fopenmp
+
+import numpy as np
+cimport cython
+from cython.parallel import prange
+
+ctypedef fused my_type:
+ int
+ double
+ long long
+
+
+# We declare our plain c function nogil
+cdef my_type clip(my_type a, my_type min_value, my_type max_value) nogil:
+ return min(max(a, min_value), max_value)
+
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def compute(my_type[:, ::1] array_1, my_type[:, ::1] array_2, my_type a, my_type b, my_type c):
+
+ cdef Py_ssize_t x_max = array_1.shape[0]
+ cdef Py_ssize_t y_max = array_1.shape[1]
+
+ assert tuple(array_1.shape) == tuple(array_2.shape)
+
+ if my_type is int:
+ dtype = np.intc
+ elif my_type is double:
+ dtype = np.double
+ elif my_type is cython.longlong:
+ dtype = np.longlong
+
+ result = np.zeros((x_max, y_max), dtype=dtype)
+ cdef my_type[:, ::1] result_view = result
+
+ cdef my_type tmp
+ cdef Py_ssize_t x, y
+
+ # We use prange here.
+ for x in prange(x_max, nogil=True):
+ for y in range(y_max):
+
+ tmp = clip(array_1[x, y], 2, 10)
+ tmp = tmp * a + array_2[x, y] * b
+ result_view[x, y] = tmp + c
+
+ return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_py.py b/docs/examples/userguide/numpy_tutorial/compute_py.py
index 00bcf244c..4a5f90b4d 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_py.py
+++ b/docs/examples/userguide/numpy_tutorial/compute_py.py
@@ -1,28 +1,28 @@
-import numpy as np
-
-
-def clip(a, min_value, max_value):
- return min(max(a, min_value), max_value)
-
-
-def compute(array_1, array_2, a, b, c):
- """
- This function must implement the formula
- np.clip(array_1, 2, 10) * a + array_2 * b + c
-
- array_1 and array_2 are 2D.
- """
- x_max = array_1.shape[0]
- y_max = array_1.shape[1]
-
- assert array_1.shape == array_2.shape
-
- result = np.zeros((x_max, y_max), dtype=array_1.dtype)
-
- for x in range(x_max):
- for y in range(y_max):
- tmp = clip(array_1[x, y], 2, 10)
- tmp = tmp * a + array_2[x, y] * b
- result[x, y] = tmp + c
-
- return result
+import numpy as np
+
+
+def clip(a, min_value, max_value):
+ return min(max(a, min_value), max_value)
+
+
+def compute(array_1, array_2, a, b, c):
+ """
+ This function must implement the formula
+ np.clip(array_1, 2, 10) * a + array_2 * b + c
+
+ array_1 and array_2 are 2D.
+ """
+ x_max = array_1.shape[0]
+ y_max = array_1.shape[1]
+
+ assert array_1.shape == array_2.shape
+
+ result = np.zeros((x_max, y_max), dtype=array_1.dtype)
+
+ for x in range(x_max):
+ for y in range(y_max):
+ tmp = clip(array_1[x, y], 2, 10)
+ tmp = tmp * a + array_2[x, y] * b
+ result[x, y] = tmp + c
+
+ return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_typed.pyx b/docs/examples/userguide/numpy_tutorial/compute_typed.pyx
index 8218aa709..cccc1aa3b 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_typed.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_typed.pyx
@@ -1,50 +1,50 @@
-import numpy as np
-
-# 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.
-DTYPE = np.intc
-
-# cdef means here that this function is a plain C function (so faster).
-# To get all the benefits, we type the arguments and the return value.
-cdef int clip(int a, int min_value, int max_value):
- return min(max(a, min_value), max_value)
-
-
-def compute(array_1, array_2, int a, int b, int c):
-
- # The "cdef" keyword is also used within functions to type variables. It
- # can only be used at the top indentation level (there are non-trivial
- # problems with allowing them in other places, though we'd love to see
- # good and thought out proposals for it).
- cdef Py_ssize_t x_max = array_1.shape[0]
- cdef Py_ssize_t y_max = array_1.shape[1]
-
- assert array_1.shape == array_2.shape
- assert array_1.dtype == DTYPE
- assert array_2.dtype == DTYPE
-
- result = np.zeros((x_max, y_max), dtype=DTYPE)
-
- # It is very important to type ALL your variables. You do not get any
- # warnings if not, only much slower code (they are implicitly typed as
- # Python objects).
- # For the "tmp" variable, we want to use the same data type as is
- # stored in the array, so we use int because it correspond to np.intc.
- # NB! An important side-effect of this is that if "tmp" overflows its
- # datatype size, it will simply wrap around like in C, rather than raise
- # an error like in Python.
-
- cdef int tmp
-
- # Py_ssize_t is the proper C type for Python array indices.
- cdef Py_ssize_t x, y
-
- for x in range(x_max):
- for y in range(y_max):
-
- tmp = clip(array_1[x, y], 2, 10)
- tmp = tmp * a + array_2[x, y] * b
- result[x, y] = tmp + c
-
- return result
+import numpy as np
+
+# 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.
+DTYPE = np.intc
+
+# cdef means here that this function is a plain C function (so faster).
+# To get all the benefits, we type the arguments and the return value.
+cdef int clip(int a, int min_value, int max_value):
+ return min(max(a, min_value), max_value)
+
+
+def compute(array_1, array_2, int a, int b, int c):
+
+ # The "cdef" keyword is also used within functions to type variables. It
+ # can only be used at the top indentation level (there are non-trivial
+ # problems with allowing them in other places, though we'd love to see
+ # good and thought out proposals for it).
+ cdef Py_ssize_t x_max = array_1.shape[0]
+ cdef Py_ssize_t y_max = array_1.shape[1]
+
+ assert array_1.shape == array_2.shape
+ assert array_1.dtype == DTYPE
+ assert array_2.dtype == DTYPE
+
+ result = np.zeros((x_max, y_max), dtype=DTYPE)
+
+ # It is very important to type ALL your variables. You do not get any
+ # warnings if not, only much slower code (they are implicitly typed as
+ # Python objects).
+ # For the "tmp" variable, we want to use the same data type as is
+ # stored in the array, so we use int because it correspond to np.intc.
+ # NB! An important side-effect of this is that if "tmp" overflows its
+ # datatype size, it will simply wrap around like in C, rather than raise
+ # an error like in Python.
+
+ cdef int tmp
+
+ # Py_ssize_t is the proper C type for Python array indices.
+ cdef Py_ssize_t x, y
+
+ for x in range(x_max):
+ for y in range(y_max):
+
+ tmp = clip(array_1[x, y], 2, 10)
+ tmp = tmp * a + array_2[x, y] * b
+ result[x, y] = tmp + c
+
+ return result
diff --git a/docs/examples/userguide/numpy_ufuncs/ufunc.py b/docs/examples/userguide/numpy_ufuncs/ufunc.py
new file mode 100644
index 000000000..874183c84
--- /dev/null
+++ b/docs/examples/userguide/numpy_ufuncs/ufunc.py
@@ -0,0 +1,8 @@
+# tag: numpy
+import cython
+
+@cython.ufunc
+@cython.cfunc
+def add_one(x: cython.double) -> cython.double:
+ # of course, this simple operation can already by done efficiently in Numpy!
+ return x+1
diff --git a/docs/examples/userguide/numpy_ufuncs/ufunc.pyx b/docs/examples/userguide/numpy_ufuncs/ufunc.pyx
new file mode 100644
index 000000000..b29c071e1
--- /dev/null
+++ b/docs/examples/userguide/numpy_ufuncs/ufunc.pyx
@@ -0,0 +1,8 @@
+# tag: numpy
+cimport cython
+
+
+@cython.ufunc
+cdef double add_one(double x):
+ # of course, this simple operation can already by done efficiently in Numpy!
+ return x+1
diff --git a/docs/examples/userguide/numpy_ufuncs/ufunc_ctuple.py b/docs/examples/userguide/numpy_ufuncs/ufunc_ctuple.py
new file mode 100644
index 000000000..b3f4fb6de
--- /dev/null
+++ b/docs/examples/userguide/numpy_ufuncs/ufunc_ctuple.py
@@ -0,0 +1,7 @@
+# tag: numpy
+import cython
+
+@cython.ufunc
+@cython.cfunc
+def add_one_add_two(x: cython.int) -> tuple[cython.int, cython.int]:
+ return x+1, x+2
diff --git a/docs/examples/userguide/numpy_ufuncs/ufunc_ctuple.pyx b/docs/examples/userguide/numpy_ufuncs/ufunc_ctuple.pyx
new file mode 100644
index 000000000..61127261c
--- /dev/null
+++ b/docs/examples/userguide/numpy_ufuncs/ufunc_ctuple.pyx
@@ -0,0 +1,7 @@
+# tag: numpy
+cimport cython
+
+
+@cython.ufunc
+cdef (int, int) add_one_add_two(int x):
+ return x+1, x+2
diff --git a/docs/examples/userguide/numpy_ufuncs/ufunc_fused.py b/docs/examples/userguide/numpy_ufuncs/ufunc_fused.py
new file mode 100644
index 000000000..01cc3bc57
--- /dev/null
+++ b/docs/examples/userguide/numpy_ufuncs/ufunc_fused.py
@@ -0,0 +1,7 @@
+# tag: numpy
+import cython
+
+@cython.ufunc
+@cython.cfunc
+def generic_add_one(x: cython.numeric) -> cython.numeric:
+ return x+1
diff --git a/docs/examples/userguide/numpy_ufuncs/ufunc_fused.pyx b/docs/examples/userguide/numpy_ufuncs/ufunc_fused.pyx
new file mode 100644
index 000000000..3baf58136
--- /dev/null
+++ b/docs/examples/userguide/numpy_ufuncs/ufunc_fused.pyx
@@ -0,0 +1,7 @@
+# tag: numpy
+cimport cython
+
+
+@cython.ufunc
+cdef cython.numeric generic_add_one(cython.numeric x):
+ return x+1
diff --git a/docs/examples/userguide/parallelism/breaking_loop.py b/docs/examples/userguide/parallelism/breaking_loop.py
new file mode 100644
index 000000000..00d0225b5
--- /dev/null
+++ b/docs/examples/userguide/parallelism/breaking_loop.py
@@ -0,0 +1,15 @@
+from cython.parallel import prange
+
+@cython.exceptval(-1)
+@cython.cfunc
+def func(n: cython.Py_ssize_t) -> cython.int:
+ i: cython.Py_ssize_t
+
+ for i in prange(n, nogil=True):
+ if i == 8:
+ with cython.gil:
+ raise Exception()
+ elif i == 4:
+ break
+ elif i == 2:
+ return i
diff --git a/docs/examples/userguide/parallelism/breaking_loop.pyx b/docs/examples/userguide/parallelism/breaking_loop.pyx
index d11b179d9..e7445082d 100644
--- a/docs/examples/userguide/parallelism/breaking_loop.pyx
+++ b/docs/examples/userguide/parallelism/breaking_loop.pyx
@@ -1,13 +1,15 @@
-from cython.parallel import prange
-
-cdef int func(Py_ssize_t n):
- cdef Py_ssize_t i
-
- for i in prange(n, nogil=True):
- if i == 8:
- with gil:
- raise Exception()
- elif i == 4:
- break
- elif i == 2:
- return i
+from cython.parallel import prange
+
+
+
+cdef int func(Py_ssize_t n) except -1:
+ cdef Py_ssize_t i
+
+ for i in prange(n, nogil=True):
+ if i == 8:
+ with gil:
+ raise Exception()
+ elif i == 4:
+ break
+ elif i == 2:
+ return i
diff --git a/docs/examples/userguide/parallelism/cimport_openmp.py b/docs/examples/userguide/parallelism/cimport_openmp.py
new file mode 100644
index 000000000..9288a4381
--- /dev/null
+++ b/docs/examples/userguide/parallelism/cimport_openmp.py
@@ -0,0 +1,11 @@
+# tag: openmp
+
+from cython.parallel import parallel
+from cython.cimports.openmp import omp_set_dynamic, omp_get_num_threads
+
+num_threads = cython.declare(cython.int)
+
+omp_set_dynamic(1)
+with cython.nogil, parallel():
+ num_threads = omp_get_num_threads()
+ # ...
diff --git a/docs/examples/userguide/parallelism/cimport_openmp.pyx b/docs/examples/userguide/parallelism/cimport_openmp.pyx
index 235ee10bc..54d5f18db 100644
--- a/docs/examples/userguide/parallelism/cimport_openmp.pyx
+++ b/docs/examples/userguide/parallelism/cimport_openmp.pyx
@@ -1,13 +1,11 @@
-# tag: openmp
-# You can ignore the previous line.
-# It's for internal testing of the Cython documentation.
-
-from cython.parallel cimport parallel
-cimport openmp
-
-cdef int num_threads
-
-openmp.omp_set_dynamic(1)
-with nogil, parallel():
- num_threads = openmp.omp_get_num_threads()
- # ...
+# tag: openmp
+
+from cython.parallel cimport parallel
+cimport openmp
+
+cdef int num_threads
+
+openmp.omp_set_dynamic(1)
+with nogil, parallel():
+ num_threads = openmp.omp_get_num_threads()
+ # ...
diff --git a/docs/examples/userguide/parallelism/memoryview_sum.py b/docs/examples/userguide/parallelism/memoryview_sum.py
new file mode 100644
index 000000000..6cff5d587
--- /dev/null
+++ b/docs/examples/userguide/parallelism/memoryview_sum.py
@@ -0,0 +1,7 @@
+from cython.parallel import prange
+
+def func(x: cython.double[:], alpha: cython.double):
+ i: cython.Py_ssize_t
+
+ for i in prange(x.shape[0], nogil=True):
+ x[i] = alpha * x[i]
diff --git a/docs/examples/userguide/parallelism/memoryview_sum.pyx b/docs/examples/userguide/parallelism/memoryview_sum.pyx
new file mode 100644
index 000000000..bdc1c9feb
--- /dev/null
+++ b/docs/examples/userguide/parallelism/memoryview_sum.pyx
@@ -0,0 +1,7 @@
+from cython.parallel import prange
+
+def func(double[:] x, double alpha):
+ cdef Py_ssize_t i
+
+ for i in prange(x.shape[0], nogil=True):
+ x[i] = alpha * x[i]
diff --git a/docs/examples/userguide/parallelism/parallel.py b/docs/examples/userguide/parallelism/parallel.py
new file mode 100644
index 000000000..0fb62d10f
--- /dev/null
+++ b/docs/examples/userguide/parallelism/parallel.py
@@ -0,0 +1,30 @@
+from cython.parallel import parallel, prange
+from cython.cimports.libc.stdlib import abort, malloc, free
+
+@cython.nogil
+@cython.cfunc
+def func(buf: cython.p_int) -> cython.void:
+ pass
+ # ...
+
+idx = cython.declare(cython.Py_ssize_t)
+i = cython.declare(cython.Py_ssize_t)
+j = cython.declare(cython.Py_ssize_t)
+n = cython.declare(cython.Py_ssize_t, 100)
+local_buf = cython.declare(p_int)
+size = cython.declare(cython.size_t, 10)
+
+with cython.nogil, parallel():
+ local_buf: cython.p_int = cython.cast(cython.p_int, malloc(cython.sizeof(cython.int) * size))
+ if local_buf is cython.NULL:
+ abort()
+
+ # populate our local buffer in a sequential loop
+ for i in range(size):
+ local_buf[i] = i * 2
+
+ # share the work using the thread-local buffer(s)
+ for j in prange(n, schedule='guided'):
+ func(local_buf)
+
+ free(local_buf)
diff --git a/docs/examples/userguide/parallelism/parallel.pyx b/docs/examples/userguide/parallelism/parallel.pyx
new file mode 100644
index 000000000..2a952d537
--- /dev/null
+++ b/docs/examples/userguide/parallelism/parallel.pyx
@@ -0,0 +1,30 @@
+from cython.parallel import parallel, prange
+from libc.stdlib cimport abort, malloc, free
+
+
+
+cdef void func(int *buf) nogil:
+ pass
+ # ...
+
+cdef Py_ssize_t idx, i, j, n = 100
+cdef int * local_buf
+cdef size_t size = 10
+
+
+
+
+with nogil, parallel():
+ local_buf = <int *> malloc(sizeof(int) * size)
+ if local_buf is NULL:
+ abort()
+
+ # populate our local buffer in a sequential loop
+ for i in range(size):
+ local_buf[i] = i * 2
+
+ # share the work using the thread-local buffer(s)
+ for j in prange(n, schedule='guided'):
+ func(local_buf)
+
+ free(local_buf)
diff --git a/docs/examples/userguide/parallelism/setup_py.py b/docs/examples/userguide/parallelism/setup_py.py
new file mode 100644
index 000000000..85a037dc5
--- /dev/null
+++ b/docs/examples/userguide/parallelism/setup_py.py
@@ -0,0 +1,16 @@
+from setuptools import Extension, setup
+from Cython.Build import cythonize
+
+ext_modules = [
+ Extension(
+ "hello",
+ ["hello.py"],
+ extra_compile_args=['-fopenmp'],
+ extra_link_args=['-fopenmp'],
+ )
+]
+
+setup(
+ name='hello-parallel-world',
+ ext_modules=cythonize(ext_modules),
+)
diff --git a/docs/examples/userguide/parallelism/setup.py b/docs/examples/userguide/parallelism/setup_pyx.py
index 0fb6026f7..fe6d0a64c 100644
--- a/docs/examples/userguide/parallelism/setup.py
+++ b/docs/examples/userguide/parallelism/setup_pyx.py
@@ -1,17 +1,16 @@
-from distutils.core import setup
-from distutils.extension import Extension
-from Cython.Build import cythonize
-
-ext_modules = [
- Extension(
- "hello",
- ["hello.pyx"],
- extra_compile_args=['-fopenmp'],
- extra_link_args=['-fopenmp'],
- )
-]
-
-setup(
- name='hello-parallel-world',
- ext_modules=cythonize(ext_modules),
-)
+from setuptools import Extension, setup
+from Cython.Build import cythonize
+
+ext_modules = [
+ Extension(
+ "hello",
+ ["hello.pyx"],
+ extra_compile_args=['-fopenmp'],
+ extra_link_args=['-fopenmp'],
+ )
+]
+
+setup(
+ name='hello-parallel-world',
+ ext_modules=cythonize(ext_modules),
+)
diff --git a/docs/examples/userguide/parallelism/simple_sum.py b/docs/examples/userguide/parallelism/simple_sum.py
new file mode 100644
index 000000000..f952a8556
--- /dev/null
+++ b/docs/examples/userguide/parallelism/simple_sum.py
@@ -0,0 +1,10 @@
+from cython.parallel import prange
+
+i = cython.declare(cython.int)
+n = cython.declare(cython.int, 30)
+sum = cython.declare(cython.int, 0)
+
+for i in prange(n, nogil=True):
+ sum += i
+
+print(sum)
diff --git a/docs/examples/userguide/parallelism/simple_sum.pyx b/docs/examples/userguide/parallelism/simple_sum.pyx
index 83b862ea6..929a988e5 100644
--- a/docs/examples/userguide/parallelism/simple_sum.pyx
+++ b/docs/examples/userguide/parallelism/simple_sum.pyx
@@ -1,10 +1,10 @@
-from cython.parallel import prange
-
-cdef int i
-cdef int n = 30
-cdef int sum = 0
-
-for i in prange(n, nogil=True):
- sum += i
-
-print(sum)
+from cython.parallel import prange
+
+cdef int i
+cdef int n = 30
+cdef int sum = 0
+
+for i in prange(n, nogil=True):
+ sum += i
+
+print(sum)
diff --git a/docs/examples/userguide/sharing_declarations/landscaping.py b/docs/examples/userguide/sharing_declarations/landscaping.py
new file mode 100644
index 000000000..2d2c4b5b7
--- /dev/null
+++ b/docs/examples/userguide/sharing_declarations/landscaping.py
@@ -0,0 +1,7 @@
+from cython.cimports.shrubbing import Shrubbery
+import shrubbing
+
+def main():
+ sh: Shrubbery
+ sh = shrubbing.standard_shrubbery()
+ print("Shrubbery size is", sh.width, 'x', sh.length)
diff --git a/docs/examples/userguide/sharing_declarations/landscaping.pyx b/docs/examples/userguide/sharing_declarations/landscaping.pyx
index c54e74fd0..afc999e53 100644
--- a/docs/examples/userguide/sharing_declarations/landscaping.pyx
+++ b/docs/examples/userguide/sharing_declarations/landscaping.pyx
@@ -1,7 +1,7 @@
-cimport shrubbing
-import shrubbing
-
-def main():
- cdef shrubbing.Shrubbery sh
- sh = shrubbing.standard_shrubbery()
- print("Shrubbery size is", sh.width, 'x', sh.length)
+cimport shrubbing
+import shrubbing
+
+def main():
+ cdef shrubbing.Shrubbery sh
+ sh = shrubbing.standard_shrubbery()
+ print("Shrubbery size is", sh.width, 'x', sh.length)
diff --git a/docs/examples/userguide/sharing_declarations/lunch.py b/docs/examples/userguide/sharing_declarations/lunch.py
new file mode 100644
index 000000000..df56913eb
--- /dev/null
+++ b/docs/examples/userguide/sharing_declarations/lunch.py
@@ -0,0 +1,5 @@
+import cython
+from cython.cimports.c_lunch import eject_tomato as c_eject_tomato
+
+def eject_tomato(speed: cython.float):
+ c_eject_tomato(speed)
diff --git a/docs/examples/userguide/sharing_declarations/lunch.pyx b/docs/examples/userguide/sharing_declarations/lunch.pyx
index 7bb2d4756..fea5e4c87 100644
--- a/docs/examples/userguide/sharing_declarations/lunch.pyx
+++ b/docs/examples/userguide/sharing_declarations/lunch.pyx
@@ -1,4 +1,5 @@
-cimport c_lunch
-
-def eject_tomato(float speed):
- c_lunch.eject_tomato(speed)
+
+cimport c_lunch
+
+def eject_tomato(float speed):
+ c_lunch.eject_tomato(speed)
diff --git a/docs/examples/userguide/sharing_declarations/restaurant.py b/docs/examples/userguide/sharing_declarations/restaurant.py
new file mode 100644
index 000000000..b4bdb2eba
--- /dev/null
+++ b/docs/examples/userguide/sharing_declarations/restaurant.py
@@ -0,0 +1,12 @@
+import cython
+from cython.cimports.dishes import spamdish, sausage
+
+@cython.cfunc
+def prepare(d: cython.pointer(spamdish)) -> cython.void:
+ d.oz_of_spam = 42
+ d.filler = sausage
+
+def serve():
+ d: spamdish
+ prepare(cython.address(d))
+ print(f'{d.oz_of_spam} oz spam, filler no. {d.filler}')
diff --git a/docs/examples/userguide/sharing_declarations/restaurant.pyx b/docs/examples/userguide/sharing_declarations/restaurant.pyx
index 0c1dbf5c0..f556646dc 100644
--- a/docs/examples/userguide/sharing_declarations/restaurant.pyx
+++ b/docs/examples/userguide/sharing_declarations/restaurant.pyx
@@ -1,12 +1,12 @@
-from __future__ import print_function
-cimport dishes
-from dishes cimport spamdish
-
-cdef void prepare(spamdish *d):
- d.oz_of_spam = 42
- d.filler = dishes.sausage
-
-def serve():
- cdef spamdish d
- prepare(&d)
- print(f'{d.oz_of_spam} oz spam, filler no. {d.filler}')
+
+cimport dishes
+from dishes cimport spamdish
+
+cdef void prepare(spamdish *d):
+ d.oz_of_spam = 42
+ d.filler = dishes.sausage
+
+def serve():
+ cdef spamdish d
+ prepare(&d)
+ print(f'{d.oz_of_spam} oz spam, filler no. {d.filler}')
diff --git a/docs/examples/userguide/sharing_declarations/setup_py.py b/docs/examples/userguide/sharing_declarations/setup_py.py
new file mode 100644
index 000000000..45ded0ff4
--- /dev/null
+++ b/docs/examples/userguide/sharing_declarations/setup_py.py
@@ -0,0 +1,4 @@
+from setuptools import setup
+from Cython.Build import cythonize
+
+setup(ext_modules=cythonize(["landscaping.py", "shrubbing.py"]))
diff --git a/docs/examples/userguide/sharing_declarations/setup.py b/docs/examples/userguide/sharing_declarations/setup_pyx.py
index 64804f97d..505b53e9d 100644
--- a/docs/examples/userguide/sharing_declarations/setup.py
+++ b/docs/examples/userguide/sharing_declarations/setup_pyx.py
@@ -1,4 +1,4 @@
-from distutils.core import setup
-from Cython.Build import cythonize
-
-setup(ext_modules=cythonize(["landscaping.pyx", "shrubbing.pyx"]))
+from setuptools import setup
+from Cython.Build import cythonize
+
+setup(ext_modules=cythonize(["landscaping.pyx", "shrubbing.pyx"]))
diff --git a/docs/examples/userguide/sharing_declarations/shrubbing.py b/docs/examples/userguide/sharing_declarations/shrubbing.py
new file mode 100644
index 000000000..27e20d631
--- /dev/null
+++ b/docs/examples/userguide/sharing_declarations/shrubbing.py
@@ -0,0 +1,10 @@
+import cython
+
+@cython.cclass
+class Shrubbery:
+ def __cinit__(self, w: cython.int, l: cython.int):
+ self.width = w
+ self.length = l
+
+def standard_shrubbery():
+ return Shrubbery(3, 7)
diff --git a/docs/examples/userguide/sharing_declarations/shrubbing.pyx b/docs/examples/userguide/sharing_declarations/shrubbing.pyx
index a8b70dae2..91235e5ec 100644
--- a/docs/examples/userguide/sharing_declarations/shrubbing.pyx
+++ b/docs/examples/userguide/sharing_declarations/shrubbing.pyx
@@ -1,7 +1,10 @@
-cdef class Shrubbery:
- def __cinit__(self, int w, int l):
- self.width = w
- self.length = l
-
-def standard_shrubbery():
- return Shrubbery(3, 7)
+
+
+
+cdef class Shrubbery:
+ def __init__(self, int w, int l):
+ self.width = w
+ self.length = l
+
+def standard_shrubbery():
+ return Shrubbery(3, 7)
diff --git a/docs/examples/userguide/sharing_declarations/spammery.py b/docs/examples/userguide/sharing_declarations/spammery.py
new file mode 100644
index 000000000..88554be4a
--- /dev/null
+++ b/docs/examples/userguide/sharing_declarations/spammery.py
@@ -0,0 +1,10 @@
+import cython
+from cython.cimports.volume import cube
+
+def menu(description, size):
+ print(description, ":", cube(size),
+ "cubic metres of spam")
+
+menu("Entree", 1)
+menu("Main course", 3)
+menu("Dessert", 2)
diff --git a/docs/examples/userguide/sharing_declarations/spammery.pyx b/docs/examples/userguide/sharing_declarations/spammery.pyx
index f65cf63d7..da11e737e 100644
--- a/docs/examples/userguide/sharing_declarations/spammery.pyx
+++ b/docs/examples/userguide/sharing_declarations/spammery.pyx
@@ -1,11 +1,10 @@
-from __future__ import print_function
-
-from volume cimport cube
-
-def menu(description, size):
- print(description, ":", cube(size),
- "cubic metres of spam")
-
-menu("Entree", 1)
-menu("Main course", 3)
-menu("Dessert", 2)
+
+from volume cimport cube
+
+def menu(description, size):
+ print(description, ":", cube(size),
+ "cubic metres of spam")
+
+menu("Entree", 1)
+menu("Main course", 3)
+menu("Dessert", 2)
diff --git a/docs/examples/userguide/sharing_declarations/volume.pxd b/docs/examples/userguide/sharing_declarations/volume.pxd
index 598efd922..a30c68e52 100644
--- a/docs/examples/userguide/sharing_declarations/volume.pxd
+++ b/docs/examples/userguide/sharing_declarations/volume.pxd
@@ -1 +1 @@
-cdef float cube(float)
+cdef float cube(float x)
diff --git a/docs/examples/userguide/sharing_declarations/volume.py b/docs/examples/userguide/sharing_declarations/volume.py
new file mode 100644
index 000000000..1f6ff9c72
--- /dev/null
+++ b/docs/examples/userguide/sharing_declarations/volume.py
@@ -0,0 +1,2 @@
+def cube(x):
+ return x * x * x
diff --git a/docs/examples/userguide/sharing_declarations/volume.pyx b/docs/examples/userguide/sharing_declarations/volume.pyx
index 0fbab6fb7..0476b6068 100644
--- a/docs/examples/userguide/sharing_declarations/volume.pyx
+++ b/docs/examples/userguide/sharing_declarations/volume.pyx
@@ -1,2 +1,2 @@
-cdef float cube(float x):
- return x * x * x
+cdef float cube(float x):
+ return x * x * x
diff --git a/docs/examples/userguide/special_methods/total_ordering.py b/docs/examples/userguide/special_methods/total_ordering.py
new file mode 100644
index 000000000..7d164d6df
--- /dev/null
+++ b/docs/examples/userguide/special_methods/total_ordering.py
@@ -0,0 +1,13 @@
+import cython
+@cython.total_ordering
+@cython.cclass
+class ExtGe:
+ x: cython.int
+
+ def __ge__(self, other):
+ if not isinstance(other, ExtGe):
+ return NotImplemented
+ return self.x >= cython.cast(ExtGe, other).x
+
+ def __eq__(self, other):
+ return isinstance(other, ExtGe) and self.x == cython.cast(ExtGe, other).x
diff --git a/docs/examples/userguide/special_methods/total_ordering.pyx b/docs/examples/userguide/special_methods/total_ordering.pyx
new file mode 100644
index 000000000..06d2ccef7
--- /dev/null
+++ b/docs/examples/userguide/special_methods/total_ordering.pyx
@@ -0,0 +1,13 @@
+import cython
+
+@cython.total_ordering
+cdef class ExtGe:
+ cdef int x
+
+ def __ge__(self, other):
+ if not isinstance(other, ExtGe):
+ return NotImplemented
+ return self.x >= (<ExtGe>other).x
+
+ def __eq__(self, other):
+ return isinstance(other, ExtGe) and self.x == (<ExtGe>other).x
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/Rectangle.pxd b/docs/examples/userguide/wrapping_CPlusPlus/Rectangle.pxd
index 68f949122..a26e69b51 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/Rectangle.pxd
+++ b/docs/examples/userguide/wrapping_CPlusPlus/Rectangle.pxd
@@ -1,7 +1,7 @@
cdef extern from "Rectangle.cpp":
pass
-# Decalre the class with cdef
+# Declare the class with cdef
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle() except +
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/cython_usage.pyx b/docs/examples/userguide/wrapping_CPlusPlus/cython_usage.pyx
index 24192bf96..d074fa5ab 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/cython_usage.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/cython_usage.pyx
@@ -1,12 +1,12 @@
-# distutils: language = c++
-
-from Rectangle cimport Rectangle
-
-def main():
- rec_ptr = new Rectangle(1, 2, 3, 4) # Instantiate a Rectangle object on the heap
- try:
- rec_area = rec_ptr.getArea()
- finally:
- del rec_ptr # delete heap allocated object
-
- cdef Rectangle rec_stack # Instantiate a Rectangle object on the stack
+# distutils: language = c++
+
+from Rectangle cimport Rectangle
+
+def main():
+ rec_ptr = new Rectangle(1, 2, 3, 4) # Instantiate a Rectangle object on the heap
+ try:
+ rec_area = rec_ptr.getArea()
+ finally:
+ del rec_ptr # delete heap allocated object
+
+ cdef Rectangle rec_stack # Instantiate a Rectangle object on the stack
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/function_templates.pyx b/docs/examples/userguide/wrapping_CPlusPlus/function_templates.pyx
index 13c75426e..35d064fdd 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/function_templates.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/function_templates.pyx
@@ -1,7 +1,7 @@
-# distutils: language = c++
-
-cdef extern from "<algorithm>" namespace "std":
- T max[T](T a, T b)
-
-print(max[long](3, 4))
-print(max(1.5, 2.5)) # simple template argument deduction
+# distutils: language = c++
+
+cdef extern from "<algorithm>" namespace "std":
+ T max[T](T a, T b)
+
+print(max[long](3, 4))
+print(max(1.5, 2.5)) # simple template argument deduction
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/iterate.pyx b/docs/examples/userguide/wrapping_CPlusPlus/iterate.pyx
index ea0007e6a..cdce8910f 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/iterate.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/iterate.pyx
@@ -1,12 +1,12 @@
-# distutils: language = c++
-
-from libcpp.vector cimport vector
-
-def main():
- cdef vector[int] v = [4, 6, 5, 10, 3]
-
- cdef int value
- for value in v:
- print(value)
-
- return [x*x for x in v if x % 2 == 0]
+# distutils: language = c++
+
+from libcpp.vector cimport vector
+
+def main():
+ cdef vector[int] v = [4, 6, 5, 10, 3]
+
+ cdef int value
+ for value in v:
+ print(value)
+
+ return [x*x for x in v if x % 2 == 0]
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/nested_class.pyx b/docs/examples/userguide/wrapping_CPlusPlus/nested_class.pyx
index e53f39b98..c5c764468 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/nested_class.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/nested_class.pyx
@@ -1,17 +1,17 @@
-# distutils: language = c++
-
-cdef extern from "<vector>" namespace "std":
- cdef cppclass vector[T]:
- cppclass iterator:
- T operator*()
- iterator operator++()
- bint operator==(iterator)
- bint operator!=(iterator)
- vector()
- void push_back(T&)
- T& operator[](int)
- T& at(int)
- iterator begin()
- iterator end()
-
-cdef vector[int].iterator iter #iter is declared as being of type vector<int>::iterator
+# distutils: language = c++
+
+cdef extern from "<vector>" namespace "std":
+ cdef cppclass vector[T]:
+ cppclass iterator:
+ T operator*()
+ iterator operator++()
+ bint operator==(iterator)
+ bint operator!=(iterator)
+ vector()
+ void push_back(T&)
+ T& operator[](int)
+ T& at(int)
+ iterator begin()
+ iterator end()
+
+cdef vector[int].iterator iter #iter is declared as being of type vector<int>::iterator
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/python_to_cpp.pyx b/docs/examples/userguide/wrapping_CPlusPlus/python_to_cpp.pyx
index 30bdb7bcb..b4be72c16 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/python_to_cpp.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/python_to_cpp.pyx
@@ -1,19 +1,19 @@
-# distutils: language = c++
-
-from libcpp.string cimport string
-from libcpp.vector cimport vector
-
-py_bytes_object = b'The knights who say ni'
-py_unicode_object = u'Those who hear them seldom live to tell the tale.'
-
-cdef string s = py_bytes_object
-print(s) # b'The knights who say ni'
-
-cdef string cpp_string = <string> py_unicode_object.encode('utf-8')
-print(cpp_string) # b'Those who hear them seldom live to tell the tale.'
-
-cdef vector[int] vect = range(1, 10, 2)
-print(vect) # [1, 3, 5, 7, 9]
-
-cdef vector[string] cpp_strings = b'It is a good shrubbery'.split()
-print(cpp_strings[1]) # b'is'
+# distutils: language = c++
+
+from libcpp.string cimport string
+from libcpp.vector cimport vector
+
+py_bytes_object = b'The knights who say ni'
+py_unicode_object = u'Those who hear them seldom live to tell the tale.'
+
+cdef string s = py_bytes_object
+print(s) # b'The knights who say ni'
+
+cdef string cpp_string = <string> py_unicode_object.encode('utf-8')
+print(cpp_string) # b'Those who hear them seldom live to tell the tale.'
+
+cdef vector[int] vect = range(1, 10, 2)
+print(vect) # [1, 3, 5, 7, 9]
+
+cdef vector[string] cpp_strings = b'It is a good shrubbery'.split()
+print(cpp_strings[1]) # b'is'
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/rect.pyx b/docs/examples/userguide/wrapping_CPlusPlus/rect.pyx
index e7c4423ef..d8eec16ef 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/rect.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/rect.pyx
@@ -8,7 +8,7 @@ from Rectangle cimport Rectangle
cdef class PyRectangle:
cdef Rectangle c_rect # Hold a C++ instance which we're wrapping
- def __cinit__(self, int x0, int y0, int x1, int y1):
+ def __init__(self, int x0, int y0, int x1, int y1):
self.c_rect = Rectangle(x0, y0, x1, y1)
def get_area(self):
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/rect_ptr.pyx b/docs/examples/userguide/wrapping_CPlusPlus/rect_ptr.pyx
index 508e55dc6..ec4b34ab4 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/rect_ptr.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/rect_ptr.pyx
@@ -1,12 +1,18 @@
-# distutils: language = c++
-
-from Rectangle cimport Rectangle
-
-cdef class PyRectangle:
- cdef Rectangle*c_rect # hold a pointer to the C++ instance which we're wrapping
-
- def __cinit__(self, int x0, int y0, int x1, int y1):
- self.c_rect = new Rectangle(x0, y0, x1, y1)
-
- def __dealloc__(self):
- del self.c_rect
+# distutils: language = c++
+
+from Rectangle cimport Rectangle
+
+cdef class PyRectangle:
+ cdef Rectangle*c_rect # hold a pointer to the C++ instance which we're wrapping
+
+ def __cinit__(self):
+ self.c_rect = new Rectangle()
+
+ def __init__(self, int x0, int y0, int x1, int y1):
+ self.c_rect.x0 = x0
+ self.c_rect.y0 = y0
+ self.c_rect.x1 = x1
+ self.c_rect.y1 = y1
+
+ def __dealloc__(self):
+ del self.c_rect
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/rect_with_attributes.pyx b/docs/examples/userguide/wrapping_CPlusPlus/rect_with_attributes.pyx
index 1bac30dec..441292ace 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/rect_with_attributes.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/rect_with_attributes.pyx
@@ -5,7 +5,7 @@ from Rectangle cimport Rectangle
cdef class PyRectangle:
cdef Rectangle c_rect
- def __cinit__(self, int x0, int y0, int x1, int y1):
+ def __init__(self, int x0, int y0, int x1, int y1):
self.c_rect = Rectangle(x0, y0, x1, y1)
def get_area(self):
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/setup.py b/docs/examples/userguide/wrapping_CPlusPlus/setup.py
index 0c89865d6..09009d28d 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/setup.py
+++ b/docs/examples/userguide/wrapping_CPlusPlus/setup.py
@@ -1,4 +1,4 @@
-from distutils.core import setup
+from setuptools import setup
from Cython.Build import cythonize
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/templates.pyx b/docs/examples/userguide/wrapping_CPlusPlus/templates.pyx
index 8e7383ca2..4ff232b82 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/templates.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/templates.pyx
@@ -1,30 +1,30 @@
-# distutils: language = c++
-
-# import dereference and increment operators
-from cython.operator cimport dereference as deref, preincrement as inc
-
-cdef extern from "<vector>" namespace "std":
- cdef cppclass vector[T]:
- cppclass iterator:
- T operator*()
- iterator operator++()
- bint operator==(iterator)
- bint operator!=(iterator)
- vector()
- void push_back(T&)
- T& operator[](int)
- T& at(int)
- iterator begin()
- iterator end()
-
-cdef vector[int] *v = new vector[int]()
-cdef int i
-for i in range(10):
- v.push_back(i)
-
-cdef vector[int].iterator it = v.begin()
-while it != v.end():
- print(deref(it))
- inc(it)
-
-del v
+# distutils: language = c++
+
+# import dereference and increment operators
+from cython.operator cimport dereference as deref, preincrement as inc
+
+cdef extern from "<vector>" namespace "std":
+ cdef cppclass vector[T]:
+ cppclass iterator:
+ T operator*()
+ iterator operator++()
+ bint operator==(iterator)
+ bint operator!=(iterator)
+ vector()
+ void push_back(T&)
+ T& operator[](int)
+ T& at(int)
+ iterator begin()
+ iterator end()
+
+cdef vector[int] *v = new vector[int]()
+cdef int i
+for i in range(10):
+ v.push_back(i)
+
+cdef vector[int].iterator it = v.begin()
+while it != v.end():
+ print(deref(it))
+ inc(it)
+
+del v
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/vector_demo.pyx b/docs/examples/userguide/wrapping_CPlusPlus/vector_demo.pyx
index d7fdfc969..f1697e1ec 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/vector_demo.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/vector_demo.pyx
@@ -1,15 +1,15 @@
-# distutils: language = c++
-
-from libcpp.vector cimport vector
-
-cdef vector[int] vect
-cdef int i, x
-
-for i in range(10):
- vect.push_back(i)
-
-for i in range(10):
- print(vect[i])
-
-for x in vect:
- print(x)
+# distutils: language = c++
+
+from libcpp.vector cimport vector
+
+cdef vector[int] vect
+cdef int i, x
+
+for i in range(10):
+ vect.push_back(i)
+
+for i in range(10):
+ print(vect[i])
+
+for x in vect:
+ print(x)
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/wrapper_vector.pyx b/docs/examples/userguide/wrapping_CPlusPlus/wrapper_vector.pyx
index 592e83ad9..4cdf12fc2 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/wrapper_vector.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/wrapper_vector.pyx
@@ -1,17 +1,17 @@
-# distutils: language = c++
-
-from libcpp.vector cimport vector
-
-
-cdef class VectorStack:
- cdef vector[int] v
-
- def push(self, x):
- self.v.push_back(x)
-
- def pop(self):
- if self.v.empty():
- raise IndexError()
- x = self.v.back()
- self.v.pop_back()
- return x
+# distutils: language = c++
+
+from libcpp.vector cimport vector
+
+
+cdef class VectorStack:
+ cdef vector[int] v
+
+ def push(self, x):
+ self.v.push_back(x)
+
+ def pop(self):
+ if self.v.empty():
+ raise IndexError()
+ x = self.v.back()
+ self.v.pop_back()
+ return x