14
def __init__(self, dtype, ndim, is_c_contig=False, is_f_contig=False,
15
inner_contig=False, broadcasting=None):
18
self.is_c_contig = is_c_contig
19
self.is_f_contig = is_f_contig
20
self.inner_contig = inner_contig or is_c_contig or is_f_contig
21
self.broadcasting = broadcasting
24
axes = [":"] * self.ndim
27
elif self.is_f_contig:
30
return "%s[%s]" % (self.dtype, ", ".join(axes))
33
def index_type(base_type, item):
35
Support array type creation by slicing, e.g. double[:, :] specifies
36
a 2D strided array of doubles. The syntax is the same as for
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)
63
elif isinstance(item, slice):
65
return _ArrayType(base_type, 1, is_c_contig=bool(item.step))
68
assert int(item) == item
69
return array(base_type, item)
76
_Unspecified = object()
80
def _empty_decorator(x):
83
def locals(**arg_types):
84
return _empty_decorator
86
def test_assert_path_exists(*paths):
87
return _empty_decorator
89
def test_fail_if_path_exists(*paths):
90
return _empty_decorator
92
class _EmptyDecoratorAndManager:
93
def __call__(self, x):
97
def __exit__(self, exc_type, exc_value, traceback):
103
cclass = ccall = cfunc = _EmptyDecoratorAndManager()
105
annotation_typing = returns = wraparound = boundscheck = initializedcheck = \
106
nonecheck = embedsignature = cdivision = cdivision_warnings = \
107
always_allow_keywords = profile = linetrace = infer_types = \
108
unraisable_tracebacks = freelist = auto_pickle = cpow = trashcan = \
109
auto_cpdef = c_api_binop_methods = \
110
allow_none_for_extension_args = callspec = show_performance_hints = \
111
cpp_locals = py2_import = iterable_coroutine = remove_unreachable = \
112
lambda _: _EmptyDecoratorAndManager()
115
fast_getattr = lambda _: _EmptyDecoratorAndManager()
117
exceptval = lambda _=None, check=True: _EmptyDecoratorAndManager()
119
overflowcheck = lambda _: _EmptyDecoratorAndManager()
120
optimize = _Optimization()
123
embedsignature.format = overflowcheck.fold = optimize.use_switch = \
124
optimize.unpack_method_calls = lambda arg: _EmptyDecoratorAndManager()
126
final = internal = type_version_tag = no_gc_clear = no_gc = total_ordering = \
127
ufunc = _empty_decorator
129
binding = lambda _: _empty_decorator
132
undeclared = unreachable = maybe_uninitialized = unused = \
133
unused_arg = unused_result = \
134
lambda _: _EmptyDecoratorAndManager()
138
def inline(f, *args, **kwds):
139
if isinstance(f, str):
140
global _cython_inline
141
if _cython_inline is None:
142
from Cython.Build.Inline import cython_inline as _cython_inline
143
return _cython_inline(f, *args, **kwds)
145
assert len(args) == len(kwds) == 0
150
from Cython.Build.Inline import RuntimeCompiledFunction
151
return RuntimeCompiledFunction(f)
161
return (a + b + 1) // b
166
if (a * b) < 0 and r:
173
def cast(t, *args, **kwargs):
174
kwargs.pop('typecheck', None)
177
if isinstance(t, typedef):
179
elif isinstance(t, type):
180
if len(args) != 1 or not (args[0] is None or isinstance(args[0], t)):
189
return arg.__class__.__name__
193
return pointer(type(arg))([arg])
195
def _is_value_type(t):
196
if isinstance(t, typedef):
197
return _is_value_type(t._basetype)
199
return isinstance(t, type) and issubclass(t, (StructType, UnionType, ArrayType))
201
def declare(t=None, value=_Unspecified, **kwds):
202
if value is not _Unspecified:
203
return cast(t, value)
204
elif _is_value_type(t):
210
"""Support for 'with nogil' statement and @nogil decorator.
212
def __call__(self, x):
221
def __exit__(self, exc_class, exc, tb):
222
return exc_class is None
232
class CythonMetaType(type):
234
def __getitem__(type, ix):
235
return array(type, ix)
237
CythonTypeObject = CythonMetaType('CythonTypeObject', (object,), {})
239
class CythonType(CythonTypeObject):
241
def _pointer(self, n=1):
246
class PointerType(CythonType):
248
def __init__(self, value=None):
249
if isinstance(value, (ArrayType, PointerType)):
250
self._items = [cast(self._basetype, a) for a in value._items]
251
elif isinstance(value, list):
252
self._items = [cast(self._basetype, a) for a in value]
253
elif value is None or value == 0:
258
def __getitem__(self, ix):
260
raise IndexError("negative indexing not allowed in C")
261
return self._items[ix]
263
def __setitem__(self, ix, value):
265
raise IndexError("negative indexing not allowed in C")
266
self._items[ix] = cast(self._basetype, value)
268
def __eq__(self, value):
269
if value is None and not self._items:
271
elif type(self) != type(value):
274
return not self._items and not value._items
277
return "%s *" % (self._basetype,)
279
class ArrayType(PointerType):
281
def __init__(self, value=None):
283
self._items = [None] * self._n
285
super().__init__(value)
288
class StructType(CythonType):
290
def __init__(self, *posargs, **data):
291
if not (posargs or data):
294
raise ValueError('Cannot accept both positional and keyword arguments.')
297
if data and len(data) == 1 and 'cast_from' in data:
298
cast_from = data.pop('cast_from')
299
elif len(posargs) == 1 and type(posargs[0]) is type(self):
300
cast_from, posargs = posargs[0], ()
302
for key, arg in zip(self._members, posargs):
303
setattr(self, key, arg)
306
for key, value in data.items():
307
if key not in self._members:
308
raise ValueError("Invalid struct attribute for %s: %s" % (
309
self.__class__.__name__, key))
310
setattr(self, key, value)
315
raise ValueError('Cannot accept keyword arguments when casting.')
316
if type(cast_from) is not type(self):
317
raise ValueError('Cannot cast from %s' % cast_from)
318
for key, value in cast_from.__dict__.items():
319
setattr(self, key, value)
321
def __setattr__(self, key, value):
322
if key in self._members:
323
self.__dict__[key] = cast(self._members[key], value)
325
raise AttributeError("Struct has no member '%s'" % key)
328
class UnionType(CythonType):
330
def __init__(self, cast_from=_Unspecified, **data):
331
if cast_from is not _Unspecified:
334
raise ValueError('Cannot accept keyword arguments when casting.')
335
if isinstance(cast_from, dict):
337
elif type(cast_from) is type(self):
338
datadict = cast_from.__dict__
340
raise ValueError('Cannot cast from %s' % cast_from)
343
if len(datadict) > 1:
344
raise AttributeError("Union can only store one field at a time.")
345
for key, value in datadict.items():
346
setattr(self, key, value)
348
def __setattr__(self, key, value):
349
if key == '__dict__':
350
CythonType.__setattr__(self, key, value)
351
elif key in self._members:
352
self.__dict__ = {key: cast(self._members[key], value)}
354
raise AttributeError("Union has no member '%s'" % key)
356
def pointer(basetype):
357
class PointerInstance(PointerType):
359
return PointerInstance
361
def array(basetype, n):
362
class ArrayInstance(ArrayType):
367
def struct(**members):
368
class StructInstance(StructType):
371
setattr(StructInstance, key, None)
372
return StructInstance
375
class UnionInstance(UnionType):
378
setattr(UnionInstance, key, None)
381
class typedef(CythonType):
383
def __init__(self, type, name=None):
384
self._basetype = type
387
def __call__(self, *arg):
388
value = cast(self._basetype, *arg)
392
return self.name or str(self._basetype)
394
__getitem__ = index_type
396
class _FusedType(CythonType):
397
__getitem__ = index_type
400
def fused_type(*args):
402
raise TypeError("Expected at least one type as argument")
407
if type not in (py_int, py_long, py_float, py_complex):
410
if type_ordering.index(type) > rank:
421
def _specialized_from_args(signatures, args, kwargs):
422
"Perhaps this should be implemented in a TreeFragment in Cython code"
423
raise Exception("yet to be implemented")
426
py_int = typedef(int, "int")
427
py_long = typedef(int, "long")
428
py_float = typedef(float, "float")
429
py_complex = typedef(complex, "double complex")
466
'longlong': 'long long',
467
'longdouble': 'long double',
468
'longdoublecomplex': 'long double complex',
469
'doublecomplex': 'double complex',
470
'floatcomplex': 'float complex',
475
gs['unicode'] = typedef(str, 'unicode')
477
for name in int_types:
478
reprname = to_repr(name, name)
479
gs[name] = typedef(py_int, reprname)
480
if name not in ('Py_UNICODE', 'Py_UCS4', 'Py_hash_t', 'ptrdiff_t') and not name.endswith('size_t'):
481
gs['u'+name] = typedef(py_int, "unsigned " + reprname)
482
gs['s'+name] = typedef(py_int, "signed " + reprname)
484
for name in float_types:
485
gs[name] = typedef(py_float, to_repr(name, name))
487
for name in complex_types:
488
gs[name] = typedef(py_complex, to_repr(name, name))
492
bint = typedef(bool, "bint")
493
void = typedef(None, "void")
494
Py_tss_t = typedef(None, "Py_tss_t")
497
for i in range(1, 4):
498
gs["%s_%s" % ('p'*i, t)] = gs[t]._pointer(i)
500
gs["%s_u%s" % ('p'*i, t)] = gs['u'+t]._pointer(i)
501
gs["%s_s%s" % ('p'*i, t)] = gs['s'+t]._pointer(i)
503
for t in float_types + complex_types + other_types:
504
for i in range(1, 4):
505
gs["%s_%s" % ('p'*i, t)] = gs[t]._pointer(i)
509
NULL = gs['p_void'](0)
514
def __getattr__(name):
519
"'gs' is not a publicly exposed name in cython.*. Use vars() or globals() instead.",
522
raise AttributeError(f"'cython' has no attribute {name!r}")
525
integral = floating = numeric = _FusedType()
527
type_ordering = [py_int, py_long, py_float, py_complex]
529
class CythonDotParallel:
531
The cython.parallel module.
534
__all__ = ['parallel', 'prange', 'threadid']
536
def parallel(self, num_threads=None):
539
def prange(self, start=0, stop=None, step=1, nogil=False, schedule=None, chunksize=None, num_threads=None):
543
return range(start, stop, step)
551
class CythonDotImportedFromElsewhere:
553
cython.dataclasses just shadows the standard library modules of the same name
555
def __init__(self, module):
558
self.__name__ = module
559
self.__package__ = module
561
def __getattr__(self, attr):
563
from importlib import import_module
566
mod = import_module(self.__name__)
570
raise AttributeError("%s: the standard library module %s is not available" %
571
(attr, self.__name__))
572
sys.modules['cython.%s' % self.__name__] = mod
573
return getattr(mod, attr)
577
Simplistic module mock to make cimports sort-of work in Python code.
579
def __init__(self, module, **attributes):
582
self.__name__ = module
583
self.__package__ = module
585
self.__dict__.update(attributes)
587
def __getattr__(self, item):
588
if item.startswith('__') and item.endswith('__'):
589
raise AttributeError(item)
591
package = self.__package__[len('cython.cimports.'):]
593
from importlib import import_module
595
return import_module(item, package or None)
597
ex = AttributeError(item)
603
sys.modules['cython.parallel'] = CythonDotParallel()
604
sys.modules['cython.cimports.libc.math'] = math
605
sys.modules['cython.cimports.libc'] = CythonCImports('cython.cimports.libc', math=math)
606
sys.modules['cython.cimports'] = CythonCImports('cython.cimports', libc=sys.modules['cython.cimports.libc'])
610
dataclasses = sys.modules['cython.dataclasses'] = CythonDotImportedFromElsewhere('dataclasses')