1# cython.* namespace for pure mode. 2from __future__ import absolute_import 3 4__version__ = "3.0.0a9" 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 return 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() 119optimize = _Optimization() 120 121overflowcheck.fold = optimize.use_switch = \ 122 optimize.unpack_method_calls = lambda arg: _EmptyDecoratorAndManager() 123 124final = internal = type_version_tag = no_gc_clear = no_gc = total_ordering = _empty_decorator 125 126binding = lambda _: _empty_decorator 127 128 129_cython_inline = None 130def inline(f, *args, **kwds): 131 if isinstance(f, basestring): 132 global _cython_inline 133 if _cython_inline is None: 134 from Cython.Build.Inline import cython_inline as _cython_inline 135 return _cython_inline(f, *args, **kwds) 136 else: 137 assert len(args) == len(kwds) == 0 138 return f 139 140 141def compile(f): 142 from Cython.Build.Inline import RuntimeCompiledFunction 143 return RuntimeCompiledFunction(f) 144 145 146# Special functions 147 148def cdiv(a, b): 149 if a < 0: 150 a = -a 151 b = -b 152 if b < 0: 153 return (a + b + 1) // b 154 return a // b 155 156def cmod(a, b): 157 r = a % b 158 if (a * b) < 0 and r: 159 r -= b 160 return r 161 162 163# Emulated language constructs 164 165def cast(t, *args, **kwargs): 166 kwargs.pop('typecheck', None) 167 assert not kwargs 168 169 if isinstance(t, typedef): 170 return t(*args) 171 elif isinstance(t, type): # Doesn't work with old-style classes of Python 2.x 172 if len(args) != 1 or not (args[0] is None or isinstance(args[0], t)): 173 return t(*args) 174 175 return args[0] 176 177def sizeof(arg): 178 return 1 179 180def typeof(arg): 181 return arg.__class__.__name__ 182 # return type(arg) 183 184def address(arg): 185 return pointer(type(arg))([arg]) 186 187def _is_value_type(t): 188 if isinstance(t, typedef): 189 return _is_value_type(t._basetype) 190 191 return isinstance(t, type) and issubclass(t, (StructType, UnionType, ArrayType)) 192 193def declare(t=None, value=_Unspecified, **kwds): 194 if value is not _Unspecified: 195 return cast(t, value) 196 elif _is_value_type(t): 197 return t() 198 else: 199 return None 200 201class _nogil(object): 202 """Support for 'with nogil' statement and @nogil decorator. 203 """ 204 def __call__(self, x): 205 if callable(x): 206 # Used as function decorator => return the function unchanged. 207 return x 208 # Used as conditional context manager or to create an "@nogil(True/False)" decorator => keep going. 209 return self 210 211 def __enter__(self): 212 pass 213 def __exit__(self, exc_class, exc, tb): 214 return exc_class is None 215 216nogil = _nogil() 217gil = _nogil() 218del _nogil 219 220 221# Emulated types 222 223class CythonMetaType(type): 224 225 def __getitem__(type, ix): 226 return array(type, ix) 227 228CythonTypeObject = CythonMetaType('CythonTypeObject', (object,), {}) 229 230class CythonType(CythonTypeObject): 231 232 def _pointer(self, n=1): 233 for i in range(n): 234 self = pointer(self) 235 return self 236 237class PointerType(CythonType): 238 239 def __init__(self, value=None): 240 if isinstance(value, (ArrayType, PointerType)): 241 self._items = [cast(self._basetype, a) for a in value._items] 242 elif isinstance(value, list): 243 self._items = [cast(self._basetype, a) for a in value] 244 elif value is None or value == 0: 245 self._items = [] 246 else: 247 raise ValueError 248 249 def __getitem__(self, ix): 250 if ix < 0: 251 raise IndexError("negative indexing not allowed in C") 252 return self._items[ix] 253 254 def __setitem__(self, ix, value): 255 if ix < 0: 256 raise IndexError("negative indexing not allowed in C") 257 self._items[ix] = cast(self._basetype, value) 258 259 def __eq__(self, value): 260 if value is None and not self._items: 261 return True 262 elif type(self) != type(value): 263 return False 264 else: 265 return not self._items and not value._items 266 267 def __repr__(self): 268 return "%s *" % (self._basetype,) 269 270class ArrayType(PointerType): 271 272 def __init__(self, value=None): 273 if value is None: 274 self._items = [None] * self._n 275 else: 276 super(ArrayType, self).__init__(value) 277 278 279class StructType(CythonType): 280 281 def __init__(self, *posargs, **data): 282 if not (posargs or data): 283 return 284 if posargs and data: 285 raise ValueError('Cannot accept both positional and keyword arguments.') 286 287 # Allow 'cast_from' as single positional or keyword argument. 288 if data and len(data) == 1 and 'cast_from' in data: 289 cast_from = data.pop('cast_from') 290 elif len(posargs) == 1 and type(posargs[0]) is type(self): 291 cast_from, posargs = posargs[0], () 292 elif posargs: 293 for key, arg in zip(self._members, posargs): 294 setattr(self, key, arg) 295 return 296 else: 297 for key, value in data.items(): 298 if key not in self._members: 299 raise ValueError("Invalid struct attribute for %s: %s" % ( 300 self.__class__.__name__, key)) 301 setattr(self, key, value) 302 return 303 304 # do cast 305 if data: 306 raise ValueError('Cannot accept keyword arguments when casting.') 307 if type(cast_from) is not type(self): 308 raise ValueError('Cannot cast from %s' % cast_from) 309 for key, value in cast_from.__dict__.items(): 310 setattr(self, key, value) 311 312 def __setattr__(self, key, value): 313 if key in self._members: 314 self.__dict__[key] = cast(self._members[key], value) 315 else: 316 raise AttributeError("Struct has no member '%s'" % key) 317 318 319class UnionType(CythonType): 320 321 def __init__(self, cast_from=_Unspecified, **data): 322 if cast_from is not _Unspecified: 323 # do type cast 324 if len(data) > 0: 325 raise ValueError('Cannot accept keyword arguments when casting.') 326 if isinstance(cast_from, dict): 327 datadict = cast_from 328 elif type(cast_from) is type(self): 329 datadict = cast_from.__dict__ 330 else: 331 raise ValueError('Cannot cast from %s' % cast_from) 332 else: 333 datadict = data 334 if len(datadict) > 1: 335 raise AttributeError("Union can only store one field at a time.") 336 for key, value in datadict.items(): 337 setattr(self, key, value) 338 339 def __setattr__(self, key, value): 340 if key in '__dict__': 341 CythonType.__setattr__(self, key, value) 342 elif key in self._members: 343 self.__dict__ = {key: cast(self._members[key], value)} 344 else: 345 raise AttributeError("Union has no member '%s'" % key) 346 347def pointer(basetype): 348 class PointerInstance(PointerType): 349 _basetype = basetype 350 return PointerInstance 351 352def array(basetype, n): 353 class ArrayInstance(ArrayType): 354 _basetype = basetype 355 _n = n 356 return ArrayInstance 357 358def struct(**members): 359 class StructInstance(StructType): 360 _members = members 361 for key in members: 362 setattr(StructInstance, key, None) 363 return StructInstance 364 365def union(**members): 366 class UnionInstance(UnionType): 367 _members = members 368 for key in members: 369 setattr(UnionInstance, key, None) 370 return UnionInstance 371 372class typedef(CythonType): 373 374 def __init__(self, type, name=None): 375 self._basetype = type 376 self.name = name 377 378 def __call__(self, *arg): 379 value = cast(self._basetype, *arg) 380 return value 381 382 def __repr__(self): 383 return self.name or str(self._basetype) 384 385 __getitem__ = index_type 386 387class _FusedType(CythonType): 388 pass 389 390 391def fused_type(*args): 392 if not args: 393 raise TypeError("Expected at least one type as argument") 394 395 # Find the numeric type with biggest rank if all types are numeric 396 rank = -1 397 for type in args: 398 if type not in (py_int, py_long, py_float, py_complex): 399 break 400 401 if type_ordering.index(type) > rank: 402 result_type = type 403 else: 404 return result_type 405 406 # Not a simple numeric type, return a fused type instance. The result 407 # isn't really meant to be used, as we can't keep track of the context in 408 # pure-mode. Casting won't do anything in this case. 409 return _FusedType() 410 411 412def _specialized_from_args(signatures, args, kwargs): 413 "Perhaps this should be implemented in a TreeFragment in Cython code" 414 raise Exception("yet to be implemented") 415 416 417py_int = typedef(int, "int") 418try: 419 py_long = typedef(long, "long") 420except NameError: # Py3 421 py_long = typedef(int, "long") 422py_float = typedef(float, "float") 423py_complex = typedef(complex, "double complex") 424 425 426# Predefined types 427 428int_types = [ 429 'char', 430 'short', 431 'Py_UNICODE', 432 'int', 433 'Py_UCS4', 434 'long', 435 'longlong', 436 'Py_hash_t', 437 'Py_ssize_t', 438 'size_t', 439] 440float_types = [ 441 'longdouble', 442 'double', 443 'float', 444] 445complex_types = [ 446 'longdoublecomplex', 447 'doublecomplex', 448 'floatcomplex', 449 'complex', 450] 451other_types = [ 452 'bint', 453 'void', 454 'Py_tss_t', 455] 456 457to_repr = { 458 'longlong': 'long long', 459 'longdouble': 'long double', 460 'longdoublecomplex': 'long double complex', 461 'doublecomplex': 'double complex', 462 'floatcomplex': 'float complex', 463}.get 464 465gs = globals() 466 467# note: cannot simply name the unicode type here as 2to3 gets in the way and replaces it by str 468try: 469 import __builtin__ as builtins 470except ImportError: # Py3 471 import builtins 472 473gs['unicode'] = typedef(getattr(builtins, 'unicode', str), 'unicode') 474del builtins 475 476for name in int_types: 477 reprname = to_repr(name, name) 478 gs[name] = typedef(py_int, reprname) 479 if name not in ('Py_UNICODE', 'Py_UCS4') and not name.endswith('size_t'): 480 gs['u'+name] = typedef(py_int, "unsigned " + reprname) 481 gs['s'+name] = typedef(py_int, "signed " + reprname) 482 483for name in float_types: 484 gs[name] = typedef(py_float, to_repr(name, name)) 485 486for name in complex_types: 487 gs[name] = typedef(py_complex, to_repr(name, name)) 488 489bint = typedef(bool, "bint") 490void = typedef(None, "void") 491Py_tss_t = typedef(None, "Py_tss_t") 492 493for t in int_types + float_types + complex_types + other_types: 494 for i in range(1, 4): 495 gs["%s_%s" % ('p'*i, t)] = gs[t]._pointer(i) 496 497NULL = gs['p_void'](0) 498 499# looks like 'gs' has some users out there by now... 500#del gs 501 502integral = floating = numeric = _FusedType() 503 504type_ordering = [py_int, py_long, py_float, py_complex] 505 506class CythonDotParallel(object): 507 """ 508 The cython.parallel module. 509 """ 510 511 __all__ = ['parallel', 'prange', 'threadid'] 512 513 def parallel(self, num_threads=None): 514 return nogil 515 516 def prange(self, start=0, stop=None, step=1, nogil=False, schedule=None, chunksize=None, num_threads=None): 517 if stop is None: 518 stop = start 519 start = 0 520 return range(start, stop, step) 521 522 def threadid(self): 523 return 0 524 525 # def threadsavailable(self): 526 # return 1 527 528 529class CythonCImports(object): 530 """ 531 Simplistic module mock to make cimports sort-of work in Python code. 532 """ 533 def __init__(self, module): 534 self.__path__ = [] 535 self.__file__ = None 536 self.__name__ = module 537 self.__package__ = module 538 539 def __getattr__(self, item): 540 if item.startswith('__') and item.endswith('__'): 541 raise AttributeError(item) 542 return __import__(item) 543 544 545import math, sys 546sys.modules['cython.parallel'] = CythonDotParallel() 547sys.modules['cython.cimports'] = CythonCImports('cython.cimports') 548sys.modules['cython.cimports.libc'] = CythonCImports('cython.cimports.libc') 549sys.modules['cython.cimports.libc.math'] = math 550del math, sys 551