|
|
| from __future__ import absolute_import
|
|
|
|
|
| __version__ = "3.0.10"
|
|
|
| try:
|
| from __builtin__ import basestring
|
| except ImportError:
|
| basestring = str
|
|
|
|
|
|
|
|
|
| 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.
|
| """
|
| class InvalidTypeSpecification(Exception):
|
| pass
|
|
|
| def verify_slice(s):
|
| if s.start or s.stop or s.step not in (None, 1):
|
| raise 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 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)
|
| elif isinstance(item, slice):
|
| verify_slice(item)
|
| return _ArrayType(base_type, 1, is_c_contig=bool(item.step))
|
| else:
|
|
|
| assert int(item) == item
|
| return array(base_type, item)
|
|
|
|
|
|
|
|
|
| compiled = False
|
|
|
| _Unspecified = object()
|
|
|
|
|
|
|
| def _empty_decorator(x):
|
| return x
|
|
|
| def locals(**arg_types):
|
| return _empty_decorator
|
|
|
| def test_assert_path_exists(*paths):
|
| return _empty_decorator
|
|
|
| def test_fail_if_path_exists(*paths):
|
| return _empty_decorator
|
|
|
| class _EmptyDecoratorAndManager(object):
|
| def __call__(self, x):
|
| return x
|
| def __enter__(self):
|
| pass
|
| def __exit__(self, exc_type, exc_value, traceback):
|
| pass
|
|
|
| class _Optimization(object):
|
| pass
|
|
|
| cclass = ccall = cfunc = _EmptyDecoratorAndManager()
|
|
|
| annotation_typing = returns = wraparound = boundscheck = initializedcheck = \
|
| nonecheck = embedsignature = cdivision = cdivision_warnings = \
|
| always_allow_keywords = profile = linetrace = infer_types = \
|
| unraisable_tracebacks = freelist = auto_pickle = cpow = trashcan = \
|
| auto_cpdef = c_api_binop_methods = \
|
| allow_none_for_extension_args = callspec = show_performance_hints = \
|
| cpp_locals = py2_import = iterable_coroutine = remove_unreachable = \
|
| lambda _: _EmptyDecoratorAndManager()
|
|
|
|
|
| fast_getattr = lambda _: _EmptyDecoratorAndManager()
|
|
|
| exceptval = lambda _=None, check=True: _EmptyDecoratorAndManager()
|
|
|
| overflowcheck = lambda _: _EmptyDecoratorAndManager()
|
| optimize = _Optimization()
|
|
|
|
|
| embedsignature.format = overflowcheck.fold = optimize.use_switch = \
|
| optimize.unpack_method_calls = lambda arg: _EmptyDecoratorAndManager()
|
|
|
| final = internal = type_version_tag = no_gc_clear = no_gc = total_ordering = \
|
| ufunc = _empty_decorator
|
|
|
| binding = lambda _: _empty_decorator
|
|
|
| class warn:
|
| undeclared = unreachable = maybe_uninitialized = unused = \
|
| unused_arg = unused_result = \
|
| lambda _: _EmptyDecoratorAndManager()
|
|
|
|
|
| _cython_inline = None
|
| def inline(f, *args, **kwds):
|
| if isinstance(f, basestring):
|
| global _cython_inline
|
| if _cython_inline is None:
|
| from Cython.Build.Inline import cython_inline as _cython_inline
|
| return _cython_inline(f, *args, **kwds)
|
| else:
|
| assert len(args) == len(kwds) == 0
|
| return f
|
|
|
|
|
| def compile(f):
|
| from Cython.Build.Inline import RuntimeCompiledFunction
|
| return RuntimeCompiledFunction(f)
|
|
|
|
|
|
|
|
|
| def cdiv(a, b):
|
| if a < 0:
|
| a = -a
|
| b = -b
|
| if b < 0:
|
| return (a + b + 1) // b
|
| return a // b
|
|
|
| def cmod(a, b):
|
| r = a % b
|
| if (a * b) < 0 and r:
|
| r -= b
|
| return r
|
|
|
|
|
|
|
|
|
| def cast(t, *args, **kwargs):
|
| kwargs.pop('typecheck', None)
|
| assert not kwargs
|
|
|
| if isinstance(t, typedef):
|
| return t(*args)
|
| elif isinstance(t, type):
|
| if len(args) != 1 or not (args[0] is None or isinstance(args[0], t)):
|
| return t(*args)
|
|
|
| return args[0]
|
|
|
| def sizeof(arg):
|
| return 1
|
|
|
| def typeof(arg):
|
| return arg.__class__.__name__
|
|
|
|
|
| def address(arg):
|
| return pointer(type(arg))([arg])
|
|
|
| def _is_value_type(t):
|
| if isinstance(t, typedef):
|
| return _is_value_type(t._basetype)
|
|
|
| return isinstance(t, type) and issubclass(t, (StructType, UnionType, ArrayType))
|
|
|
| def declare(t=None, value=_Unspecified, **kwds):
|
| if value is not _Unspecified:
|
| return cast(t, value)
|
| elif _is_value_type(t):
|
| return t()
|
| else:
|
| return None
|
|
|
| class _nogil(object):
|
| """Support for 'with nogil' statement and @nogil decorator.
|
| """
|
| def __call__(self, x):
|
| if callable(x):
|
|
|
| return x
|
|
|
| return self
|
|
|
| def __enter__(self):
|
| pass
|
| def __exit__(self, exc_class, exc, tb):
|
| return exc_class is None
|
|
|
| nogil = _nogil()
|
| gil = _nogil()
|
| with_gil = _nogil()
|
| del _nogil
|
|
|
|
|
|
|
|
|
| class CythonMetaType(type):
|
|
|
| def __getitem__(type, ix):
|
| return array(type, ix)
|
|
|
| CythonTypeObject = CythonMetaType('CythonTypeObject', (object,), {})
|
|
|
| class CythonType(CythonTypeObject):
|
|
|
| def _pointer(self, n=1):
|
| for i in range(n):
|
| self = pointer(self)
|
| return self
|
|
|
| class PointerType(CythonType):
|
|
|
| def __init__(self, value=None):
|
| if isinstance(value, (ArrayType, PointerType)):
|
| self._items = [cast(self._basetype, a) for a in value._items]
|
| elif isinstance(value, list):
|
| self._items = [cast(self._basetype, a) for a in value]
|
| elif value is None or value == 0:
|
| self._items = []
|
| else:
|
| raise ValueError
|
|
|
| def __getitem__(self, ix):
|
| if ix < 0:
|
| raise IndexError("negative indexing not allowed in C")
|
| return self._items[ix]
|
|
|
| def __setitem__(self, ix, value):
|
| if ix < 0:
|
| raise IndexError("negative indexing not allowed in C")
|
| self._items[ix] = cast(self._basetype, value)
|
|
|
| def __eq__(self, value):
|
| if value is None and not self._items:
|
| return True
|
| elif type(self) != type(value):
|
| return False
|
| else:
|
| return not self._items and not value._items
|
|
|
| def __repr__(self):
|
| return "%s *" % (self._basetype,)
|
|
|
| class ArrayType(PointerType):
|
|
|
| def __init__(self, value=None):
|
| if value is None:
|
| self._items = [None] * self._n
|
| else:
|
| super(ArrayType, self).__init__(value)
|
|
|
|
|
| class StructType(CythonType):
|
|
|
| def __init__(self, *posargs, **data):
|
| if not (posargs or data):
|
| return
|
| if posargs and data:
|
| raise ValueError('Cannot accept both positional and keyword arguments.')
|
|
|
|
|
| if data and len(data) == 1 and 'cast_from' in data:
|
| cast_from = data.pop('cast_from')
|
| elif len(posargs) == 1 and type(posargs[0]) is type(self):
|
| cast_from, posargs = posargs[0], ()
|
| elif posargs:
|
| for key, arg in zip(self._members, posargs):
|
| setattr(self, key, arg)
|
| return
|
| else:
|
| for key, value in data.items():
|
| if key not in self._members:
|
| raise ValueError("Invalid struct attribute for %s: %s" % (
|
| self.__class__.__name__, key))
|
| setattr(self, key, value)
|
| return
|
|
|
|
|
| if data:
|
| raise ValueError('Cannot accept keyword arguments when casting.')
|
| if type(cast_from) is not type(self):
|
| raise ValueError('Cannot cast from %s' % cast_from)
|
| for key, value in cast_from.__dict__.items():
|
| setattr(self, key, value)
|
|
|
| def __setattr__(self, key, value):
|
| if key in self._members:
|
| self.__dict__[key] = cast(self._members[key], value)
|
| else:
|
| raise AttributeError("Struct has no member '%s'" % key)
|
|
|
|
|
| class UnionType(CythonType):
|
|
|
| def __init__(self, cast_from=_Unspecified, **data):
|
| if cast_from is not _Unspecified:
|
|
|
| if len(data) > 0:
|
| raise ValueError('Cannot accept keyword arguments when casting.')
|
| if isinstance(cast_from, dict):
|
| datadict = cast_from
|
| elif type(cast_from) is type(self):
|
| datadict = cast_from.__dict__
|
| else:
|
| raise ValueError('Cannot cast from %s' % cast_from)
|
| else:
|
| datadict = data
|
| if len(datadict) > 1:
|
| raise AttributeError("Union can only store one field at a time.")
|
| for key, value in datadict.items():
|
| setattr(self, key, value)
|
|
|
| def __setattr__(self, key, value):
|
| if key == '__dict__':
|
| CythonType.__setattr__(self, key, value)
|
| elif key in self._members:
|
| self.__dict__ = {key: cast(self._members[key], value)}
|
| else:
|
| raise AttributeError("Union has no member '%s'" % key)
|
|
|
| def pointer(basetype):
|
| class PointerInstance(PointerType):
|
| _basetype = basetype
|
| return PointerInstance
|
|
|
| def array(basetype, n):
|
| class ArrayInstance(ArrayType):
|
| _basetype = basetype
|
| _n = n
|
| return ArrayInstance
|
|
|
| def struct(**members):
|
| class StructInstance(StructType):
|
| _members = members
|
| for key in members:
|
| setattr(StructInstance, key, None)
|
| return StructInstance
|
|
|
| def union(**members):
|
| class UnionInstance(UnionType):
|
| _members = members
|
| for key in members:
|
| setattr(UnionInstance, key, None)
|
| return UnionInstance
|
|
|
| class typedef(CythonType):
|
|
|
| def __init__(self, type, name=None):
|
| self._basetype = type
|
| self.name = name
|
|
|
| def __call__(self, *arg):
|
| value = cast(self._basetype, *arg)
|
| return value
|
|
|
| def __repr__(self):
|
| return self.name or str(self._basetype)
|
|
|
| __getitem__ = index_type
|
|
|
| class _FusedType(CythonType):
|
| __getitem__ = index_type
|
|
|
|
|
| def fused_type(*args):
|
| if not args:
|
| raise TypeError("Expected at least one type as argument")
|
|
|
|
|
| rank = -1
|
| for type in args:
|
| if type not in (py_int, py_long, py_float, py_complex):
|
| break
|
|
|
| if type_ordering.index(type) > rank:
|
| result_type = type
|
| else:
|
| return result_type
|
|
|
|
|
|
|
|
|
| return _FusedType()
|
|
|
|
|
| def _specialized_from_args(signatures, args, kwargs):
|
| "Perhaps this should be implemented in a TreeFragment in Cython code"
|
| raise Exception("yet to be implemented")
|
|
|
|
|
| py_int = typedef(int, "int")
|
| try:
|
| py_long = typedef(long, "long")
|
| except NameError:
|
| py_long = typedef(int, "long")
|
| py_float = typedef(float, "float")
|
| py_complex = typedef(complex, "double complex")
|
|
|
|
|
|
|
|
|
| int_types = [
|
| 'char',
|
| 'short',
|
| 'Py_UNICODE',
|
| 'int',
|
| 'Py_UCS4',
|
| 'long',
|
| 'longlong',
|
| 'Py_hash_t',
|
| 'Py_ssize_t',
|
| 'size_t',
|
| 'ssize_t',
|
| 'ptrdiff_t',
|
| ]
|
| float_types = [
|
| 'longdouble',
|
| 'double',
|
| 'float',
|
| ]
|
| complex_types = [
|
| 'longdoublecomplex',
|
| 'doublecomplex',
|
| 'floatcomplex',
|
| 'complex',
|
| ]
|
| other_types = [
|
| 'bint',
|
| 'void',
|
| 'Py_tss_t',
|
| ]
|
|
|
| to_repr = {
|
| 'longlong': 'long long',
|
| 'longdouble': 'long double',
|
| 'longdoublecomplex': 'long double complex',
|
| 'doublecomplex': 'double complex',
|
| 'floatcomplex': 'float complex',
|
| }.get
|
|
|
| gs = globals()
|
|
|
|
|
| try:
|
| import __builtin__ as builtins
|
| except ImportError:
|
| import builtins
|
|
|
| gs['unicode'] = typedef(getattr(builtins, 'unicode', str), 'unicode')
|
| del builtins
|
|
|
| for name in int_types:
|
| reprname = to_repr(name, name)
|
| gs[name] = typedef(py_int, reprname)
|
| if name not in ('Py_UNICODE', 'Py_UCS4', 'Py_hash_t', 'ptrdiff_t') and not name.endswith('size_t'):
|
| gs['u'+name] = typedef(py_int, "unsigned " + reprname)
|
| gs['s'+name] = typedef(py_int, "signed " + reprname)
|
|
|
| for name in float_types:
|
| gs[name] = typedef(py_float, to_repr(name, name))
|
|
|
| for name in complex_types:
|
| gs[name] = typedef(py_complex, to_repr(name, name))
|
|
|
| bint = typedef(bool, "bint")
|
| void = typedef(None, "void")
|
| Py_tss_t = typedef(None, "Py_tss_t")
|
|
|
| for t in int_types:
|
| for i in range(1, 4):
|
| gs["%s_%s" % ('p'*i, t)] = gs[t]._pointer(i)
|
| if 'u'+t in gs:
|
| gs["%s_u%s" % ('p'*i, t)] = gs['u'+t]._pointer(i)
|
| gs["%s_s%s" % ('p'*i, t)] = gs['s'+t]._pointer(i)
|
|
|
| for t in float_types + complex_types + other_types:
|
| for i in range(1, 4):
|
| gs["%s_%s" % ('p'*i, t)] = gs[t]._pointer(i)
|
|
|
| del t, i
|
|
|
| NULL = gs['p_void'](0)
|
|
|
|
|
|
|
|
|
| integral = floating = numeric = _FusedType()
|
|
|
| type_ordering = [py_int, py_long, py_float, py_complex]
|
|
|
| class CythonDotParallel(object):
|
| """
|
| The cython.parallel module.
|
| """
|
|
|
| __all__ = ['parallel', 'prange', 'threadid']
|
|
|
| def parallel(self, num_threads=None):
|
| return nogil
|
|
|
| def prange(self, start=0, stop=None, step=1, nogil=False, schedule=None, chunksize=None, num_threads=None):
|
| if stop is None:
|
| stop = start
|
| start = 0
|
| return range(start, stop, step)
|
|
|
| def threadid(self):
|
| return 0
|
|
|
|
|
|
|
|
|
| class CythonDotImportedFromElsewhere(object):
|
| """
|
| cython.dataclasses just shadows the standard library modules of the same name
|
| """
|
| def __init__(self, module):
|
| self.__path__ = []
|
| self.__file__ = None
|
| self.__name__ = module
|
| self.__package__ = module
|
|
|
| def __getattr__(self, attr):
|
|
|
| from importlib import import_module
|
| import sys
|
| try:
|
| mod = import_module(self.__name__)
|
| except ImportError:
|
|
|
|
|
| raise AttributeError("%s: the standard library module %s is not available" %
|
| (attr, self.__name__))
|
| sys.modules['cython.%s' % self.__name__] = mod
|
| return getattr(mod, attr)
|
|
|
| class CythonCImports(object):
|
| """
|
| Simplistic module mock to make cimports sort-of work in Python code.
|
| """
|
| def __init__(self, module):
|
| self.__path__ = []
|
| self.__file__ = None
|
| self.__name__ = module
|
| self.__package__ = module
|
|
|
| def __getattr__(self, item):
|
| if item.startswith('__') and item.endswith('__'):
|
| raise AttributeError(item)
|
| try:
|
| return __import__(item)
|
| except ImportError:
|
| import sys
|
| ex = AttributeError(item)
|
| if sys.version_info >= (3, 0):
|
| ex.__cause__ = None
|
| raise ex
|
|
|
|
|
| import math, sys
|
| sys.modules['cython.parallel'] = CythonDotParallel()
|
| sys.modules['cython.cimports'] = CythonCImports('cython.cimports')
|
| sys.modules['cython.cimports.libc'] = CythonCImports('cython.cimports.libc')
|
| sys.modules['cython.cimports.libc.math'] = math
|
|
|
|
|
| dataclasses = sys.modules['cython.dataclasses'] = CythonDotImportedFromElsewhere('dataclasses')
|
| del math, sys
|
|
|