Home | History | Annotate | Download | only in Cython
      1 # cython.* namespace for pure mode.
      2 __version__ = "0.20.2"
      3 
      4 
      5 # BEGIN shameless copy from Cython/minivect/minitypes.py
      6 
      7 class _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 
     31 def 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 
     70 compiled = False
     71 
     72 _Unspecified = object()
     73 
     74 # Function decorators
     75 
     76 def _empty_decorator(x):
     77     return x
     78 
     79 def locals(**arg_types):
     80     return _empty_decorator
     81 
     82 def test_assert_path_exists(*paths):
     83     return _empty_decorator
     84 
     85 def test_fail_if_path_exists(*paths):
     86     return _empty_decorator
     87 
     88 class _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 
     96 cclass = ccall = cfunc = _EmptyDecoratorAndManager()
     97 
     98 returns = lambda type_arg: _EmptyDecoratorAndManager()
     99 
    100 final = internal = type_version_tag = no_gc_clear = _empty_decorator
    101 
    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)
    106   else:
    107     assert len(args) == len(kwds) == 0
    108     return f
    109 
    110 def compile(f):
    111     from Cython.Build.Inline import RuntimeCompiledFunction
    112     return RuntimeCompiledFunction(f)
    113 
    114 # Special functions
    115 
    116 def cdiv(a, b):
    117     q = a / b
    118     if q < 0:
    119         q += 1
    120 
    121 def 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 
    130 def cast(type, *args):
    131     if hasattr(type, '__call__'):
    132         return type(*args)
    133     else:
    134         return args[0]
    135 
    136 def sizeof(arg):
    137     return 1
    138 
    139 def typeof(arg):
    140     return arg.__class__.__name__
    141     # return type(arg)
    142 
    143 def address(arg):
    144     return pointer(type(arg))([arg])
    145 
    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:
    149             return type(value)
    150         else:
    151             return type()
    152     else:
    153         return value
    154 
    155 class _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 
    163 nogil = _nogil()
    164 gil = _nogil()
    165 del _nogil
    166 
    167 # Emulated types
    168 
    169 class CythonMetaType(type):
    170 
    171     def __getitem__(type, ix):
    172         return array(type, ix)
    173 
    174 CythonTypeObject = CythonMetaType('CythonTypeObject', (object,), {})
    175 
    176 class CythonType(CythonTypeObject):
    177 
    178     def _pointer(self, n=1):
    179         for i in range(n):
    180             self = pointer(self)
    181         return self
    182 
    183 class 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 
    216 class ArrayType(PointerType):
    217 
    218     def __init__(self):
    219         self._items = [None] * self._n
    220 
    221 
    222 class 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 
    244 class 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 
    272 def pointer(basetype):
    273     class PointerInstance(PointerType):
    274         _basetype = basetype
    275     return PointerInstance
    276 
    277 def array(basetype, n):
    278     class ArrayInstance(ArrayType):
    279         _basetype = basetype
    280         _n = n
    281     return ArrayInstance
    282 
    283 def struct(**members):
    284     class StructInstance(StructType):
    285         _members = members
    286     for key in members:
    287         setattr(StructInstance, key, None)
    288     return StructInstance
    289 
    290 def union(**members):
    291     class UnionInstance(UnionType):
    292         _members = members
    293     for key in members:
    294         setattr(UnionInstance, key, None)
    295     return UnionInstance
    296 
    297 class 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 
    312 class _FusedType(CythonType):
    313     pass
    314 
    315 
    316 def 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 
    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")
    340 
    341 
    342 py_int = typedef(int, "int")
    343 try:
    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")
    349 
    350 
    351 # Predefined types
    352 
    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']
    357 
    358 to_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 
    366 gs = globals()
    367 
    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)
    374 
    375 for name in float_types:
    376     gs[name] = typedef(py_float, to_repr(name, name))
    377 
    378 for name in complex_types:
    379     gs[name] = typedef(py_complex, to_repr(name, name))
    380 
    381 bint = typedef(bool, "bint")
    382 void = typedef(int, "void")
    383 
    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)
    387 
    388 void = typedef(None, "void")
    389 NULL = p_void(0)
    390 
    391 integral = floating = numeric = _FusedType()
    392 
    393 type_ordering = [py_int, py_long, py_float, py_complex]
    394 
    395 class 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 
    417 import sys
    418 sys.modules['cython.parallel'] = CythonDotParallel()
    419 del sys
    420