1from numba.core.types.abstract import Callable, Literal, Type 2from numba.core.types.common import (Dummy, IterableType, Opaque, 3 SimpleIteratorType) 4from numba.core.typeconv import Conversion 5from numba.core.errors import TypingError, LiteralTypingError 6 7 8class PyObject(Dummy): 9 """ 10 A generic CPython object. 11 """ 12 13 def is_precise(self): 14 return False 15 16 17class Phantom(Dummy): 18 """ 19 A type that cannot be materialized. A Phantom cannot be used as 20 argument or return type. 21 """ 22 23 24class Undefined(Dummy): 25 """ 26 A type that is left imprecise. This is used as a temporaray placeholder 27 during type inference in the hope that the type can be later refined. 28 """ 29 30 def is_precise(self): 31 return False 32 33 34class RawPointer(Opaque): 35 """ 36 A raw pointer without any specific meaning. 37 """ 38 39 40class StringLiteral(Literal, Dummy): 41 pass 42 43 44Literal.ctor_map[str] = StringLiteral 45 46 47def unliteral(lit_type): 48 """ 49 Get base type from Literal type. 50 """ 51 if hasattr(lit_type, '__unliteral__'): 52 return lit_type.__unliteral__() 53 return getattr(lit_type, 'literal_type', lit_type) 54 55 56def literal(value): 57 """Returns a Literal instance or raise LiteralTypingError 58 """ 59 ty = type(value) 60 if isinstance(value, Literal): 61 msg = "the function does not accept a Literal type; got {} ({})" 62 raise ValueError(msg.format(value, ty)) 63 try: 64 ctor = Literal.ctor_map[ty] 65 except KeyError: 66 raise LiteralTypingError("{} cannot be used as a literal".format(ty)) 67 else: 68 return ctor(value) 69 70 71def maybe_literal(value): 72 """Get a Literal type for the value or None. 73 """ 74 try: 75 return literal(value) 76 except LiteralTypingError: 77 return 78 79 80class Omitted(Opaque): 81 """ 82 An omitted function argument with a default value. 83 """ 84 85 def __init__(self, value): 86 self._value = value 87 super(Omitted, self).__init__("omitted(default=%r)" % (value,)) 88 89 @property 90 def key(self): 91 return type(self._value), id(self._value) 92 93 @property 94 def value(self): 95 return self._value 96 97 98class VarArg(Type): 99 """ 100 Special type representing a variable number of arguments at the 101 end of a function's signature. Only used for signature matching, 102 not for actual values. 103 """ 104 105 def __init__(self, dtype): 106 self.dtype = dtype 107 super(VarArg, self).__init__("*%s" % dtype) 108 109 @property 110 def key(self): 111 return self.dtype 112 113 114class Module(Dummy): 115 def __init__(self, pymod): 116 self.pymod = pymod 117 super(Module, self).__init__("Module(%s)" % pymod) 118 119 @property 120 def key(self): 121 return self.pymod 122 123 124class Macro(Type): 125 def __init__(self, template): 126 self.template = template 127 cls = type(self) 128 super(Macro, self).__init__("%s(%s)" % (cls.__name__, template)) 129 130 @property 131 def key(self): 132 return self.template 133 134 135class MemInfoPointer(Type): 136 """ 137 Pointer to a Numba "meminfo" (i.e. the information for a managed 138 piece of memory). 139 """ 140 mutable = True 141 142 def __init__(self, dtype): 143 self.dtype = dtype 144 name = "memory-managed *%s" % dtype 145 super(MemInfoPointer, self).__init__(name) 146 147 @property 148 def key(self): 149 return self.dtype 150 151 152class CPointer(Type): 153 """ 154 Type class for pointers to other types. 155 """ 156 mutable = True 157 158 def __init__(self, dtype): 159 self.dtype = dtype 160 name = "%s*" % dtype 161 super(CPointer, self).__init__(name) 162 163 @property 164 def key(self): 165 return self.dtype 166 167 168class EphemeralPointer(CPointer): 169 """ 170 Type class for pointers which aren't guaranteed to last long - e.g. 171 stack-allocated slots. The data model serializes such pointers 172 by copying the data pointed to. 173 """ 174 175 176class EphemeralArray(Type): 177 """ 178 Similar to EphemeralPointer, but pointing to an array of elements, 179 rather than a single one. The array size must be known at compile-time. 180 """ 181 182 def __init__(self, dtype, count): 183 self.dtype = dtype 184 self.count = count 185 name = "*%s[%d]" % (dtype, count) 186 super(EphemeralArray, self).__init__(name) 187 188 @property 189 def key(self): 190 return self.dtype, self.count 191 192 193class Object(Type): 194 # XXX unused? 195 mutable = True 196 197 def __init__(self, clsobj): 198 self.cls = clsobj 199 name = "Object(%s)" % clsobj.__name__ 200 super(Object, self).__init__(name) 201 202 @property 203 def key(self): 204 return self.cls 205 206 207class Optional(Type): 208 """ 209 Type class for optional types, i.e. union { some type, None } 210 """ 211 212 def __init__(self, typ): 213 assert not isinstance(typ, (Optional, NoneType)) 214 typ = unliteral(typ) 215 self.type = typ 216 name = "OptionalType(%s)" % self.type 217 super(Optional, self).__init__(name) 218 219 def __str__(self): 220 return "%s i.e. the type '%s or None'" % (self.name, self.type) 221 222 @property 223 def key(self): 224 return self.type 225 226 def can_convert_to(self, typingctx, other): 227 if isinstance(other, Optional): 228 return typingctx.can_convert(self.type, other.type) 229 else: 230 conv = typingctx.can_convert(self.type, other) 231 if conv is not None: 232 return max(conv, Conversion.safe) 233 234 def can_convert_from(self, typingctx, other): 235 if isinstance(other, NoneType): 236 return Conversion.promote 237 elif isinstance(other, Optional): 238 return typingctx.can_convert(other.type, self.type) 239 else: 240 conv = typingctx.can_convert(other, self.type) 241 if conv is not None: 242 return max(conv, Conversion.promote) 243 244 def unify(self, typingctx, other): 245 if isinstance(other, Optional): 246 unified = typingctx.unify_pairs(self.type, other.type) 247 else: 248 unified = typingctx.unify_pairs(self.type, other) 249 250 if unified is not None: 251 if isinstance(unified, Optional): 252 return unified 253 else: 254 return Optional(unified) 255 256 257class NoneType(Opaque): 258 """ 259 The type for None. 260 """ 261 262 def unify(self, typingctx, other): 263 """ 264 Turn anything to a Optional type; 265 """ 266 if isinstance(other, (Optional, NoneType)): 267 return other 268 return Optional(other) 269 270 271class EllipsisType(Opaque): 272 """ 273 The type for the Ellipsis singleton. 274 """ 275 276 277class ExceptionClass(Callable, Phantom): 278 """ 279 The type of exception classes (not instances). 280 """ 281 282 def __init__(self, exc_class): 283 assert issubclass(exc_class, BaseException) 284 name = "%s" % (exc_class.__name__) 285 self.exc_class = exc_class 286 super(ExceptionClass, self).__init__(name) 287 288 def get_call_type(self, context, args, kws): 289 return self.get_call_signatures()[0][0] 290 291 def get_call_signatures(self): 292 from numba.core import typing 293 return_type = ExceptionInstance(self.exc_class) 294 return [typing.signature(return_type)], False 295 296 @property 297 def key(self): 298 return self.exc_class 299 300 301class ExceptionInstance(Phantom): 302 """ 303 The type of exception instances. *exc_class* should be the 304 exception class. 305 """ 306 307 def __init__(self, exc_class): 308 assert issubclass(exc_class, BaseException) 309 name = "%s(...)" % (exc_class.__name__,) 310 self.exc_class = exc_class 311 super(ExceptionInstance, self).__init__(name) 312 313 @property 314 def key(self): 315 return self.exc_class 316 317 318class SliceType(Type): 319 320 def __init__(self, name, members): 321 assert members in (2, 3) 322 self.members = members 323 self.has_step = members >= 3 324 super(SliceType, self).__init__(name) 325 326 @property 327 def key(self): 328 return self.members 329 330 331class SliceLiteral(Literal, SliceType): 332 def __init__(self, value): 333 self._literal_init(value) 334 name = 'Literal[slice]({})'.format(value) 335 members = 2 if value.step is None else 3 336 SliceType.__init__(self, name=name, members=members) 337 338 339Literal.ctor_map[slice] = SliceLiteral 340 341 342class ClassInstanceType(Type): 343 """ 344 The type of a jitted class *instance*. It will be the return-type 345 of the constructor of the class. 346 """ 347 mutable = True 348 name_prefix = "instance" 349 350 def __init__(self, class_type): 351 self.class_type = class_type 352 name = "{0}.{1}".format(self.name_prefix, self.class_type.name) 353 super(ClassInstanceType, self).__init__(name) 354 355 def get_data_type(self): 356 return ClassDataType(self) 357 358 def get_reference_type(self): 359 return self 360 361 @property 362 def key(self): 363 return self.class_type.key 364 365 @property 366 def classname(self): 367 return self.class_type.class_name 368 369 @property 370 def jit_props(self): 371 return self.class_type.jit_props 372 373 @property 374 def jit_static_methods(self): 375 return self.class_type.jit_static_methods 376 377 @property 378 def jit_methods(self): 379 return self.class_type.jit_methods 380 381 @property 382 def struct(self): 383 return self.class_type.struct 384 385 @property 386 def methods(self): 387 return self.class_type.methods 388 389 @property 390 def static_methods(self): 391 return self.class_type.static_methods 392 393 394class ClassType(Callable, Opaque): 395 """ 396 The type of the jitted class (not instance). When the type of a class 397 is called, its constructor is invoked. 398 """ 399 mutable = True 400 name_prefix = "jitclass" 401 instance_type_class = ClassInstanceType 402 403 def __init__(self, class_def, ctor_template_cls, struct, jit_methods, 404 jit_props, jit_static_methods): 405 self.class_name = class_def.__name__ 406 self.class_doc = class_def.__doc__ 407 self._ctor_template_class = ctor_template_cls 408 self.jit_methods = jit_methods 409 self.jit_props = jit_props 410 self.jit_static_methods = jit_static_methods 411 self.struct = struct 412 fielddesc = ','.join("{0}:{1}".format(k, v) for k, v in struct.items()) 413 name = "{0}.{1}#{2:x}<{3}>".format(self.name_prefix, self.class_name, 414 id(self), fielddesc) 415 super(ClassType, self).__init__(name) 416 417 def get_call_type(self, context, args, kws): 418 return self.ctor_template(context).apply(args, kws) 419 420 def get_call_signatures(self): 421 return (), True 422 423 @property 424 def methods(self): 425 return {k: v.py_func for k, v in self.jit_methods.items()} 426 427 @property 428 def static_methods(self): 429 return {k: v.py_func for k, v in self.jit_static_methods.items()} 430 431 @property 432 def instance_type(self): 433 return ClassInstanceType(self) 434 435 @property 436 def ctor_template(self): 437 return self._specialize_template(self._ctor_template_class) 438 439 def _specialize_template(self, basecls): 440 return type(basecls.__name__, (basecls,), dict(key=self)) 441 442 443class DeferredType(Type): 444 """ 445 Represents a type that will be defined later. It must be defined 446 before it is materialized (used in the compiler). Once defined, it 447 behaves exactly as the type it is defining. 448 """ 449 450 def __init__(self): 451 self._define = None 452 name = "{0}#{1}".format(type(self).__name__, id(self)) 453 super(DeferredType, self).__init__(name) 454 455 def get(self): 456 if self._define is None: 457 raise RuntimeError("deferred type not defined") 458 return self._define 459 460 def define(self, typ): 461 if self._define is not None: 462 raise TypeError("deferred type already defined") 463 if not isinstance(typ, Type): 464 raise TypeError("arg is not a Type; got: {0}".format(type(typ))) 465 self._define = typ 466 467 def unify(self, typingctx, other): 468 return typingctx.unify_pairs(self.get(), other) 469 470 471class ClassDataType(Type): 472 """ 473 Internal only. 474 Represents the data of the instance. The representation of 475 ClassInstanceType contains a pointer to a ClassDataType which represents 476 a C structure that contains all the data fields of the class instance. 477 """ 478 479 def __init__(self, classtyp): 480 self.class_type = classtyp 481 name = "data.{0}".format(self.class_type.name) 482 super(ClassDataType, self).__init__(name) 483 484 485class ContextManager(Callable, Phantom): 486 """ 487 An overly-simple ContextManager type that cannot be materialized. 488 """ 489 490 def __init__(self, cm): 491 self.cm = cm 492 super(ContextManager, self).__init__("ContextManager({})".format(cm)) 493 494 def get_call_signatures(self): 495 if not self.cm.is_callable: 496 msg = "contextmanager {} is not callable".format(self.cm) 497 raise TypingError(msg) 498 499 return (), False 500 501 def get_call_type(self, context, args, kws): 502 from numba.core import typing 503 504 if not self.cm.is_callable: 505 msg = "contextmanager {} is not callable".format(self.cm) 506 raise TypingError(msg) 507 508 posargs = list(args) + [v for k, v in sorted(kws.items())] 509 return typing.signature(self, *posargs) 510 511 512class UnicodeType(IterableType): 513 514 def __init__(self, name): 515 super(UnicodeType, self).__init__(name) 516 517 @property 518 def iterator_type(self): 519 return UnicodeIteratorType(self) 520 521 522class UnicodeIteratorType(SimpleIteratorType): 523 524 def __init__(self, dtype): 525 name = "iter_unicode" 526 self.data = dtype 527 super(UnicodeIteratorType, self).__init__(name, dtype) 528