Commit b9a2c953 authored by Mark Florisson's avatar Mark Florisson

Fix fused types delimiter, add pure-mode memoryview syntax like cython.double[:, :]

parent 29b22283
# cython.* namespace for pure mode.
# Shamelessly copied from Cython/minivect/minitypes.py
class _ArrayType(object):
is_array = True
subtypes = ['dtype']
def __init__(self, dtype, ndim, is_c_contig=False, is_f_contig=False,
inner_contig=False, broadcasting=None):
self.dtype = dtype
self.ndim = ndim
self.is_c_contig = is_c_contig
self.is_f_contig = is_f_contig
self.inner_contig = inner_contig or is_c_contig or is_f_contig
self.broadcasting = broadcasting
def __repr__(self):
axes = [":"] * self.ndim
if self.is_c_contig:
axes[-1] = "::1"
elif self.is_f_contig:
axes[0] = "::1"
return "%s[%s]" % (self.dtype, ", ".join(axes))
def index_type(base_type, item):
"""
Support array type creation by slicing, e.g. double[:, :] specifies
a 2D strided array of doubles. The syntax is the same as for
Cython memoryviews.
"""
assert isinstance(item, (tuple, slice))
def verify_slice(s):
if s.start or s.stop or s.step not in (None, 1):
raise minierror.InvalidTypeSpecification(
"Only a step of 1 may be provided to indicate C or "
"Fortran contiguity")
if isinstance(item, tuple):
step_idx = None
for idx, s in enumerate(item):
verify_slice(s)
if s.step and (step_idx or idx not in (0, len(item) - 1)):
raise minierror.InvalidTypeSpecification(
"Step may only be provided once, and only in the "
"first or last dimension.")
if s.step == 1:
step_idx = idx
return _ArrayType(base_type, len(item),
is_c_contig=step_idx == len(item) - 1,
is_f_contig=step_idx == 0)
else:
verify_slice(item)
return _ArrayType(base_type, 1, is_c_contig=bool(item.step))
# END shameless copy
compiled = False
_Unspecified = object()
......@@ -240,6 +300,8 @@ class typedef(CythonType):
def __repr__(self):
return self.name or str(self._basetype)
__getitem__ = index_type
class _FusedType(CythonType):
pass
......
......@@ -700,7 +700,7 @@ __pyx_FusedFunction_getitem(__pyx_FusedFunctionObject *self, PyObject *idx)
Py_DECREF(string);
}
sep = PyUnicode_FromString(", ");
sep = PyUnicode_FromString("|");
if (sep)
signature = PyUnicode_Join(sep, list);
__pyx_err:
......
......@@ -230,9 +230,10 @@ __signatures__
Finally, function objects from ``def`` or ``cpdef`` functions have an attribute
__signatures__, which maps the signature strings to the actual specialized
functions. This may be useful for inspection. Listed signature strings may also
be used as indices to the fused function::
be used as indices to the fused function, but the index format may change between
Cython versions::
specialized_function = fused_function["MyExtensionClass, int, float"]
specialized_function = fused_function["MyExtensionClass|int|float"]
It would usually be preferred to index like this, however::
......@@ -242,8 +243,7 @@ Although the latter will select the biggest types for ``int`` and ``float`` from
Python space, as they are not type identifiers but builtin types there. Passing
``cython.int`` and ``cython.float`` would resolve that, however.
For memoryview indexing from python space you have to use strings instead of
types::
For memoryview indexing from python space we can do the following:
ctypedef fused my_fused_type:
int[:, ::1]
......@@ -252,6 +252,6 @@ types::
def func(my_fused_type array):
...
my_fused_type['int[:, ::1]'](myarray)
my_fused_type[cython.int[:, ::1]](myarray)
The same goes for when using e.g. ``cython.numeric[:, :]``.
......@@ -48,7 +48,7 @@ def opt_func(fused_t obj, cython.floating myf = 1.2, cython.integral myi = 7):
>>> opt_func[str, float, int]("spam", f, i)
str object float int
spam 5.60 9 5.60 9
>>> opt_func["str, double, long"]("spam", f, i)
>>> opt_func[str, cy.double, long]("spam", f, i)
str object double long
spam 5.60 9 5.60 9
>>> opt_func[str, float, cy.int]("spam", f, i)
......@@ -62,7 +62,7 @@ def opt_func(fused_t obj, cython.floating myf = 1.2, cython.integral myi = 7):
>>> opt_func[ExtClassA, float, int](ExtClassA(), f, i)
ExtClassA float int
ExtClassA 5.60 9 5.60 9
>>> opt_func["ExtClassA, double, long"](ExtClassA(), f, i)
>>> opt_func[ExtClassA, cy.double, long](ExtClassA(), f, i)
ExtClassA double long
ExtClassA 5.60 9 5.60 9
......
......@@ -863,6 +863,13 @@ def test_dispatch_ndim(ndim_t array):
double[:, :] 2
>>> test_dispatch_ndim(np.empty((5, 5, 5), dtype=np.double))
double[:, :, :] 3
Test indexing using Cython.Shadow
>>> import cython
>>> test_dispatch_ndim[cython.double[:]](np.empty(5, dtype=np.double))
double[:] 1
>>> test_dispatch_ndim[cython.double[:, :]](np.empty((5, 5), dtype=np.double))
double[:, :] 2
"""
print cython.typeof(array), np.asarray(array).ndim
......
......@@ -201,7 +201,6 @@ def ae(result, expected):
assert result == expected
ae(a_mod.public_cpdef["int, float, list"](5, 6, [7]), ("int", "float", "list object"))
ae(a_mod.public_cpdef[int, float, list](5, 6, [7]), ("int", "float", "list object"))
idx = cy.typeof(0), cy.typeof(0.0), cy.typeof([])
......
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