1# cython.* namespace for pure mode.
2__version__ = "0.20.2"
3
4
5# BEGIN shameless copy from Cython/minivect/minitypes.py
6
7class _ArrayType(object):
8
9    is_array = True
10    subtypes = ['dtype']
11
12    def __init__(self, dtype, ndim, is_c_contig=False, is_f_contig=False,
13                 inner_contig=False, broadcasting=None):
14        self.dtype = dtype
15        self.ndim = ndim
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
20
21    def __repr__(self):
22        axes = [":"] * self.ndim
23        if self.is_c_contig:
24            axes[-1] = "::1"
25        elif self.is_f_contig:
26            axes[0] = "::1"
27
28        return "%s[%s]" % (self.dtype, ", ".join(axes))
29
30
31def index_type(base_type, item):
32    """
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
35    Cython memoryviews.
36    """
37    assert isinstance(item, (tuple, slice))
38
39    class InvalidTypeSpecification(Exception):
40        pass
41
42    def verify_slice(s):
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 "
46                "Fortran contiguity")
47
48    if isinstance(item, tuple):
49        step_idx = None
50        for idx, s in enumerate(item):
51            verify_slice(s)
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.")
56
57            if s.step == 1:
58                step_idx = idx
59
60        return _ArrayType(base_type, len(item),
61                          is_c_contig=step_idx == len(item) - 1,
62                          is_f_contig=step_idx == 0)
63    else:
64        verify_slice(item)
65        return _ArrayType(base_type, 1, is_c_contig=bool(item.step))
66
67# END shameless copy
68
69
70compiled = False
71
72_Unspecified = object()
73
74# Function decorators
75
76def _empty_decorator(x):
77    return x
78
79def locals(**arg_types):
80    return _empty_decorator
81
82def test_assert_path_exists(*paths):
83    return _empty_decorator
84
85def test_fail_if_path_exists(*paths):
86    return _empty_decorator
87
88class _EmptyDecoratorAndManager(object):
89    def __call__(self, x):
90        return x
91    def __enter__(self):
92        pass
93    def __exit__(self, exc_type, exc_value, traceback):
94        pass
95
96cclass = ccall = cfunc = _EmptyDecoratorAndManager()
97
98returns = lambda type_arg: _EmptyDecoratorAndManager()
99
100final = internal = type_version_tag = no_gc_clear = _empty_decorator
101
102def inline(f, *args, **kwds):
103  if isinstance(f, basestring):
104    from Cython.Build.Inline import cython_inline
105    return cython_inline(f, *args, **kwds)
106  else:
107    assert len(args) == len(kwds) == 0
108    return f
109
110def compile(f):
111    from Cython.Build.Inline import RuntimeCompiledFunction
112    return RuntimeCompiledFunction(f)
113
114# Special functions
115
116def cdiv(a, b):
117    q = a / b
118    if q < 0:
119        q += 1
120
121def cmod(a, b):
122    r = a % b
123    if (a*b) < 0:
124        r -= b
125    return r
126
127
128# Emulated language constructs
129
130def cast(type, *args):
131    if hasattr(type, '__call__'):
132        return type(*args)
133    else:
134        return args[0]
135
136def sizeof(arg):
137    return 1
138
139def typeof(arg):
140    return arg.__class__.__name__
141    # return type(arg)
142
143def address(arg):
144    return pointer(type(arg))([arg])
145
146def declare(type=None, value=_Unspecified, **kwds):
147    if type not in (None, object) and hasattr(type, '__call__'):
148        if value is not _Unspecified:
149            return type(value)
150        else:
151            return type()
152    else:
153        return value
154
155class _nogil(object):
156    """Support for 'with nogil' statement
157    """
158    def __enter__(self):
159        pass
160    def __exit__(self, exc_class, exc, tb):
161        return exc_class is None
162
163nogil = _nogil()
164gil = _nogil()
165del _nogil
166
167# Emulated types
168
169class CythonMetaType(type):
170
171    def __getitem__(type, ix):
172        return array(type, ix)
173
174CythonTypeObject = CythonMetaType('CythonTypeObject', (object,), {})
175
176class CythonType(CythonTypeObject):
177
178    def _pointer(self, n=1):
179        for i in range(n):
180            self = pointer(self)
181        return self
182
183class PointerType(CythonType):
184
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:
191            self._items = []
192        else:
193            raise ValueError
194
195    def __getitem__(self, ix):
196        if ix < 0:
197            raise IndexError("negative indexing not allowed in C")
198        return self._items[ix]
199
200    def __setitem__(self, ix, value):
201        if ix < 0:
202            raise IndexError("negative indexing not allowed in C")
203        self._items[ix] = cast(self._basetype, value)
204
205    def __eq__(self, value):
206        if value is None and not self._items:
207            return True
208        elif type(self) != type(value):
209            return False
210        else:
211            return not self._items and not value._items
212
213    def __repr__(self):
214        return "%s *" % (self._basetype,)
215
216class ArrayType(PointerType):
217
218    def __init__(self):
219        self._items = [None] * self._n
220
221
222class StructType(CythonType):
223
224    def __init__(self, cast_from=_Unspecified, **data):
225        if cast_from is not _Unspecified:
226            # do cast
227            if len(data) > 0:
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)
233        else:
234            for key, value in data.iteritems():
235                setattr(self, key, value)
236
237    def __setattr__(self, key, value):
238        if key in self._members:
239            self.__dict__[key] = cast(self._members[key], value)
240        else:
241            raise AttributeError("Struct has no member '%s'" % key)
242
243
244class UnionType(CythonType):
245
246    def __init__(self, cast_from=_Unspecified, **data):
247        if cast_from is not _Unspecified:
248            # do type cast
249            if len(data) > 0:
250                raise ValueError('Cannot accept keyword arguments when casting.')
251            if isinstance(cast_from, dict):
252                datadict = cast_from
253            elif type(cast_from) is type(self):
254                datadict = cast_from.__dict__
255            else:
256                raise ValueError('Cannot cast from %s'%cast_from)
257        else:
258            datadict = data
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)
263
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)}
269        else:
270            raise AttributeError("Union has no member '%s'" % key)
271
272def pointer(basetype):
273    class PointerInstance(PointerType):
274        _basetype = basetype
275    return PointerInstance
276
277def array(basetype, n):
278    class ArrayInstance(ArrayType):
279        _basetype = basetype
280        _n = n
281    return ArrayInstance
282
283def struct(**members):
284    class StructInstance(StructType):
285        _members = members
286    for key in members:
287        setattr(StructInstance, key, None)
288    return StructInstance
289
290def union(**members):
291    class UnionInstance(UnionType):
292        _members = members
293    for key in members:
294        setattr(UnionInstance, key, None)
295    return UnionInstance
296
297class typedef(CythonType):
298
299    def __init__(self, type, name=None):
300        self._basetype = type
301        self.name = name
302
303    def __call__(self, *arg):
304        value = cast(self._basetype, *arg)
305        return value
306
307    def __repr__(self):
308        return self.name or str(self._basetype)
309
310    __getitem__ = index_type
311
312class _FusedType(CythonType):
313    pass
314
315
316def fused_type(*args):
317    if not args:
318        raise TypeError("Expected at least one type as argument")
319
320    # Find the numeric type with biggest rank if all types are numeric
321    rank = -1
322    for type in args:
323        if type not in (py_int, py_long, py_float, py_complex):
324            break
325
326        if type_ordering.index(type) > rank:
327            result_type = type
328    else:
329        return result_type
330
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.
334    return _FusedType()
335
336
337def _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")
340
341
342py_int = typedef(int, "int")
343try:
344    py_long = typedef(long, "long")
345except NameError: # Py3
346    py_long = typedef(int, "long")
347py_float = typedef(float, "float")
348py_complex = typedef(complex, "double complex")
349
350
351# Predefined types
352
353int_types = ['char', 'short', 'Py_UNICODE', 'int', 'long', 'longlong', 'Py_ssize_t', 'size_t']
354float_types = ['longdouble', 'double', 'float']
355complex_types = ['longdoublecomplex', 'doublecomplex', 'floatcomplex', 'complex']
356other_types = ['bint', 'void']
357
358to_repr = {
359    'longlong': 'long long',
360    'longdouble': 'long double',
361    'longdoublecomplex': 'long double complex',
362    'doublecomplex': 'double complex',
363    'floatcomplex': 'float complex',
364}.get
365
366gs = globals()
367
368for 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)
374
375for name in float_types:
376    gs[name] = typedef(py_float, to_repr(name, name))
377
378for name in complex_types:
379    gs[name] = typedef(py_complex, to_repr(name, name))
380
381bint = typedef(bool, "bint")
382void = typedef(int, "void")
383
384for 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)
387
388void = typedef(None, "void")
389NULL = p_void(0)
390
391integral = floating = numeric = _FusedType()
392
393type_ordering = [py_int, py_long, py_float, py_complex]
394
395class CythonDotParallel(object):
396    """
397    The cython.parallel module.
398    """
399
400    __all__ = ['parallel', 'prange', 'threadid']
401
402    def parallel(self, num_threads=None):
403        return nogil
404
405    def prange(self, start=0, stop=None, step=1, schedule=None, nogil=False):
406        if stop is None:
407            stop = start
408            start = 0
409        return range(start, stop, step)
410
411    def threadid(self):
412        return 0
413
414    # def threadsavailable(self):
415        # return 1
416
417import sys
418sys.modules['cython.parallel'] = CythonDotParallel()
419del sys
420