1# cython.* namespace for pure mode. 2from __future__ import absolute_import 3 4__version__ = "0.29.13" 5 6try: 7 from __builtin__ import basestring 8except ImportError: 9 basestring = str 10 11 12# BEGIN shameless copy from Cython/minivect/minitypes.py 13 14class _ArrayType(object): 15 16 is_array = True 17 subtypes = ['dtype'] 18 19 def __init__(self, dtype, ndim, is_c_contig=False, is_f_contig=False, 20 inner_contig=False, broadcasting=None): 21 self.dtype = dtype 22 self.ndim = ndim 23 self.is_c_contig = is_c_contig 24 self.is_f_contig = is_f_contig 25 self.inner_contig = inner_contig or is_c_contig or is_f_contig 26 self.broadcasting = broadcasting 27 28 def __repr__(self): 29 axes = [":"] * self.ndim 30 if self.is_c_contig: 31 axes[-1] = "::1" 32 elif self.is_f_contig: 33 axes[0] = "::1" 34 35 return "%s[%s]" % (self.dtype, ", ".join(axes)) 36 37 38def index_type(base_type, item): 39 """ 40 Support array type creation by slicing, e.g. double[:, :] specifies 41 a 2D strided array of doubles. The syntax is the same as for 42 Cython memoryviews. 43 """ 44 class InvalidTypeSpecification(Exception): 45 pass 46 47 def verify_slice(s): 48 if s.start or s.stop or s.step not in (None, 1): 49 raise InvalidTypeSpecification( 50 "Only a step of 1 may be provided to indicate C or " 51 "Fortran contiguity") 52 53 if isinstance(item, tuple): 54 step_idx = None 55 for idx, s in enumerate(item): 56 verify_slice(s) 57 if s.step and (step_idx or idx not in (0, len(item) - 1)): 58 raise InvalidTypeSpecification( 59 "Step may only be provided once, and only in the " 60 "first or last dimension.") 61 62 if s.step == 1: 63 step_idx = idx 64 65 return _ArrayType(base_type, len(item), 66 is_c_contig=step_idx == len(item) - 1, 67 is_f_contig=step_idx == 0) 68 elif isinstance(item, slice): 69 verify_slice(item) 70 return _ArrayType(base_type, 1, is_c_contig=bool(item.step)) 71 else: 72 # int[8] etc. 73 assert int(item) == item # array size must be a plain integer 74 array(base_type, item) 75 76# END shameless copy 77 78 79compiled = False 80 81_Unspecified = object() 82 83# Function decorators 84 85def _empty_decorator(x): 86 return x 87 88def locals(**arg_types): 89 return _empty_decorator 90 91def test_assert_path_exists(*paths): 92 return _empty_decorator 93 94def test_fail_if_path_exists(*paths): 95 return _empty_decorator 96 97class _EmptyDecoratorAndManager(object): 98 def __call__(self, x): 99 return x 100 def __enter__(self): 101 pass 102 def __exit__(self, exc_type, exc_value, traceback): 103 pass 104 105class _Optimization(object): 106 pass 107 108cclass = ccall = cfunc = _EmptyDecoratorAndManager() 109 110returns = wraparound = boundscheck = initializedcheck = nonecheck = \ 111 embedsignature = cdivision = cdivision_warnings = \ 112 always_allows_keywords = profile = linetrace = infer_types = \ 113 unraisable_tracebacks = freelist = \ 114 lambda _: _EmptyDecoratorAndManager() 115 116exceptval = lambda _=None, check=True: _EmptyDecoratorAndManager() 117 118overflowcheck = lambda _: _EmptyDecoratorAndManager() 119optimization = _Optimization() 120 121overflowcheck.fold = optimization.use_switch = \ 122 optimization.unpack_method_calls = lambda arg: _EmptyDecoratorAndManager() 123 124final = internal = type_version_tag = no_gc_clear = no_gc = _empty_decorator 125 126 127_cython_inline = None 128def inline(f, *args, **kwds): 129 if isinstance(f, basestring): 130 global _cython_inline 131 if _cython_inline is None: 132 from Cython.Build.Inline import cython_inline as _cython_inline 133 return _cython_inline(f, *args, **kwds) 134 else: 135 assert len(args) == len(kwds) == 0 136 return f 137 138 139def compile(f): 140 from Cython.Build.Inline import RuntimeCompiledFunction 141 return RuntimeCompiledFunction(f) 142 143 144# Special functions 145 146def cdiv(a, b): 147 q = a / b 148 if q < 0: 149 q += 1 150 return q 151 152def cmod(a, b): 153 r = a % b 154 if (a*b) < 0: 155 r -= b 156 return r 157 158 159# Emulated language constructs 160 161def cast(type, *args, **kwargs): 162 kwargs.pop('typecheck', None) 163 assert not kwargs 164 if hasattr(type, '__call__'): 165 return type(*args) 166 else: 167 return args[0] 168 169def sizeof(arg): 170 return 1 171 172def typeof(arg): 173 return arg.__class__.__name__ 174 # return type(arg) 175 176def address(arg): 177 return pointer(type(arg))([arg]) 178 179def declare(type=None, value=_Unspecified, **kwds): 180 if type not in (None, object) and hasattr(type, '__call__'): 181 if value is not _Unspecified: 182 return type(value) 183 else: 184 return type() 185 else: 186 return value 187 188class _nogil(object): 189 """Support for 'with nogil' statement and @nogil decorator. 190 """ 191 def __call__(self, x): 192 if callable(x): 193 # Used as function decorator => return the function unchanged. 194 return x 195 # Used as conditional context manager or to create an "@nogil(True/False)" decorator => keep going. 196 return self 197 198 def __enter__(self): 199 pass 200 def __exit__(self, exc_class, exc, tb): 201 return exc_class is None 202 203nogil = _nogil() 204gil = _nogil() 205del _nogil 206 207 208# Emulated types 209 210class CythonMetaType(type): 211 212 def __getitem__(type, ix): 213 return array(type, ix) 214 215CythonTypeObject = CythonMetaType('CythonTypeObject', (object,), {}) 216 217class CythonType(CythonTypeObject): 218 219 def _pointer(self, n=1): 220 for i in range(n): 221 self = pointer(self) 222 return self 223 224class PointerType(CythonType): 225 226 def __init__(self, value=None): 227 if isinstance(value, (ArrayType, PointerType)): 228 self._items = [cast(self._basetype, a) for a in value._items] 229 elif isinstance(value, list): 230 self._items = [cast(self._basetype, a) for a in value] 231 elif value is None or value == 0: 232 self._items = [] 233 else: 234 raise ValueError 235 236 def __getitem__(self, ix): 237 if ix < 0: 238 raise IndexError("negative indexing not allowed in C") 239 return self._items[ix] 240 241 def __setitem__(self, ix, value): 242 if ix < 0: 243 raise IndexError("negative indexing not allowed in C") 244 self._items[ix] = cast(self._basetype, value) 245 246 def __eq__(self, value): 247 if value is None and not self._items: 248 return True 249 elif type(self) != type(value): 250 return False 251 else: 252 return not self._items and not value._items 253 254 def __repr__(self): 255 return "%s *" % (self._basetype,) 256 257class ArrayType(PointerType): 258 259 def __init__(self): 260 self._items = [None] * self._n 261 262 263class StructType(CythonType): 264 265 def __init__(self, cast_from=_Unspecified, **data): 266 if cast_from is not _Unspecified: 267 # do cast 268 if len(data) > 0: 269 raise ValueError('Cannot accept keyword arguments when casting.') 270 if type(cast_from) is not type(self): 271 raise ValueError('Cannot cast from %s'%cast_from) 272 for key, value in cast_from.__dict__.items(): 273 setattr(self, key, value) 274 else: 275 for key, value in data.items(): 276 setattr(self, key, value) 277 278 def __setattr__(self, key, value): 279 if key in self._members: 280 self.__dict__[key] = cast(self._members[key], value) 281 else: 282 raise AttributeError("Struct has no member '%s'" % key) 283 284 285class UnionType(CythonType): 286 287 def __init__(self, cast_from=_Unspecified, **data): 288 if cast_from is not _Unspecified: 289 # do type cast 290 if len(data) > 0: 291 raise ValueError('Cannot accept keyword arguments when casting.') 292 if isinstance(cast_from, dict): 293 datadict = cast_from 294 elif type(cast_from) is type(self): 295 datadict = cast_from.__dict__ 296 else: 297 raise ValueError('Cannot cast from %s'%cast_from) 298 else: 299 datadict = data 300 if len(datadict) > 1: 301 raise AttributeError("Union can only store one field at a time.") 302 for key, value in datadict.items(): 303 setattr(self, key, value) 304 305 def __setattr__(self, key, value): 306 if key in '__dict__': 307 CythonType.__setattr__(self, key, value) 308 elif key in self._members: 309 self.__dict__ = {key: cast(self._members[key], value)} 310 else: 311 raise AttributeError("Union has no member '%s'" % key) 312 313def pointer(basetype): 314 class PointerInstance(PointerType): 315 _basetype = basetype 316 return PointerInstance 317 318def array(basetype, n): 319 class ArrayInstance(ArrayType): 320 _basetype = basetype 321 _n = n 322 return ArrayInstance 323 324def struct(**members): 325 class StructInstance(StructType): 326 _members = members 327 for key in members: 328 setattr(StructInstance, key, None) 329 return StructInstance 330 331def union(**members): 332 class UnionInstance(UnionType): 333 _members = members 334 for key in members: 335 setattr(UnionInstance, key, None) 336 return UnionInstance 337 338class typedef(CythonType): 339 340 def __init__(self, type, name=None): 341 self._basetype = type 342 self.name = name 343 344 def __call__(self, *arg): 345 value = cast(self._basetype, *arg) 346 return value 347 348 def __repr__(self): 349 return self.name or str(self._basetype) 350 351 __getitem__ = index_type 352 353class _FusedType(CythonType): 354 pass 355 356 357def fused_type(*args): 358 if not args: 359 raise TypeError("Expected at least one type as argument") 360 361 # Find the numeric type with biggest rank if all types are numeric 362 rank = -1 363 for type in args: 364 if type not in (py_int, py_long, py_float, py_complex): 365 break 366 367 if type_ordering.index(type) > rank: 368 result_type = type 369 else: 370 return result_type 371 372 # Not a simple numeric type, return a fused type instance. The result 373 # isn't really meant to be used, as we can't keep track of the context in 374 # pure-mode. Casting won't do anything in this case. 375 return _FusedType() 376 377 378def _specialized_from_args(signatures, args, kwargs): 379 "Perhaps this should be implemented in a TreeFragment in Cython code" 380 raise Exception("yet to be implemented") 381 382 383py_int = typedef(int, "int") 384try: 385 py_long = typedef(long, "long") 386except NameError: # Py3 387 py_long = typedef(int, "long") 388py_float = typedef(float, "float") 389py_complex = typedef(complex, "double complex") 390 391 392# Predefined types 393 394int_types = ['char', 'short', 'Py_UNICODE', 'int', 'Py_UCS4', 'long', 'longlong', 'Py_ssize_t', 'size_t'] 395float_types = ['longdouble', 'double', 'float'] 396complex_types = ['longdoublecomplex', 'doublecomplex', 'floatcomplex', 'complex'] 397other_types = ['bint', 'void', 'Py_tss_t'] 398 399to_repr = { 400 'longlong': 'long long', 401 'longdouble': 'long double', 402 'longdoublecomplex': 'long double complex', 403 'doublecomplex': 'double complex', 404 'floatcomplex': 'float complex', 405}.get 406 407gs = globals() 408 409# note: cannot simply name the unicode type here as 2to3 gets in the way and replaces it by str 410try: 411 import __builtin__ as builtins 412except ImportError: # Py3 413 import builtins 414 415gs['unicode'] = typedef(getattr(builtins, 'unicode', str), 'unicode') 416del builtins 417 418for name in int_types: 419 reprname = to_repr(name, name) 420 gs[name] = typedef(py_int, reprname) 421 if name not in ('Py_UNICODE', 'Py_UCS4') and not name.endswith('size_t'): 422 gs['u'+name] = typedef(py_int, "unsigned " + reprname) 423 gs['s'+name] = typedef(py_int, "signed " + reprname) 424 425for name in float_types: 426 gs[name] = typedef(py_float, to_repr(name, name)) 427 428for name in complex_types: 429 gs[name] = typedef(py_complex, to_repr(name, name)) 430 431bint = typedef(bool, "bint") 432void = typedef(None, "void") 433Py_tss_t = typedef(None, "Py_tss_t") 434 435for t in int_types + float_types + complex_types + other_types: 436 for i in range(1, 4): 437 gs["%s_%s" % ('p'*i, t)] = gs[t]._pointer(i) 438 439NULL = gs['p_void'](0) 440 441# looks like 'gs' has some users out there by now... 442#del gs 443 444integral = floating = numeric = _FusedType() 445 446type_ordering = [py_int, py_long, py_float, py_complex] 447 448class CythonDotParallel(object): 449 """ 450 The cython.parallel module. 451 """ 452 453 __all__ = ['parallel', 'prange', 'threadid'] 454 455 def parallel(self, num_threads=None): 456 return nogil 457 458 def prange(self, start=0, stop=None, step=1, nogil=False, schedule=None, chunksize=None, num_threads=None): 459 if stop is None: 460 stop = start 461 start = 0 462 return range(start, stop, step) 463 464 def threadid(self): 465 return 0 466 467 # def threadsavailable(self): 468 # return 1 469 470import sys 471sys.modules['cython.parallel'] = CythonDotParallel() 472del sys 473