Commit b67e5567 authored by Stefan Behnel's avatar Stefan Behnel

Fix line endings.

parent e6a49ace
This example directory is organized like the ``Cython/docs/src/`` directory, This example directory is organized like the ``Cython/docs/src/`` directory,
with one directory per ``.rst`` file. All files in this directory are tested with one directory per ``.rst`` file. All files in this directory are tested
in the :file:`runtests.py` with the mode `compile`. in the :file:`runtests.py` with the mode `compile`.
def say_hello_to(name): def say_hello_to(name):
print("Hello %s!" % name) print("Hello %s!" % name)
from distutils.core import setup from distutils.core import setup
from Cython.Build import cythonize from Cython.Build import cythonize
setup(name='Hello world app', setup(name='Hello world app',
ext_modules=cythonize("hello.pyx")) ext_modules=cythonize("hello.pyx"))
cdef double f(double x) except? -2: cdef double f(double x) except? -2:
return x ** 2 - x return x ** 2 - x
def f(x): def f(x):
return x ** 2 - x return x ** 2 - x
def integrate_f(a, b, N): def integrate_f(a, b, N):
s = 0 s = 0
dx = (b - a) / N dx = (b - a) / N
for i in range(N): for i in range(N):
s += f(a + i * dx) s += f(a + i * dx)
return s * dx return s * dx
def f(double x): def f(double x):
return x ** 2 - x return x ** 2 - x
def integrate_f(double a, double b, int N): def integrate_f(double a, double b, int N):
cdef int i cdef int i
cdef double s, dx cdef double s, dx
s = 0 s = 0
dx = (b - a) / N dx = (b - a) / N
for i in range(N): for i in range(N):
s += f(a + i * dx) s += f(a + i * dx)
return s * dx return s * dx
from cpython cimport array from cpython cimport array
import array import array
cdef array.array int_array_template = array.array('i', []) cdef array.array int_array_template = array.array('i', [])
cdef array.array newarray cdef array.array newarray
# create an array with 3 elements with same type as template # create an array with 3 elements with same type as template
newarray = array.clone(int_array_template, 3, zero=False) newarray = array.clone(int_array_template, 3, zero=False)
from cpython cimport array from cpython cimport array
import array import array
cdef array.array a = array.array('i', [1, 2, 3]) cdef array.array a = array.array('i', [1, 2, 3])
cdef int[:] ca = a cdef int[:] ca = a
cdef int overhead(object a): cdef int overhead(object a):
cdef int[:] ca = a cdef int[:] ca = a
return ca[0] return ca[0]
cdef int no_overhead(int[:] ca): cdef int no_overhead(int[:] ca):
return ca[0] return ca[0]
print(overhead(a)) # new memory view will be constructed, overhead print(overhead(a)) # new memory view will be constructed, overhead
print(no_overhead(ca)) # ca is already a memory view, so no overhead print(no_overhead(ca)) # ca is already a memory view, so no overhead
from cpython cimport array from cpython cimport array
import array import array
cdef array.array a = array.array('i', [1, 2, 3]) cdef array.array a = array.array('i', [1, 2, 3])
cdef array.array b = array.array('i', [4, 5, 6]) cdef array.array b = array.array('i', [4, 5, 6])
# extend a with b, resize as needed # extend a with b, resize as needed
array.extend(a, b) array.extend(a, b)
# resize a, leaving just original three elements # resize a, leaving just original three elements
array.resize(a, len(a) - len(b)) array.resize(a, len(a) - len(b))
from cpython cimport array from cpython cimport array
import array import array
cdef array.array a = array.array('i', [1, 2, 3]) cdef array.array a = array.array('i', [1, 2, 3])
cdef int[:] ca = a cdef int[:] ca = a
print(ca[0]) print(ca[0])
from cpython cimport array from cpython cimport array
import array import array
cdef array.array a = array.array('i', [1, 2, 3]) cdef array.array a = array.array('i', [1, 2, 3])
# access underlying pointer: # access underlying pointer:
print(a.data.as_ints[0]) print(a.data.as_ints[0])
from libc.string cimport memset from libc.string cimport memset
memset(a.data.as_voidptr, 0, len(a) * sizeof(int)) memset(a.data.as_voidptr, 0, len(a) * sizeof(int))
from sin_of_square cimport Function, SinOfSquareFunction from sin_of_square cimport Function, SinOfSquareFunction
def integrate(Function f, double a, double b, int N): def integrate(Function f, double a, double b, int N):
cdef int i cdef int i
cdef double s, dx cdef double s, dx
if f is None: if f is None:
raise ValueError("f cannot be None") raise ValueError("f cannot be None")
s = 0 s = 0
dx = (b - a) / N dx = (b - a) / N
for i in range(N): for i in range(N):
s += f.evaluate(a + i * dx) s += f.evaluate(a + i * dx)
return s * dx return s * dx
print(integrate(SinOfSquareFunction(), 0, 1, 10000)) print(integrate(SinOfSquareFunction(), 0, 1, 10000))
class MathFunction(object): class MathFunction(object):
def __init__(self, name, operator): def __init__(self, name, operator):
self.name = name self.name = name
self.operator = operator self.operator = operator
def __call__(self, *operands): def __call__(self, *operands):
return self.operator(*operands) return self.operator(*operands)
cdef class Function: cdef class Function:
cpdef double evaluate(self, double x) except *: cpdef double evaluate(self, double x) except *:
return 0 return 0
# cython: nonecheck=True # cython: nonecheck=True
# ^^^ Turns on nonecheck globally # ^^^ Turns on nonecheck globally
import cython import cython
cdef class MyClass: cdef class MyClass:
pass pass
# Turn off nonecheck locally for the function # Turn off nonecheck locally for the function
@cython.nonecheck(False) @cython.nonecheck(False)
def func(): def func():
cdef MyClass obj = None cdef MyClass obj = None
try: try:
# Turn nonecheck on again for a block # Turn nonecheck on again for a block
with cython.nonecheck(True): with cython.nonecheck(True):
print(obj.myfunc()) # Raises exception print(obj.myfunc()) # Raises exception
except AttributeError: except AttributeError:
pass pass
print(obj.myfunc()) # Hope for a crash! print(obj.myfunc()) # Hope for a crash!
from libc.math cimport sin from libc.math cimport sin
cdef class Function: cdef class Function:
cpdef double evaluate(self, double x) except *: cpdef double evaluate(self, double x) except *:
return 0 return 0
cdef class SinOfSquareFunction(Function): cdef class SinOfSquareFunction(Function):
cpdef double evaluate(self, double x) except *: cpdef double evaluate(self, double x) except *:
return sin(x ** 2) return sin(x ** 2)
from sin_of_square cimport Function from sin_of_square cimport Function
cdef class WaveFunction(Function): cdef class WaveFunction(Function):
# Not available in Python-space: # Not available in Python-space:
cdef double offset cdef double offset
# Available in Python-space: # Available in Python-space:
cdef public double freq cdef public double freq
# Available in Python-space, but only for reading: # Available in Python-space, but only for reading:
cdef readonly double scale cdef readonly double scale
# Available in Python-space: # Available in Python-space:
@property @property
def period(self): def period(self):
return 1.0 / self.freq return 1.0 / self.freq
@period.setter @period.setter
def period(self, value): def period(self, value):
self.freq = 1.0 / value self.freq = 1.0 / value
# queue.pyx # queue.pyx
cimport cqueue cimport cqueue
cdef class Queue: cdef class Queue:
cdef cqueue.Queue* _c_queue cdef cqueue.Queue* _c_queue
def __cinit__(self): def __cinit__(self):
self._c_queue = cqueue.queue_new() self._c_queue = cqueue.queue_new()
# queue.pyx # queue.pyx
cimport cqueue cimport cqueue
cdef class Queue: cdef class Queue:
cdef cqueue.Queue* _c_queue cdef cqueue.Queue* _c_queue
def __cinit__(self): def __cinit__(self):
self._c_queue = cqueue.queue_new() self._c_queue = cqueue.queue_new()
if self._c_queue is NULL: if self._c_queue is NULL:
raise MemoryError() raise MemoryError()
from __future__ import print_function from __future__ import print_function
import time import time
import queue import queue
Q = queue.Queue() Q = queue.Queue()
Q.append(10) Q.append(10)
Q.append(20) Q.append(20)
print(Q.peek()) print(Q.peek())
print(Q.pop()) print(Q.pop())
print(Q.pop()) print(Q.pop())
try: try:
print(Q.pop()) print(Q.pop())
except IndexError as e: except IndexError as e:
print("Error message:", e) # Prints "Queue is empty" print("Error message:", e) # Prints "Queue is empty"
i = 10000 i = 10000
values = range(i) values = range(i)
start_time = time.time() start_time = time.time()
Q.extend(values) Q.extend(values)
end_time = time.time() - start_time end_time = time.time() - start_time
print("Adding {} items took {:1.3f} msecs.".format(i, 1000 * end_time)) print("Adding {} items took {:1.3f} msecs.".format(i, 1000 * end_time))
for i in range(41): for i in range(41):
Q.pop() Q.pop()
Q.pop() Q.pop()
print("The answer is:") print("The answer is:")
print(Q.pop()) print(Q.pop())
# distutils: language=c++ # distutils: language=c++
from libcpp.vector cimport vector from libcpp.vector cimport vector
def primes(unsigned int nb_primes): def primes(unsigned int nb_primes):
cdef int n, i cdef int n, i
cdef vector[int] p cdef vector[int] p
p.reserve(nb_primes) # allocate memory for 'nb_primes' elements. p.reserve(nb_primes) # allocate memory for 'nb_primes' elements.
n = 2 n = 2
while p.size() < nb_primes: # size() for vectors is similar to len() while p.size() < nb_primes: # size() for vectors is similar to len()
for i in p: for i in p:
if n % i == 0: if n % i == 0:
break break
else: else:
p.push_back(n) # push_back is similar to append() p.push_back(n) # push_back is similar to append()
n += 1 n += 1
# Vectors are automatically converted to Python # Vectors are automatically converted to Python
# lists when converted to Python objects. # lists when converted to Python objects.
return p return p
from libc.stdlib cimport atoi from libc.stdlib cimport atoi
cdef parse_charptr_to_py_int(char* s): cdef parse_charptr_to_py_int(char* s):
assert s is not NULL, "byte string value is NULL" assert s is not NULL, "byte string value is NULL"
return atoi(s) # note: atoi() has no error detection! return atoi(s) # note: atoi() has no error detection!
""" """
>>> sin(0) >>> sin(0)
0.0 0.0
""" """
cdef extern from "math.h": cdef extern from "math.h":
cpdef double sin(double x) cpdef double sin(double x)
cdef extern from "string.h": cdef extern from "string.h":
char* strstr(const char *haystack, const char *needle) char* strstr(const char *haystack, const char *needle)
cdef extern from "string.h": cdef extern from "string.h":
char* strstr(const char *haystack, const char *needle) char* strstr(const char *haystack, const char *needle)
cdef char* data = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh" cdef char* data = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh"
cdef char* pos = strstr(needle='akd', haystack=data) cdef char* pos = strstr(needle='akd', haystack=data)
print(pos is not NULL) print(pos is not NULL)
from libc.math cimport sin from libc.math cimport sin
cdef double f(double x): cdef double f(double x):
return sin(x * x) return sin(x * x)
from cpython.version cimport PY_VERSION_HEX from cpython.version cimport PY_VERSION_HEX
# Python version >= 3.2 final ? # Python version >= 3.2 final ?
print(PY_VERSION_HEX >= 0x030200F0) print(PY_VERSION_HEX >= 0x030200F0)
from distutils.core import setup from distutils.core import setup
from distutils.extension import Extension from distutils.extension import Extension
from Cython.Build import cythonize from Cython.Build import cythonize
ext_modules = [ ext_modules = [
Extension("demo", Extension("demo",
sources=["demo.pyx"], sources=["demo.pyx"],
libraries=["m"] # Unix-like specific libraries=["m"] # Unix-like specific
) )
] ]
setup(name="Demos", setup(name="Demos",
ext_modules=cythonize(ext_modules)) ext_modules=cythonize(ext_modules))
import random import random
from libc.stdlib cimport malloc, free from libc.stdlib cimport malloc, free
def random_noise(int number=1): def random_noise(int number=1):
cdef int i cdef int i
# allocate number * sizeof(double) bytes of memory # allocate number * sizeof(double) bytes of memory
cdef double *my_array = <double *> malloc(number * sizeof(double)) cdef double *my_array = <double *> malloc(number * sizeof(double))
if not my_array: if not my_array:
raise MemoryError() raise MemoryError()
try: try:
ran = random.normalvariate ran = random.normalvariate
for i in range(number): for i in range(number):
my_array[i] = ran(0, 1) my_array[i] = ran(0, 1)
# ... let's just assume we do some more heavy C calculations here to make up # ... let's just assume we do some more heavy C calculations here to make up
# for the work that it takes to pack the C double values into Python float # for the work that it takes to pack the C double values into Python float
# objects below, right after throwing away the existing objects above. # objects below, right after throwing away the existing objects above.
return [x for x in my_array[:number]] return [x for x in my_array[:number]]
finally: finally:
# return the previously allocated memory to the system # return the previously allocated memory to the system
free(my_array) free(my_array)
from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
cdef class SomeMemory: cdef class SomeMemory:
cdef double* data cdef double* data
def __cinit__(self, size_t number): def __cinit__(self, size_t number):
# allocate some memory (uninitialised, may contain arbitrary data) # allocate some memory (uninitialised, may contain arbitrary data)
self.data = <double*> PyMem_Malloc(number * sizeof(double)) self.data = <double*> PyMem_Malloc(number * sizeof(double))
if not self.data: if not self.data:
raise MemoryError() raise MemoryError()
def resize(self, size_t new_number): def resize(self, size_t new_number):
# Allocates new_number * sizeof(double) bytes, # Allocates new_number * sizeof(double) bytes,
# preserving the current content and making a best-effort to # preserving the current content and making a best-effort to
# re-use the original data location. # re-use the original data location.
mem = <double*> PyMem_Realloc(self.data, new_number * sizeof(double)) mem = <double*> PyMem_Realloc(self.data, new_number * sizeof(double))
if not mem: if not mem:
raise MemoryError() raise MemoryError()
# Only overwrite the pointer if the memory was really reallocated. # Only overwrite the pointer if the memory was really reallocated.
# On error (mem is NULL), the originally memory has not been freed. # On error (mem is NULL), the originally memory has not been freed.
self.data = mem self.data = mem
def __dealloc__(self): def __dealloc__(self):
PyMem_Free(self.data) # no-op if self.data is NULL PyMem_Free(self.data) # no-op if self.data is NULL
import numpy as np import numpy as np
def naive_convolve(f, g): def naive_convolve(f, g):
# f is an image and is indexed by (v, w) # f is an image and is indexed by (v, w)
# g is a filter kernel and is indexed by (s, t), # g is a filter kernel and is indexed by (s, t),
# it needs odd dimensions # it needs odd dimensions
# h is the output image and is indexed by (x, y), # h is the output image and is indexed by (x, y),
# it is not cropped # it is not cropped
if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1: if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1:
raise ValueError("Only odd dimensions on filter supported") raise ValueError("Only odd dimensions on filter supported")
# smid and tmid are number of pixels between the center pixel # smid and tmid are number of pixels between the center pixel
# and the edge, ie for a 5x5 filter they will be 2. # and the edge, ie for a 5x5 filter they will be 2.
# #
# The output size is calculated by adding smid, tmid to each # The output size is calculated by adding smid, tmid to each
# side of the dimensions of the input image. # side of the dimensions of the input image.
vmax = f.shape[0] vmax = f.shape[0]
wmax = f.shape[1] wmax = f.shape[1]
smax = g.shape[0] smax = g.shape[0]
tmax = g.shape[1] tmax = g.shape[1]
smid = smax // 2 smid = smax // 2
tmid = tmax // 2 tmid = tmax // 2
xmax = vmax + 2 * smid xmax = vmax + 2 * smid
ymax = wmax + 2 * tmid ymax = wmax + 2 * tmid
# Allocate result image. # Allocate result image.
h = np.zeros([xmax, ymax], dtype=f.dtype) h = np.zeros([xmax, ymax], dtype=f.dtype)
# Do convolution # Do convolution
for x in range(xmax): for x in range(xmax):
for y in range(ymax): for y in range(ymax):
# Calculate pixel value for h at (x,y). Sum one component # Calculate pixel value for h at (x,y). Sum one component
# for each pixel (s, t) of the filter g. # for each pixel (s, t) of the filter g.
s_from = max(smid - x, -smid) s_from = max(smid - x, -smid)
s_to = min((xmax - x) - smid, smid + 1) s_to = min((xmax - x) - smid, smid + 1)
t_from = max(tmid - y, -tmid) t_from = max(tmid - y, -tmid)
t_to = min((ymax - y) - tmid, tmid + 1) t_to = min((ymax - y) - tmid, tmid + 1)
value = 0 value = 0
for s in range(s_from, s_to): for s in range(s_from, s_to):
for t in range(t_from, t_to): for t in range(t_from, t_to):
v = x - smid + s v = x - smid + s
w = y - tmid + t w = y - tmid + t
value += g[smid - s, tmid - t] * f[v, w] value += g[smid - s, tmid - t] * f[v, w]
h[x, y] = value h[x, y] = value
return h return h
# calc_pi.py # calc_pi.py
def recip_square(i): def recip_square(i):
return 1. / i ** 2 return 1. / i ** 2
def approx_pi(n=10000000): def approx_pi(n=10000000):
val = 0. val = 0.
for k in range(1, n + 1): for k in range(1, n + 1):
val += recip_square(k) val += recip_square(k)
return (6 * val) ** .5 return (6 * val) ** .5
# cython: profile=True # cython: profile=True
# calc_pi.pyx # calc_pi.pyx
def recip_square(int i): def recip_square(int i):
return 1. / i ** 2 return 1. / i ** 2
def approx_pi(int n=10000000): def approx_pi(int n=10000000):
cdef double val = 0. cdef double val = 0.
cdef int k cdef int k
for k in range(1, n + 1): for k in range(1, n + 1):
val += recip_square(k) val += recip_square(k)
return (6 * val) ** .5 return (6 * val) ** .5
# cython: profile=True # cython: profile=True
# calc_pi.pyx # calc_pi.pyx
cdef inline double recip_square(int i): cdef inline double recip_square(int i):
return 1. / (i * i) return 1. / (i * i)
def approx_pi(int n=10000000): def approx_pi(int n=10000000):
cdef double val = 0. cdef double val = 0.
cdef int k cdef int k
for k in range(1, n + 1): for k in range(1, n + 1):
val += recip_square(k) val += recip_square(k)
return (6 * val) ** .5 return (6 * val) ** .5
# cython: profile=True # cython: profile=True
# calc_pi.pyx # calc_pi.pyx
cimport cython cimport cython
@cython.profile(False) @cython.profile(False)
cdef inline double recip_square(int i): cdef inline double recip_square(int i):
return 1. / (i * i) return 1. / (i * i)
def approx_pi(int n=10000000): def approx_pi(int n=10000000):
cdef double val = 0. cdef double val = 0.
cdef int k cdef int k
for k in range(1, n + 1): for k in range(1, n + 1):
val += recip_square(k) val += recip_square(k)
return (6 * val) ** .5 return (6 * val) ** .5
cimport cython cimport cython
@cython.profile(False) @cython.profile(False)
def my_often_called_function(): def my_often_called_function():
pass pass
# profile.py # profile.py
import pstats, cProfile import pstats, cProfile
import calc_pi import calc_pi
cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof") cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
s = pstats.Stats("Profile.prof") s = pstats.Stats("Profile.prof")
s.strip_dirs().sort_stats("time").print_stats() s.strip_dirs().sort_stats("time").print_stats()
# profile.py # profile.py
import pstats, cProfile import pstats, cProfile
import pyximport import pyximport
pyximport.install() pyximport.install()
import calc_pi import calc_pi
cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof") cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
s = pstats.Stats("Profile.prof") s = pstats.Stats("Profile.prof")
s.strip_dirs().sort_stats("time").print_stats() s.strip_dirs().sort_stats("time").print_stats()
def myfunction(x, y=2): def myfunction(x, y=2):
a = x - y a = x - y
return a + x * y return a + x * y
def _helper(a): def _helper(a):
return a + 1 return a + 1
class A: class A:
def __init__(self, b=0): def __init__(self, b=0):
self.a = 3 self.a = 3
self.b = b self.b = b
def foo(self, x): def foo(self, x):
print(x + _helper(1.0)) print(x + _helper(1.0))
cpdef int myfunction(int x, int y=2): cpdef int myfunction(int x, int y=2):
a = x - y a = x - y
return a + x * y return a + x * y
cdef double _helper(double a): cdef double _helper(double a):
return a + 1 return a + 1
cdef class A: cdef class A:
cdef public int a, b cdef public int a, b
def __init__(self, b=0): def __init__(self, b=0):
self.a = 3 self.a = 3
self.b = b self.b = b
cpdef foo(self, double x): cpdef foo(self, double x):
print(x + _helper(1.0)) print(x + _helper(1.0))
import cython import cython
def func(foo: dict, bar: cython.int) -> tuple: def func(foo: dict, bar: cython.int) -> tuple:
foo["hello world"] = 3 + bar foo["hello world"] = 3 + bar
return foo, 5 return foo, 5
import cython import cython
@cython.locals(counts=cython.int[10], digit=cython.int) @cython.locals(counts=cython.int[10], digit=cython.int)
def count_digits(digits): def count_digits(digits):
""" """
>>> digits = '01112222333334445667788899' >>> digits = '01112222333334445667788899'
>>> count_digits(map(int, digits)) >>> count_digits(map(int, digits))
[1, 3, 4, 5, 3, 1, 2, 2, 3, 2] [1, 3, 4, 5, 3, 1, 2, 2, 3, 2]
""" """
counts = [0] * 10 counts = [0] * 10
for digit in digits: for digit in digits:
assert 0 <= digit <= 9 assert 0 <= digit <= 9
counts[digit] += 1 counts[digit] += 1
return counts return counts
import cython import cython
@cython.cclass @cython.cclass
class A: class A:
cython.declare(a=cython.int, b=cython.int) cython.declare(a=cython.int, b=cython.int)
c = cython.declare(cython.int, visibility='public') c = cython.declare(cython.int, visibility='public')
d = cython.declare(cython.int) # private by default. d = cython.declare(cython.int) # private by default.
e = cython.declare(cython.int, visibility='readonly') e = cython.declare(cython.int, visibility='readonly')
def __init__(self, a, b, c, d=5, e=3): def __init__(self, a, b, c, d=5, e=3):
self.a = a self.a = a
self.b = b self.b = b
self.c = c self.c = c
self.d = d self.d = d
self.e = e self.e = e
import cython import cython
if cython.compiled: if cython.compiled:
print("Yep, I'm compiled.") print("Yep, I'm compiled.")
else: else:
print("Just a lowly interpreted script.") print("Just a lowly interpreted script.")
import cython import cython
x = cython.declare(cython.int) # cdef int x x = cython.declare(cython.int) # cdef int x
y = cython.declare(cython.double, 0.57721) # cdef double y = 0.57721 y = cython.declare(cython.double, 0.57721) # cdef double y = 0.57721
import cython import cython
cython.declare(x=cython.int, y=cython.double) # cdef int x; cdef double y cython.declare(x=cython.int, y=cython.double) # cdef int x; cdef double y
def dostuff(n): def dostuff(n):
t = 0 t = 0
for i in range(n): for i in range(n):
t += i t += i
return t return t
import cython import cython
@cython.exceptval(-1) @cython.exceptval(-1)
def func(x: cython.int) -> cython.int: def func(x: cython.int) -> cython.int:
if x < 0: if x < 0:
raise ValueError("need integer >= 0") raise ValueError("need integer >= 0")
return x + 1 return x + 1
import cython import cython
@cython.locals(a=cython.long, b=cython.long, n=cython.longlong) @cython.locals(a=cython.long, b=cython.long, n=cython.longlong)
def foo(a, b, x, y): def foo(a, b, x, y):
n = a * b n = a * b
# ... # ...
# mymodule.py # mymodule.py
import cython import cython
# override with Python import if not in compiled code # override with Python import if not in compiled code
if not cython.compiled: if not cython.compiled:
from math import sin from math import sin
# calls sin() from math.h when compiled with Cython and math.sin() in Python # calls sin() from math.h when compiled with Cython and math.sin() in Python
print(sin(0)) print(sin(0))
import cython import cython
def func(): def func():
# Cython types are evaluated as for cdef declarations # Cython types are evaluated as for cdef declarations
x: cython.int # cdef int x x: cython.int # cdef int x
y: cython.double = 0.57721 # cdef double y = 0.57721 y: cython.double = 0.57721 # cdef double y = 0.57721
z: cython.float = 0.57721 # cdef float z = 0.57721 z: cython.float = 0.57721 # cdef float z = 0.57721
# Python types shadow Cython types for compatibility reasons # Python types shadow Cython types for compatibility reasons
a: float = 0.54321 # cdef double a = 0.54321 a: float = 0.54321 # cdef double a = 0.54321
b: int = 5 # cdef object b = 5 b: int = 5 # cdef object b = 5
c: long = 6 # cdef object c = 6 c: long = 6 # cdef object c = 6
pass pass
@cython.cclass @cython.cclass
class A: class A:
a: cython.int a: cython.int
b: cython.int b: cython.int
def __init__(self, b=0): def __init__(self, b=0):
self.a = 3 self.a = 3
self.b = b self.b = b
from to_unicode cimport _text from to_unicode cimport _text
def api_func(s): def api_func(s):
text_input = _text(s) text_input = _text(s)
# ... # ...
def process_byte_data(unsigned char[:] data): def process_byte_data(unsigned char[:] data):
length = data.shape[0] length = data.shape[0]
first_byte = data[0] first_byte = data[0]
slice_view = data[1:-1] slice_view = data[1:-1]
# ... # ...
# cython: c_string_type=unicode, c_string_encoding=utf8 # cython: c_string_type=unicode, c_string_encoding=utf8
cdef char* c_string = 'abcdefg' cdef char* c_string = 'abcdefg'
# implicit decoding: # implicit decoding:
cdef object py_unicode_object = c_string cdef object py_unicode_object = c_string
# explicit conversion to Python bytes: # explicit conversion to Python bytes:
py_bytes_object = <bytes>c_string py_bytes_object = <bytes>c_string
# cython: c_string_type=str, c_string_encoding=ascii # cython: c_string_type=str, c_string_encoding=ascii
cdef char* c_string = 'abcdefg' cdef char* c_string = 'abcdefg'
# implicit decoding in Py3, bytes conversion in Py2: # implicit decoding in Py3, bytes conversion in Py2:
cdef object py_str_object = c_string cdef object py_str_object = c_string
# explicit conversion to Python bytes: # explicit conversion to Python bytes:
py_bytes_object = <bytes>c_string py_bytes_object = <bytes>c_string
# explicit conversion to Python unicode: # explicit conversion to Python unicode:
py_bytes_object = <unicode>c_string py_bytes_object = <unicode>c_string
# cython: c_string_type=unicode, c_string_encoding=ascii # cython: c_string_type=unicode, c_string_encoding=ascii
def func(): def func():
ustring = u'abc' ustring = u'abc'
cdef char* s = ustring cdef char* s = ustring
return s[0] # returns u'a' return s[0] # returns u'a'
from libc.stdlib cimport malloc from libc.stdlib cimport malloc
from libc.string cimport strcpy, strlen from libc.string cimport strcpy, strlen
cdef char* hello_world = 'hello world' cdef char* hello_world = 'hello world'
cdef Py_ssize_t n = strlen(hello_world) cdef Py_ssize_t n = strlen(hello_world)
cdef char* c_call_returning_a_c_string(): cdef char* c_call_returning_a_c_string():
cdef char* c_string = <char *> malloc((n + 1) * sizeof(char)) cdef char* c_string = <char *> malloc((n + 1) * sizeof(char))
if not c_string: if not c_string:
raise MemoryError() raise MemoryError()
strcpy(c_string, hello_world) strcpy(c_string, hello_world)
return c_string return c_string
cdef void get_a_c_string(char** c_string_ptr, Py_ssize_t *length): cdef void get_a_c_string(char** c_string_ptr, Py_ssize_t *length):
c_string_ptr[0] = <char *> malloc((n + 1) * sizeof(char)) c_string_ptr[0] = <char *> malloc((n + 1) * sizeof(char))
if not c_string_ptr[0]: if not c_string_ptr[0]:
raise MemoryError() raise MemoryError()
strcpy(c_string_ptr[0], hello_world) strcpy(c_string_ptr[0], hello_world)
length[0] = n length[0] = n
cdef extern from "someheader.h": cdef extern from "someheader.h":
ctypedef const char specialChar ctypedef const char specialChar
int process_string(const char* s) int process_string(const char* s)
const unsigned char* look_up_cached_string(const unsigned char* key) const unsigned char* look_up_cached_string(const unsigned char* key)
# distutils: language = c++ # distutils: language = c++
from libcpp.string cimport string from libcpp.string cimport string
def get_bytes(): def get_bytes():
py_bytes_object = b'hello world' py_bytes_object = b'hello world'
cdef string s = py_bytes_object cdef string s = py_bytes_object
s.append('abc') s.append('abc')
py_bytes_object = s py_bytes_object = s
return py_bytes_object return py_bytes_object
from c_func cimport get_a_c_string from c_func cimport get_a_c_string
cdef char* c_string = NULL cdef char* c_string = NULL
cdef Py_ssize_t length = 0 cdef Py_ssize_t length = 0
# get pointer and length from a C function # get pointer and length from a C function
get_a_c_string(&c_string, &length) get_a_c_string(&c_string, &length)
ustring = c_string[:length].decode('UTF-8') ustring = c_string[:length].decode('UTF-8')
# distutils: language = c++ # distutils: language = c++
from libcpp.string cimport string from libcpp.string cimport string
def get_ustrings(): def get_ustrings():
cdef string s = string(b'abcdefg') cdef string s = string(b'abcdefg')
ustring1 = s.decode('UTF-8') ustring1 = s.decode('UTF-8')
ustring2 = s[2:-2].decode('UTF-8') ustring2 = s[2:-2].decode('UTF-8')
return ustring1, ustring2 return ustring1, ustring2
cdef bytes bytes_string = b"hello to A bytes' world" cdef bytes bytes_string = b"hello to A bytes' world"
cdef char c cdef char c
for c in bytes_string: for c in bytes_string:
if c == 'A': if c == 'A':
print("Found the letter A") print("Found the letter A")
cdef char* c_string = "Hello to A C-string's world" cdef char* c_string = "Hello to A C-string's world"
cdef char c cdef char c
for c in c_string[:11]: for c in c_string[:11]:
if c == 'A': if c == 'A':
print("Found the letter A") print("Found the letter A")
cdef unicode ustring = u'Hello world' cdef unicode ustring = u'Hello world'
# NOTE: no typing required for 'uchar' ! # NOTE: no typing required for 'uchar' !
for uchar in ustring: for uchar in ustring:
if uchar == u'A': if uchar == u'A':
print("Found the letter A") print("Found the letter A")
cpdef void is_in(Py_UCS4 uchar_val): cpdef void is_in(Py_UCS4 uchar_val):
if uchar_val in u'abcABCxY': if uchar_val in u'abcABCxY':
print("The character is in the string.") print("The character is in the string.")
else: else:
print("The character is not in the string") print("The character is not in the string")
from c_func cimport c_call_returning_a_c_string from c_func cimport c_call_returning_a_c_string
cdef char* some_c_string = c_call_returning_a_c_string() cdef char* some_c_string = c_call_returning_a_c_string()
ustring = some_c_string.decode('UTF-8') ustring = some_c_string.decode('UTF-8')
def process_byte_data(unsigned char[:] data): def process_byte_data(unsigned char[:] data):
# ... process the data, here, dummy processing. # ... process the data, here, dummy processing.
cdef bint return_all = (data[0] == 108) cdef bint return_all = (data[0] == 108)
if return_all: if return_all:
return bytes(data) return bytes(data)
else: else:
# example for returning a slice # example for returning a slice
return bytes(data[5:7]) return bytes(data[5:7])
from libc.stdlib cimport free from libc.stdlib cimport free
from c_func cimport get_a_c_string from c_func cimport get_a_c_string
def main(): def main():
cdef char* c_string = NULL cdef char* c_string = NULL
cdef Py_ssize_t length = 0 cdef Py_ssize_t length = 0
# get pointer and length from a C function # get pointer and length from a C function
get_a_c_string(&c_string, &length) get_a_c_string(&c_string, &length)
try: try:
py_bytes_string = c_string[:length] # Performs a copy of the data py_bytes_string = c_string[:length] # Performs a copy of the data
finally: finally:
free(c_string) free(c_string)
# define a global name for whatever char type is used in the module # define a global name for whatever char type is used in the module
ctypedef unsigned char char_type ctypedef unsigned char char_type
cdef char_type[:] _chars(s): cdef char_type[:] _chars(s):
if isinstance(s, unicode): if isinstance(s, unicode):
# encode to the specific encoding used inside of the module # encode to the specific encoding used inside of the module
s = (<unicode>s).encode('utf8') s = (<unicode>s).encode('utf8')
return s return s
# to_unicode.pyx # to_unicode.pyx
from cpython.version cimport PY_MAJOR_VERSION from cpython.version cimport PY_MAJOR_VERSION
cdef unicode _text(s): cdef unicode _text(s):
if type(s) is unicode: if type(s) is unicode:
# Fast path for most common case(s). # Fast path for most common case(s).
return <unicode>s return <unicode>s
elif PY_MAJOR_VERSION < 3 and isinstance(s, bytes): elif PY_MAJOR_VERSION < 3 and isinstance(s, bytes):
# Only accept byte strings as text input in Python 2.x, not in Py3. # Only accept byte strings as text input in Python 2.x, not in Py3.
return (<bytes>s).decode('ascii') return (<bytes>s).decode('ascii')
elif isinstance(s, unicode): elif isinstance(s, unicode):
# We know from the fast path above that 's' can only be a subtype here. # We know from the fast path above that 's' can only be a subtype here.
# An evil cast to <unicode> might still work in some(!) cases, # An evil cast to <unicode> might still work in some(!) cases,
# depending on what the further processing does. To be safe, # depending on what the further processing does. To be safe,
# we can always create a copy instead. # we can always create a copy instead.
return unicode(s) return unicode(s)
else: else:
raise TypeError("Could not convert to unicode.") raise TypeError("Could not convert to unicode.")
from libc.stdlib cimport free from libc.stdlib cimport free
from c_func cimport c_call_returning_a_c_string from c_func cimport c_call_returning_a_c_string
cdef bytes py_string cdef bytes py_string
cdef char* c_string = c_call_returning_a_c_string() cdef char* c_string = c_call_returning_a_c_string()
try: try:
py_string = c_string py_string = c_string
finally: finally:
free(c_string) free(c_string)
from libc.stdlib cimport free from libc.stdlib cimport free
cdef unicode tounicode(char* s): cdef unicode tounicode(char* s):
return s.decode('UTF-8', 'strict') return s.decode('UTF-8', 'strict')
cdef unicode tounicode_with_length( cdef unicode tounicode_with_length(
char* s, size_t length): char* s, size_t length):
return s[:length].decode('UTF-8', 'strict') return s[:length].decode('UTF-8', 'strict')
cdef unicode tounicode_with_length_and_free( cdef unicode tounicode_with_length_and_free(
char* s, size_t length): char* s, size_t length):
try: try:
return s[:length].decode('UTF-8', 'strict') return s[:length].decode('UTF-8', 'strict')
finally: finally:
free(s) free(s)
\ No newline at end of file
# distutils: language = c++ # distutils: language = c++
# matrix.pyx # matrix.pyx
from libcpp.vector cimport vector from libcpp.vector cimport vector
cdef class Matrix: cdef class Matrix:
cdef unsigned ncols cdef unsigned ncols
cdef vector[float] v cdef vector[float] v
def __cinit__(self, unsigned ncols): def __cinit__(self, unsigned ncols):
self.ncols = ncols self.ncols = ncols
def add_row(self): def add_row(self):
"""Adds a row, initially zero-filled.""" """Adds a row, initially zero-filled."""
self.v.resize(self.v.size() + self.ncols) self.v.resize(self.v.size() + self.ncols)
# distutils: language = c++ # distutils: language = c++
from cpython cimport Py_buffer from cpython cimport Py_buffer
from libcpp.vector cimport vector from libcpp.vector cimport vector
cdef class Matrix: cdef class Matrix:
cdef Py_ssize_t ncols cdef Py_ssize_t ncols
cdef Py_ssize_t shape[2] cdef Py_ssize_t shape[2]
cdef Py_ssize_t strides[2] cdef Py_ssize_t strides[2]
cdef vector[float] v cdef vector[float] v
def __cinit__(self, Py_ssize_t ncols): def __cinit__(self, Py_ssize_t ncols):
self.ncols = ncols self.ncols = ncols
def add_row(self): def add_row(self):
"""Adds a row, initially zero-filled.""" """Adds a row, initially zero-filled."""
self.v.resize(self.v.size() + self.ncols) self.v.resize(self.v.size() + self.ncols)
def __getbuffer__(self, Py_buffer *buffer, int flags): def __getbuffer__(self, Py_buffer *buffer, int flags):
cdef Py_ssize_t itemsize = sizeof(self.v[0]) cdef Py_ssize_t itemsize = sizeof(self.v[0])
self.shape[0] = self.v.size() / self.ncols self.shape[0] = self.v.size() / self.ncols
self.shape[1] = self.ncols self.shape[1] = self.ncols
# Stride 1 is the distance, in bytes, between two items in a row; # Stride 1 is the distance, in bytes, between two items in a row;
# this is the distance between two adjacent items in the vector. # this is the distance between two adjacent items in the vector.
# Stride 0 is the distance between the first elements of adjacent rows. # Stride 0 is the distance between the first elements of adjacent rows.
self.strides[1] = <Py_ssize_t>( <char *>&(self.v[1]) self.strides[1] = <Py_ssize_t>( <char *>&(self.v[1])
- <char *>&(self.v[0])) - <char *>&(self.v[0]))
self.strides[0] = self.ncols * self.strides[1] self.strides[0] = self.ncols * self.strides[1]
buffer.buf = <char *>&(self.v[0]) buffer.buf = <char *>&(self.v[0])
buffer.format = 'f' # float buffer.format = 'f' # float
buffer.internal = NULL # see References buffer.internal = NULL # see References
buffer.itemsize = itemsize buffer.itemsize = itemsize
buffer.len = self.v.size() * itemsize # product(shape) * itemsize buffer.len = self.v.size() * itemsize # product(shape) * itemsize
buffer.ndim = 2 buffer.ndim = 2
buffer.obj = self buffer.obj = self
buffer.readonly = 0 buffer.readonly = 0
buffer.shape = self.shape buffer.shape = self.shape
buffer.strides = self.strides buffer.strides = self.strides
buffer.suboffsets = NULL # for pointer arrays only buffer.suboffsets = NULL # for pointer arrays only
def __releasebuffer__(self, Py_buffer *buffer): def __releasebuffer__(self, Py_buffer *buffer):
pass pass
# distutils: language = c++ # distutils: language = c++
from cpython cimport Py_buffer from cpython cimport Py_buffer
from libcpp.vector cimport vector from libcpp.vector cimport vector
cdef class Matrix: cdef class Matrix:
cdef int view_count cdef int view_count
cdef Py_ssize_t ncols cdef Py_ssize_t ncols
cdef vector[float] v cdef vector[float] v
# ... # ...
def __cinit__(self, Py_ssize_t ncols): def __cinit__(self, Py_ssize_t ncols):
self.ncols = ncols self.ncols = ncols
self.view_count = 0 self.view_count = 0
def add_row(self): def add_row(self):
if self.view_count > 0: if self.view_count > 0:
raise ValueError("can't add row while being viewed") raise ValueError("can't add row while being viewed")
self.v.resize(self.v.size() + self.ncols) self.v.resize(self.v.size() + self.ncols)
def __getbuffer__(self, Py_buffer *buffer, int flags): def __getbuffer__(self, Py_buffer *buffer, int flags):
# ... as before # ... as before
self.view_count += 1 self.view_count += 1
def __releasebuffer__(self, Py_buffer *buffer): def __releasebuffer__(self, Py_buffer *buffer):
self.view_count -= 1 self.view_count -= 1
\ No newline at end of file
cdef class Rectangle: cdef class Rectangle:
cdef int x0, y0 cdef int x0, y0
cdef int x1, y1 cdef int x1, y1
def __init__(self, int x0, int y0, int x1, int y1): def __init__(self, int x0, int y0, int x1, int y1):
self.x0 = x0 self.x0 = x0
self.y0 = y0 self.y0 = y0
self.x1 = x1 self.x1 = x1
self.y1 = y1 self.y1 = y1
def area(self): def area(self):
area = (self.x1 - self.x0) * (self.y1 - self.y0) area = (self.x1 - self.x0) * (self.y1 - self.y0)
if area < 0: if area < 0:
area = -area area = -area
return area return area
def rectArea(x0, y0, x1, y1): def rectArea(x0, y0, x1, y1):
rect = Rectangle(x0, y0, x1, y1) rect = Rectangle(x0, y0, x1, y1)
return rect.area() return rect.area()
cdef class Rectangle: cdef class Rectangle:
cdef int x0, y0 cdef int x0, y0
cdef int x1, y1 cdef int x1, y1
def __init__(self, int x0, int y0, int x1, int y1): def __init__(self, int x0, int y0, int x1, int y1):
self.x0 = x0 self.x0 = x0
self.y0 = y0 self.y0 = y0
self.x1 = x1 self.x1 = x1
self.y1 = y1 self.y1 = y1
cdef int _area(self): cdef int _area(self):
area = (self.x1 - self.x0) * (self.y1 - self.y0) area = (self.x1 - self.x0) * (self.y1 - self.y0)
if area < 0: if area < 0:
area = -area area = -area
return area return area
def area(self): def area(self):
return self._area() return self._area()
def rectArea(x0, y0, x1, y1): def rectArea(x0, y0, x1, y1):
cdef Rectangle rect = Rectangle(x0, y0, x1, y1) cdef Rectangle rect = Rectangle(x0, y0, x1, y1)
return rect._area() return rect._area()
cdef class Rectangle: cdef class Rectangle:
cdef int x0, y0 cdef int x0, y0
cdef int x1, y1 cdef int x1, y1
def __init__(self, int x0, int y0, int x1, int y1): def __init__(self, int x0, int y0, int x1, int y1):
self.x0 = x0 self.x0 = x0
self.y0 = y0 self.y0 = y0
self.x1 = x1 self.x1 = x1
self.y1 = y1 self.y1 = y1
cpdef int area(self): cpdef int area(self):
area = (self.x1 - self.x0) * (self.y1 - self.y0) area = (self.x1 - self.x0) * (self.y1 - self.y0)
if area < 0: if area < 0:
area = -area area = -area
return area return area
def rectArea(x0, y0, x1, y1): def rectArea(x0, y0, x1, y1):
cdef Rectangle rect = Rectangle(x0, y0, x1, y1) cdef Rectangle rect = Rectangle(x0, y0, x1, y1)
return rect.area() return rect.area()
cdef class Animal: cdef class Animal:
cdef int number_of_legs cdef int number_of_legs
cdef dict __dict__ cdef dict __dict__
def __cinit__(self, int number_of_legs): def __cinit__(self, int number_of_legs):
self.number_of_legs = number_of_legs self.number_of_legs = number_of_legs
dog = Animal(4) dog = Animal(4)
dog.has_tail = True dog.has_tail = True
cdef class Animal: cdef class Animal:
cdef int number_of_legs cdef int number_of_legs
def __cinit__(self, int number_of_legs): def __cinit__(self, int number_of_legs):
self.number_of_legs = number_of_legs self.number_of_legs = number_of_legs
class ExtendableAnimal(Animal): # Note that we use class, not cdef class class ExtendableAnimal(Animal): # Note that we use class, not cdef class
pass pass
dog = ExtendableAnimal(4) dog = ExtendableAnimal(4)
dog.has_tail = True dog.has_tail = True
\ No newline at end of file
from __future__ import print_function from __future__ import print_function
cdef class Shrubbery: cdef class Shrubbery:
def __init__(self, w, h): def __init__(self, w, h):
self.width = w self.width = w
self.height = h self.height = h
def describe(self): def describe(self):
print("This shrubbery is", self.width, print("This shrubbery is", self.width,
"by", self.height, "cubits.") "by", self.height, "cubits.")
cdef class Shrubbery: cdef class Shrubbery:
cdef public int width, height cdef public int width, height
cdef readonly float depth cdef readonly float depth
from __future__ import print_function from __future__ import print_function
cdef class Shrubbery: cdef class Shrubbery:
cdef int width, height cdef int width, height
def __init__(self, w, h): def __init__(self, w, h):
self.width = w self.width = w
self.height = h self.height = h
def describe(self): def describe(self):
print("This shrubbery is", self.width, print("This shrubbery is", self.width,
"by", self.height, "cubits.") "by", self.height, "cubits.")
from my_module cimport Shrubbery from my_module cimport Shrubbery
cdef Shrubbery another_shrubbery(Shrubbery sh1): cdef Shrubbery another_shrubbery(Shrubbery sh1):
cdef Shrubbery sh2 cdef Shrubbery sh2
sh2 = Shrubbery() sh2 = Shrubbery()
sh2.width = sh1.width sh2.width = sh1.width
sh2.height = sh1.height sh2.height = sh1.height
return sh2 return sh2
from my_module cimport Shrubbery from my_module cimport Shrubbery
cdef widen_shrubbery(Shrubbery sh, extra_width): cdef widen_shrubbery(Shrubbery sh, extra_width):
sh.width = sh.width + extra_width sh.width = sh.width + extra_width
cdef extern from *: cdef extern from *:
""" """
/* This is C code which will be put /* This is C code which will be put
* in the .c file output by Cython */ * in the .c file output by Cython */
static long square(long x) {return x * x;} static long square(long x) {return x * x;}
#define assign(x, y) ((x) = (y)) #define assign(x, y) ((x) = (y))
""" """
long square(long x) long square(long x)
void assign(long& x, long y) void assign(long& x, long y)
# delorean.pyx # delorean.pyx
cdef public struct Vehicle: cdef public struct Vehicle:
int speed int speed
float power float power
cdef api void activate(Vehicle *v): cdef api void activate(Vehicle *v):
if v.speed >= 88 and v.power >= 1.21: if v.speed >= 88 and v.power >= 1.21:
print("Time travel achieved") print("Time travel achieved")
\ No newline at end of file
from __future__ import print_function from __future__ import print_function
ctypedef fused char_or_float: ctypedef fused char_or_float:
char char
float float
cpdef char_or_float plus_one(char_or_float var): cpdef char_or_float plus_one(char_or_float var):
return var + 1 return var + 1
def show_me(): def show_me():
cdef: cdef:
char a = 127 char a = 127
float b = 127 float b = 127
print('char', plus_one(a)) print('char', plus_one(a))
print('float', plus_one(b)) print('float', plus_one(b))
from cpython.ref cimport PyObject from cpython.ref cimport PyObject
cdef extern from *: cdef extern from *:
ctypedef Py_ssize_t Py_intptr_t ctypedef Py_ssize_t Py_intptr_t
python_string = "foo" python_string = "foo"
cdef void* ptr = <void*>python_string cdef void* ptr = <void*>python_string
cdef Py_intptr_t adress_in_c = <Py_intptr_t>ptr cdef Py_intptr_t adress_in_c = <Py_intptr_t>ptr
address_from_void = adress_in_c # address_from_void is a python int address_from_void = adress_in_c # address_from_void is a python int
cdef PyObject* ptr2 = <PyObject*>python_string cdef PyObject* ptr2 = <PyObject*>python_string
cdef Py_intptr_t address_in_c2 = <Py_intptr_t>ptr2 cdef Py_intptr_t address_in_c2 = <Py_intptr_t>ptr2
address_from_PyObject = address_in_c2 # address_from_PyObject is a python int address_from_PyObject = address_in_c2 # address_from_PyObject is a python int
assert address_from_void == address_from_PyObject == id(python_string) assert address_from_void == address_from_PyObject == id(python_string)
print(<object>ptr) # Prints "foo" print(<object>ptr) # Prints "foo"
print(<object>ptr2) # prints "foo" print(<object>ptr2) # prints "foo"
from __future__ import print_function from __future__ import print_function
cdef: cdef:
struct Spam: struct Spam:
int tons int tons
int i int i
float a float a
Spam *p Spam *p
void f(Spam *s): void f(Spam *s):
print(s.tons, "Tons of spam") print(s.tons, "Tons of spam")
from __future__ import print_function from __future__ import print_function
DEF FavouriteFood = u"spam" DEF FavouriteFood = u"spam"
DEF ArraySize = 42 DEF ArraySize = 42
DEF OtherArraySize = 2 * ArraySize + 17 DEF OtherArraySize = 2 * ArraySize + 17
cdef int a1[ArraySize] cdef int a1[ArraySize]
cdef int a2[OtherArraySize] cdef int a2[OtherArraySize]
print("I like", FavouriteFood) print("I like", FavouriteFood)
\ No newline at end of file
def f(a, b, *args, c, d = 42, e, **kwds): def f(a, b, *args, c, d = 42, e, **kwds):
... ...
# We cannot call f with less verbosity than this. # We cannot call f with less verbosity than this.
foo = f(4, "bar", c=68, e=1.0) foo = f(4, "bar", c=68, e=1.0)
def g(a, b, *, c, d): def g(a, b, *, c, d):
... ...
# We cannot call g with less verbosity than this. # We cannot call g with less verbosity than this.
foo = g(4.0, "something", c=68, d="other") foo = g(4.0, "something", c=68, d="other")
from libc.stdio cimport FILE, fopen from libc.stdio cimport FILE, fopen
from libc.stdlib cimport malloc, free from libc.stdlib cimport malloc, free
from cpython.exc cimport PyErr_SetFromErrnoWithFilenameObject from cpython.exc cimport PyErr_SetFromErrnoWithFilenameObject
def open_file(): def open_file():
cdef FILE* p cdef FILE* p
p = fopen("spam.txt", "r") p = fopen("spam.txt", "r")
if p is NULL: if p is NULL:
PyErr_SetFromErrnoWithFilenameObject(OSError, "spam.txt") PyErr_SetFromErrnoWithFilenameObject(OSError, "spam.txt")
... ...
def allocating_memory(number=10): def allocating_memory(number=10):
cdef double *my_array = <double *> malloc(number * sizeof(double)) cdef double *my_array = <double *> malloc(number * sizeof(double))
if not my_array: # same as 'is NULL' above if not my_array: # same as 'is NULL' above
raise MemoryError() raise MemoryError()
... ...
free(my_array) free(my_array)
from __future__ import print_function from __future__ import print_function
cdef class A: cdef class A:
cdef foo(self): cdef foo(self):
print("A") print("A")
cdef class B(A): cdef class B(A):
cdef foo(self, x=None): cdef foo(self, x=None):
print("B", x) print("B", x)
cdef class C(B): cdef class C(B):
cpdef foo(self, x=True, int k=3): cpdef foo(self, x=True, int k=3):
print("C", x, k) print("C", x, k)
from __future__ import print_function from __future__ import print_function
cdef class A: cdef class A:
cdef foo(self): cdef foo(self):
print("A") print("A")
cdef class B(A): cdef class B(A):
cpdef foo(self): cpdef foo(self):
print("B") print("B")
class C(B): # NOTE: not cdef class class C(B): # NOTE: not cdef class
def foo(self): def foo(self):
print("C") print("C")
cdef struct Grail: cdef struct Grail:
int age int age
float volume float volume
cdef union Food: cdef union Food:
char *spam char *spam
float *eggs float *eggs
cdef enum CheeseType: cdef enum CheeseType:
cheddar, edam, cheddar, edam,
camembert camembert
cdef enum CheeseState: cdef enum CheeseState:
hard = 1 hard = 1
soft = 2 soft = 2
runny = 3 runny = 3
import numpy as np import numpy as np
def add_one(int[:,:] buf): def add_one(int[:,:] buf):
for x in range(buf.shape[0]): for x in range(buf.shape[0]):
for y in range(buf.shape[1]): for y in range(buf.shape[1]):
buf[x, y] += 1 buf[x, y] += 1
# exporting_object must be a Python object # exporting_object must be a Python object
# implementing the buffer interface, e.g. a numpy array. # implementing the buffer interface, e.g. a numpy array.
exporting_object = np.zeros((10, 20), dtype=np.intc) exporting_object = np.zeros((10, 20), dtype=np.intc)
add_one(exporting_object) add_one(exporting_object)
import numpy as np import numpy as np
cdef int[:, :, :] to_view, from_view cdef int[:, :, :] to_view, from_view
to_view = np.empty((20, 15, 30), dtype=np.intc) to_view = np.empty((20, 15, 30), dtype=np.intc)
from_view = np.ones((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 # copy the elements in from_view to to_view
to_view[...] = from_view to_view[...] = from_view
# or # or
to_view[:] = from_view to_view[:] = from_view
# or # or
to_view[:, :, :] = from_view to_view[:, :, :] = from_view
from cython cimport view from cython cimport view
# direct access in both dimensions, strided in the first dimension, contiguous in the last # direct access in both dimensions, strided in the first dimension, contiguous in the last
cdef int[:, ::view.contiguous] a cdef int[:, ::view.contiguous] a
# contiguous list of pointers to contiguous lists of ints # contiguous list of pointers to contiguous lists of ints
cdef int[::view.indirect_contiguous, ::1] b cdef int[::view.indirect_contiguous, ::1] b
# direct or indirect in the first dimension, direct in the second dimension # direct or indirect in the first dimension, direct in the second dimension
# strided in both dimensions # strided in both dimensions
cdef int[::view.generic, :] c cdef int[::view.generic, :] c
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment