Commit 107fc454 authored by Stefan Behnel's avatar Stefan Behnel

Merge branch 'master' into release

parents e2d55c56 c4c9683e
...@@ -79,7 +79,7 @@ Bugs fixed ...@@ -79,7 +79,7 @@ Bugs fixed
* The exception handling in generators and coroutines under CPython 3.7 was adapted * The exception handling in generators and coroutines under CPython 3.7 was adapted
to the newly introduced exception stack. Users of Cython 0.28 who want to support to the newly introduced exception stack. Users of Cython 0.28 who want to support
Python 3.7 are encouraged to upgrade to 0.29 to avoid potentially incorrect error Python 3.7 are encouraged to upgrade to 0.29 to avoid potentially incorrect error
reporting and tracebacks. reporting and tracebacks. (Github issue #1958)
* Crash when importing a module under Stackless Python that was built for CPython. * Crash when importing a module under Stackless Python that was built for CPython.
Patch by Anselm Kruis. (Github issue #2534) Patch by Anselm Kruis. (Github issue #2534)
......
# tag: numpy # tag: numpy_old
# You can ignore the previous line. # You can ignore the previous line.
# It's for internal testing of the cython documentation. # It's for internal testing of the cython documentation.
import numpy as np import numpy as np
# "cimport" is used to import special compile-time information # "cimport" is used to import special compile-time information
# about the numpy module (this is stored in a file numpy.pxd which is # about the numpy module (this is stored in a file numpy.pxd which is
# currently part of the Cython distribution). # currently part of the Cython distribution).
cimport numpy as np cimport numpy as np
# We now need to fix a datatype for our arrays. I've used the variable # 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 # DTYPE for this, which is assigned to the usual NumPy runtime
# type info object. # type info object.
DTYPE = np.int DTYPE = np.int
# "ctypedef" assigns a corresponding compile-time type to DTYPE_t. For # "ctypedef" assigns a corresponding compile-time type to DTYPE_t. For
# every type in the numpy module there's a corresponding compile-time # every type in the numpy module there's a corresponding compile-time
# type with a _t-suffix. # type with a _t-suffix.
ctypedef np.int_t DTYPE_t ctypedef np.int_t DTYPE_t
# "def" can type its arguments but not have a return type. The type of the # "def" can type its arguments but not have a return type. The type of the
# arguments for a "def" function is checked at run-time when entering the # arguments for a "def" function is checked at run-time when entering the
# function. # function.
# #
# The arrays f, g and h is typed as "np.ndarray" instances. The only effect # The arrays f, g and h is typed as "np.ndarray" instances. The only effect
# this has is to a) insert checks that the function arguments really are # this has is to a) insert checks that the function arguments really are
# NumPy arrays, and b) make some attribute access like f.shape[0] much # NumPy arrays, and b) make some attribute access like f.shape[0] much
# more efficient. (In this example this doesn't matter though.) # more efficient. (In this example this doesn't matter though.)
def naive_convolve(np.ndarray f, np.ndarray g): def naive_convolve(np.ndarray f, np.ndarray g):
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")
assert f.dtype == DTYPE and g.dtype == DTYPE assert f.dtype == DTYPE and g.dtype == DTYPE
# The "cdef" keyword is also used within functions to type variables. It # 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 # 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 # problems with allowing them in other places, though we'd love to see
# good and thought out proposals for it). # good and thought out proposals for it).
# #
# For the indices, the "int" type is used. This corresponds to a C int, # For the indices, the "int" type is used. This corresponds to a C int,
# other C types (like "unsigned int") could have been used instead. # other C types (like "unsigned int") could have been used instead.
# Purists could use "Py_ssize_t" which is the proper Python type for # Purists could use "Py_ssize_t" which is the proper Python type for
# array indices. # array indices.
cdef int vmax = f.shape[0] cdef int vmax = f.shape[0]
cdef int wmax = f.shape[1] cdef int wmax = f.shape[1]
cdef int smax = g.shape[0] cdef int smax = g.shape[0]
cdef int tmax = g.shape[1] cdef int tmax = g.shape[1]
cdef int smid = smax // 2 cdef int smid = smax // 2
cdef int tmid = tmax // 2 cdef int tmid = tmax // 2
cdef int xmax = vmax + 2 * smid cdef int xmax = vmax + 2 * smid
cdef int ymax = wmax + 2 * tmid cdef int ymax = wmax + 2 * tmid
cdef np.ndarray h = np.zeros([xmax, ymax], dtype=DTYPE) cdef np.ndarray h = np.zeros([xmax, ymax], dtype=DTYPE)
cdef int x, y, s, t, v, w cdef int x, y, s, t, v, w
# It is very important to type ALL your variables. You do not get any # 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 # warnings if not, only much slower code (they are implicitly typed as
# Python objects). # Python objects).
cdef int s_from, s_to, t_from, t_to cdef int s_from, s_to, t_from, t_to
# For the value variable, we want to use the same data type as is # For the value variable, we want to use the same data type as is
# stored in the array, so we use "DTYPE_t" as defined above. # stored in the array, so we use "DTYPE_t" as defined above.
# NB! An important side-effect of this is that if "value" overflows its # NB! An important side-effect of this is that if "value" overflows its
# datatype size, it will simply wrap around like in C, rather than raise # datatype size, it will simply wrap around like in C, rather than raise
# an error like in Python. # an error like in Python.
cdef DTYPE_t value cdef DTYPE_t value
for x in range(xmax): for x in range(xmax):
for y in range(ymax): for y in range(ymax):
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
...@@ -134,7 +134,8 @@ def get_distutils_distro(_cache=[]): ...@@ -134,7 +134,8 @@ def get_distutils_distro(_cache=[]):
EXT_DEP_MODULES = { EXT_DEP_MODULES = {
'tag:numpy': 'numpy', 'tag:numpy': 'numpy',
'tag:numpy_old': 'numpy',
'tag:pythran': 'pythran', 'tag:pythran': 'pythran',
'tag:setuptools': 'setuptools.sandbox', 'tag:setuptools': 'setuptools.sandbox',
'tag:asyncio': 'asyncio', 'tag:asyncio': 'asyncio',
...@@ -254,12 +255,19 @@ def update_linetrace_extension(ext): ...@@ -254,12 +255,19 @@ def update_linetrace_extension(ext):
return ext return ext
def update_numpy_extension(ext): def update_old_numpy_extension(ext):
update_numpy_extension(ext, set_api17_macro=False)
def update_numpy_extension(ext, set_api17_macro=True):
import numpy import numpy
from numpy.distutils.misc_util import get_info from numpy.distutils.misc_util import get_info
ext.include_dirs.append(numpy.get_include()) ext.include_dirs.append(numpy.get_include())
if set_api17_macro:
ext.define_macros.append(('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION'))
# We need the npymath library for numpy.math. # We need the npymath library for numpy.math.
# This is typically a static-only library. # This is typically a static-only library.
for attr, value in get_info('npymath').items(): for attr, value in get_info('npymath').items():
...@@ -391,6 +399,7 @@ EXCLUDE_EXT = object() ...@@ -391,6 +399,7 @@ EXCLUDE_EXT = object()
EXT_EXTRAS = { EXT_EXTRAS = {
'tag:numpy' : update_numpy_extension, 'tag:numpy' : update_numpy_extension,
'tag:numpy_old' : update_old_numpy_extension,
'tag:openmp': update_openmp_extension, 'tag:openmp': update_openmp_extension,
'tag:cpp11': update_cpp11_extension, 'tag:cpp11': update_cpp11_extension,
'tag:trace' : update_linetrace_extension, 'tag:trace' : update_linetrace_extension,
......
# ticket: 155 # ticket: 155
# tag: numpy # tag: numpy_old
""" """
>>> myfunc() >>> myfunc()
......
# tag: numpy # tag: numpy_old
# tag: openmp # tag: openmp
cimport cython cimport cython
......
# tag: numpy # tag: numpy_old
cimport numpy as np cimport numpy as np
cimport cython cimport cython
......
# tag: numpy # tag: numpy_old
# cannot be named "numpy" in order to not clash with the numpy module! # cannot be named "numpy" in order to not clash with the numpy module!
cimport numpy as np cimport numpy as np
......
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