1 # cython.* namespace for pure mode.
5 # BEGIN shameless copy from Cython/minivect/minitypes.py
7 class _ArrayType(object):
12 def __init__(self
, dtype
, ndim
, is_c_contig
=False, is_f_contig
=False,
13 inner_contig
=False, broadcasting
=None):
16 self
.is_c_contig
= is_c_contig
17 self
.is_f_contig
= is_f_contig
18 self
.inner_contig
= inner_contig
or is_c_contig
or is_f_contig
19 self
.broadcasting
= broadcasting
22 axes
= [":"] * self
.ndim
25 elif self
.is_f_contig
:
28 return "%s[%s]" % (self
.dtype
, ", ".join(axes
))
31 def index_type(base_type
, item
):
33 Support array type creation by slicing, e.g. double[:, :] specifies
34 a 2D strided array of doubles. The syntax is the same as for
37 assert isinstance(item
, (tuple, slice))
39 class InvalidTypeSpecification(Exception):
43 if s
.start
or s
.stop
or s
.step
not in (None, 1):
44 raise InvalidTypeSpecification(
45 "Only a step of 1 may be provided to indicate C or "
48 if isinstance(item
, tuple):
50 for idx
, s
in enumerate(item
):
52 if s
.step
and (step_idx
or idx
not in (0, len(item
) - 1)):
53 raise InvalidTypeSpecification(
54 "Step may only be provided once, and only in the "
55 "first or last dimension.")
60 return _ArrayType(base_type
, len(item
),
61 is_c_contig
=step_idx
== len(item
) - 1,
62 is_f_contig
=step_idx
== 0)
65 return _ArrayType(base_type
, 1, is_c_contig
=bool(item
.step
))
72 _Unspecified
= object()
76 def _empty_decorator(x
):
79 def locals(**arg_types
):
80 return _empty_decorator
82 def test_assert_path_exists(*paths
):
83 return _empty_decorator
85 def test_fail_if_path_exists(*paths
):
86 return _empty_decorator
88 class _EmptyDecoratorAndManager(object):
89 def __call__(self
, x
):
93 def __exit__(self
, exc_type
, exc_value
, traceback
):
96 cclass
= ccall
= cfunc
= _EmptyDecoratorAndManager()
98 returns
= lambda type_arg
: _EmptyDecoratorAndManager()
100 final
= internal
= type_version_tag
= no_gc_clear
= _empty_decorator
102 def inline(f
, *args
, **kwds
):
103 if isinstance(f
, basestring
):
104 from Cython
.Build
.Inline
import cython_inline
105 return cython_inline(f
, *args
, **kwds
)
107 assert len(args
) == len(kwds
) == 0
111 from Cython
.Build
.Inline
import RuntimeCompiledFunction
112 return RuntimeCompiledFunction(f
)
128 # Emulated language constructs
130 def cast(type, *args
):
131 if hasattr(type, '__call__'):
140 return arg
.__class
__.__name
__
144 return pointer(type(arg
))([arg
])
146 def declare(type=None, value
=_Unspecified
, **kwds
):
147 if type not in (None, object) and hasattr(type, '__call__'):
148 if value
is not _Unspecified
:
155 class _nogil(object):
156 """Support for 'with nogil' statement
160 def __exit__(self
, exc_class
, exc
, tb
):
161 return exc_class
is None
169 class CythonMetaType(type):
171 def __getitem__(type, ix
):
172 return array(type, ix
)
174 CythonTypeObject
= CythonMetaType('CythonTypeObject', (object,), {})
176 class CythonType(CythonTypeObject
):
178 def _pointer(self
, n
=1):
183 class PointerType(CythonType
):
185 def __init__(self
, value
=None):
186 if isinstance(value
, (ArrayType
, PointerType
)):
187 self
._items
= [cast(self
._basetype
, a
) for a
in value
._items
]
188 elif isinstance(value
, list):
189 self
._items
= [cast(self
._basetype
, a
) for a
in value
]
190 elif value
is None or value
== 0:
195 def __getitem__(self
, ix
):
197 raise IndexError("negative indexing not allowed in C")
198 return self
._items
[ix
]
200 def __setitem__(self
, ix
, value
):
202 raise IndexError("negative indexing not allowed in C")
203 self
._items
[ix
] = cast(self
._basetype
, value
)
205 def __eq__(self
, value
):
206 if value
is None and not self
._items
:
208 elif type(self
) != type(value
):
211 return not self
._items
and not value
._items
214 return "%s *" % (self
._basetype
,)
216 class ArrayType(PointerType
):
219 self
._items
= [None] * self
._n
222 class StructType(CythonType
):
224 def __init__(self
, cast_from
=_Unspecified
, **data
):
225 if cast_from
is not _Unspecified
:
228 raise ValueError('Cannot accept keyword arguments when casting.')
229 if type(cast_from
) is not type(self
):
230 raise ValueError('Cannot cast from %s'%cast
_from
)
231 for key
, value
in cast_from
.__dict
__.items():
232 setattr(self
, key
, value
)
234 for key
, value
in data
.iteritems():
235 setattr(self
, key
, value
)
237 def __setattr__(self
, key
, value
):
238 if key
in self
._members
:
239 self
.__dict
__[key
] = cast(self
._members
[key
], value
)
241 raise AttributeError("Struct has no member '%s'" % key
)
244 class UnionType(CythonType
):
246 def __init__(self
, cast_from
=_Unspecified
, **data
):
247 if cast_from
is not _Unspecified
:
250 raise ValueError('Cannot accept keyword arguments when casting.')
251 if isinstance(cast_from
, dict):
253 elif type(cast_from
) is type(self
):
254 datadict
= cast_from
.__dict
__
256 raise ValueError('Cannot cast from %s'%cast
_from
)
259 if len(datadict
) > 1:
260 raise AttributeError("Union can only store one field at a time.")
261 for key
, value
in datadict
.iteritems():
262 setattr(self
, key
, value
)
264 def __setattr__(self
, key
, value
):
265 if key
in '__dict__':
266 CythonType
.__setattr
__(self
, key
, value
)
267 elif key
in self
._members
:
268 self
.__dict
__ = {key
: cast(self
._members
[key
], value
)}
270 raise AttributeError("Union has no member '%s'" % key
)
272 def pointer(basetype
):
273 class PointerInstance(PointerType
):
275 return PointerInstance
277 def array(basetype
, n
):
278 class ArrayInstance(ArrayType
):
283 def struct(**members
):
284 class StructInstance(StructType
):
287 setattr(StructInstance
, key
, None)
288 return StructInstance
290 def union(**members
):
291 class UnionInstance(UnionType
):
294 setattr(UnionInstance
, key
, None)
297 class typedef(CythonType
):
299 def __init__(self
, type, name
=None):
300 self
._basetype
= type
303 def __call__(self
, *arg
):
304 value
= cast(self
._basetype
, *arg
)
308 return self
.name
or str(self
._basetype
)
310 __getitem__
= index_type
312 class _FusedType(CythonType
):
316 def fused_type(*args
):
318 raise TypeError("Expected at least one type as argument")
320 # Find the numeric type with biggest rank if all types are numeric
323 if type not in (py_int
, py_long
, py_float
, py_complex
):
326 if type_ordering
.index(type) > rank
:
331 # Not a simple numeric type, return a fused type instance. The result
332 # isn't really meant to be used, as we can't keep track of the context in
333 # pure-mode. Casting won't do anything in this case.
337 def _specialized_from_args(signatures
, args
, kwargs
):
338 "Perhaps this should be implemented in a TreeFragment in Cython code"
339 raise Exception("yet to be implemented")
342 py_int
= typedef(int, "int")
344 py_long
= typedef(long, "long")
345 except NameError: # Py3
346 py_long
= typedef(int, "long")
347 py_float
= typedef(float, "float")
348 py_complex
= typedef(complex, "double complex")
353 int_types
= ['char', 'short', 'Py_UNICODE', 'int', 'long', 'longlong', 'Py_ssize_t', 'size_t']
354 float_types
= ['longdouble', 'double', 'float']
355 complex_types
= ['longdoublecomplex', 'doublecomplex', 'floatcomplex', 'complex']
356 other_types
= ['bint', 'void']
359 'longlong': 'long long',
360 'longdouble': 'long double',
361 'longdoublecomplex': 'long double complex',
362 'doublecomplex': 'double complex',
363 'floatcomplex': 'float complex',
368 for name
in int_types
:
369 reprname
= to_repr(name
, name
)
370 gs
[name
] = typedef(py_int
, reprname
)
371 if name
!= 'Py_UNICODE' and not name
.endswith('size_t'):
372 gs
['u'+name
] = typedef(py_int
, "unsigned " + reprname
)
373 gs
['s'+name
] = typedef(py_int
, "signed " + reprname
)
375 for name
in float_types
:
376 gs
[name
] = typedef(py_float
, to_repr(name
, name
))
378 for name
in complex_types
:
379 gs
[name
] = typedef(py_complex
, to_repr(name
, name
))
381 bint
= typedef(bool, "bint")
382 void
= typedef(int, "void")
384 for t
in int_types
+ float_types
+ complex_types
+ other_types
:
385 for i
in range(1, 4):
386 gs
["%s_%s" % ('p'*i
, t
)] = globals()[t
]._pointer
(i
)
388 void
= typedef(None, "void")
391 integral
= floating
= numeric
= _FusedType()
393 type_ordering
= [py_int
, py_long
, py_float
, py_complex
]
395 class CythonDotParallel(object):
397 The cython.parallel module.
400 __all__
= ['parallel', 'prange', 'threadid']
402 def parallel(self
, num_threads
=None):
405 def prange(self
, start
=0, stop
=None, step
=1, schedule
=None, nogil
=False):
409 return range(start
, stop
, step
)
414 # def threadsavailable(self):
418 sys
.modules
['cython.parallel'] = CythonDotParallel()