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. # 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 compiled = False
_Unspecified = object() _Unspecified = object()
...@@ -240,6 +300,8 @@ class typedef(CythonType): ...@@ -240,6 +300,8 @@ class typedef(CythonType):
def __repr__(self): def __repr__(self):
return self.name or str(self._basetype) return self.name or str(self._basetype)
__getitem__ = index_type
class _FusedType(CythonType): class _FusedType(CythonType):
pass pass
......
...@@ -700,7 +700,7 @@ __pyx_FusedFunction_getitem(__pyx_FusedFunctionObject *self, PyObject *idx) ...@@ -700,7 +700,7 @@ __pyx_FusedFunction_getitem(__pyx_FusedFunctionObject *self, PyObject *idx)
Py_DECREF(string); Py_DECREF(string);
} }
sep = PyUnicode_FromString(", "); sep = PyUnicode_FromString("|");
if (sep) if (sep)
signature = PyUnicode_Join(sep, list); signature = PyUnicode_Join(sep, list);
__pyx_err: __pyx_err:
......
...@@ -230,9 +230,10 @@ __signatures__ ...@@ -230,9 +230,10 @@ __signatures__
Finally, function objects from ``def`` or ``cpdef`` functions have an attribute Finally, function objects from ``def`` or ``cpdef`` functions have an attribute
__signatures__, which maps the signature strings to the actual specialized __signatures__, which maps the signature strings to the actual specialized
functions. This may be useful for inspection. Listed signature strings may also 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:: 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 ...@@ -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 Python space, as they are not type identifiers but builtin types there. Passing
``cython.int`` and ``cython.float`` would resolve that, however. ``cython.int`` and ``cython.float`` would resolve that, however.
For memoryview indexing from python space you have to use strings instead of For memoryview indexing from python space we can do the following:
types::
ctypedef fused my_fused_type: ctypedef fused my_fused_type:
int[:, ::1] int[:, ::1]
...@@ -252,6 +252,6 @@ types:: ...@@ -252,6 +252,6 @@ types::
def func(my_fused_type array): 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[:, :]``. 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): ...@@ -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) >>> opt_func[str, float, int]("spam", f, i)
str object float int str object float int
spam 5.60 9 5.60 9 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 str object double long
spam 5.60 9 5.60 9 spam 5.60 9 5.60 9
>>> opt_func[str, float, cy.int]("spam", f, i) >>> 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): ...@@ -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) >>> opt_func[ExtClassA, float, int](ExtClassA(), f, i)
ExtClassA float int ExtClassA float int
ExtClassA 5.60 9 5.60 9 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 double long
ExtClassA 5.60 9 5.60 9 ExtClassA 5.60 9 5.60 9
......
...@@ -863,6 +863,13 @@ def test_dispatch_ndim(ndim_t array): ...@@ -863,6 +863,13 @@ def test_dispatch_ndim(ndim_t array):
double[:, :] 2 double[:, :] 2
>>> test_dispatch_ndim(np.empty((5, 5, 5), dtype=np.double)) >>> test_dispatch_ndim(np.empty((5, 5, 5), dtype=np.double))
double[:, :, :] 3 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 print cython.typeof(array), np.asarray(array).ndim
......
...@@ -201,7 +201,6 @@ def ae(result, expected): ...@@ -201,7 +201,6 @@ def ae(result, expected):
assert 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")) 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([]) 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