Cython has moved to github.
cython-devel
view Cython/Compiler/PyrexTypes.py @ 3080:982665cb1a01
casting to typedef pointer/array types (ticket #518)
| author | Lisandro Dalcin <dalcinl@gmail.com> |
|---|---|
| date | Wed Mar 10 17:03:40 2010 -0300 (2 years ago) |
| parents | 3345e2713fcb |
| children | 1a2e04bc1395 b7ff459dc469 |
line source
3 #
4 # Pyrex - Types
5 #
7 from Code import UtilityCode
8 import StringEncoding
9 import Naming
10 import copy
11 from Errors import error
13 class BaseType(object):
14 #
15 # Base class for all Pyrex types including pseudo-types.
17 def can_coerce_to_pyobject(self, env):
18 return False
20 def cast_code(self, expr_code):
21 return "((%s)%s)" % (self.declaration_code(""), expr_code)
23 def specalization_name(self):
24 return self.declaration_code("").replace(" ", "__")
26 def base_declaration_code(self, base_code, entity_code):
27 if entity_code:
28 return "%s %s" % (base_code, entity_code)
29 else:
30 return base_code
32 class PyrexType(BaseType):
33 #
34 # Base class for all Pyrex types.
35 #
36 # is_pyobject boolean Is a Python object type
37 # is_extension_type boolean Is a Python extension type
38 # is_numeric boolean Is a C numeric type
39 # is_int boolean Is a C integer type
40 # is_float boolean Is a C floating point type
41 # is_complex boolean Is a C complex type
42 # is_void boolean Is the C void type
43 # is_array boolean Is a C array type
44 # is_ptr boolean Is a C pointer type
45 # is_null_ptr boolean Is the type of NULL
46 # is_reference boolean Is a C reference type
47 # is_cfunction boolean Is a C function type
48 # is_struct_or_union boolean Is a C struct or union type
49 # is_struct boolean Is a C struct type
50 # is_enum boolean Is a C enum type
51 # is_typedef boolean Is a typedef type
52 # is_string boolean Is a C char * type
53 # is_unicode boolean Is a UTF-8 encoded C char * type
54 # is_returncode boolean Is used only to signal exceptions
55 # is_error boolean Is the dummy error type
56 # is_buffer boolean Is buffer access type
57 # has_attributes boolean Has C dot-selectable attributes
58 # default_value string Initial value
59 # pymemberdef_typecode string Type code for PyMemberDef struct
60 #
61 # declaration_code(entity_code,
62 # for_display = 0, dll_linkage = None, pyrex = 0)
63 # Returns a code fragment for the declaration of an entity
64 # of this type, given a code fragment for the entity.
65 # * If for_display, this is for reading by a human in an error
66 # message; otherwise it must be valid C code.
67 # * If dll_linkage is not None, it must be 'DL_EXPORT' or
68 # 'DL_IMPORT', and will be added to the base type part of
69 # the declaration.
70 # * If pyrex = 1, this is for use in a 'cdef extern'
71 # statement of a Pyrex include file.
72 #
73 # assignable_from(src_type)
74 # Tests whether a variable of this type can be
75 # assigned a value of type src_type.
76 #
77 # same_as(other_type)
78 # Tests whether this type represents the same type
79 # as other_type.
80 #
81 # as_argument_type():
82 # Coerces array type into pointer type for use as
83 # a formal argument type.
84 #
86 is_pyobject = 0
87 is_unspecified = 0
88 is_extension_type = 0
89 is_builtin_type = 0
90 is_numeric = 0
91 is_int = 0
92 is_float = 0
93 is_complex = 0
94 is_void = 0
95 is_array = 0
96 is_ptr = 0
97 is_null_ptr = 0
98 is_reference = 0
99 is_cfunction = 0
100 is_struct_or_union = 0
101 is_cpp_class = 0
102 is_struct = 0
103 is_enum = 0
104 is_typedef = 0
105 is_string = 0
106 is_unicode = 0
107 is_returncode = 0
108 is_error = 0
109 is_buffer = 0
110 has_attributes = 0
111 default_value = ""
112 pymemberdef_typecode = None
114 def resolve(self):
115 # If a typedef, returns the base type.
116 return self
118 def specialize(self, values):
119 # TODO(danilo): Override wherever it makes sense.
120 return self
122 def literal_code(self, value):
123 # Returns a C code fragment representing a literal
124 # value of this type.
125 return str(value)
127 def __str__(self):
128 return self.declaration_code("", for_display = 1).strip()
130 def same_as(self, other_type, **kwds):
131 return self.same_as_resolved_type(other_type.resolve(), **kwds)
133 def same_as_resolved_type(self, other_type):
134 return self == other_type or other_type is error_type
136 def subtype_of(self, other_type):
137 return self.subtype_of_resolved_type(other_type.resolve())
139 def subtype_of_resolved_type(self, other_type):
140 return self.same_as(other_type)
142 def assignable_from(self, src_type):
143 return self.assignable_from_resolved_type(src_type.resolve())
145 def assignable_from_resolved_type(self, src_type):
146 return self.same_as(src_type)
148 def as_argument_type(self):
149 return self
151 def is_complete(self):
152 # A type is incomplete if it is an unsized array,
153 # a struct whose attributes are not defined, etc.
154 return 1
156 def is_simple_buffer_dtype(self):
157 return (self.is_int or self.is_float or self.is_complex or self.is_pyobject or
158 self.is_extension_type or self.is_ptr)
160 def struct_nesting_depth(self):
161 # Returns the number levels of nested structs. This is
162 # used for constructing a stack for walking the run-time
163 # type information of the struct.
164 return 1
167 def create_typedef_type(name, base_type, cname, is_external=0):
168 if base_type.is_complex:
169 if is_external:
170 raise ValueError("Complex external typedefs not supported")
171 return base_type
172 else:
173 return CTypedefType(name, base_type, cname, is_external)
175 class CTypedefType(BaseType):
176 #
177 # Pseudo-type defined with a ctypedef statement in a
178 # 'cdef extern from' block. Delegates most attribute
179 # lookups to the base type. ANYTHING NOT DEFINED
180 # HERE IS DELEGATED!
181 #
182 # qualified_name string
183 # typedef_name string
184 # typedef_cname string
185 # typedef_base_type PyrexType
186 # typedef_is_external bool
188 is_typedef = 1
189 typedef_is_external = 0
191 to_py_utility_code = None
192 from_py_utility_code = None
195 def __init__(self, name, base_type, cname, is_external=0):
196 assert not base_type.is_complex
197 self.typedef_name = name
198 self.typedef_cname = cname
199 self.typedef_base_type = base_type
200 self.typedef_is_external = is_external
201 # Make typecodes in external typedefs use typesize-neutral macros
202 if is_external:
203 typecode = None
204 if base_type.is_int:
205 if base_type.signed == 0:
206 typecode = "__Pyx_T_UNSIGNED_INT"
207 else:
208 typecode = "__Pyx_T_SIGNED_INT"
209 elif base_type.is_float and not rank_to_type_name[base_type.rank] == "long double":
210 typecode = "__Pyx_T_FLOATING"
211 if typecode:
212 self.pymemberdef_typecode = "%s(%s)" % (typecode, cname)
214 def resolve(self):
215 return self.typedef_base_type.resolve()
217 def declaration_code(self, entity_code,
218 for_display = 0, dll_linkage = None, pyrex = 0):
219 if pyrex or for_display:
220 base_code = self.typedef_name
221 else:
222 base_code = public_decl(self.typedef_cname, dll_linkage)
223 return self.base_declaration_code(base_code, entity_code)
225 def as_argument_type(self):
226 return self
228 def cast_code(self, expr_code):
229 # If self is really an array (rather than pointer), we can't cast.
230 # For example, the gmp mpz_t.
231 if self.typedef_base_type.is_array:
232 base_type = self.typedef_base_type.base_type
233 return CPtrType(base_type).cast_code(expr_code)
234 else:
235 return BaseType.cast_code(self, expr_code)
237 def __repr__(self):
238 return "<CTypedefType %s>" % self.typedef_cname
240 def __str__(self):
241 return self.typedef_name
243 def _create_utility_code(self, template_utility_code,
244 template_function_name):
245 type_name = self.typedef_cname.replace(" ","_")
246 utility_code = template_utility_code.specialize(
247 type = self.typedef_cname,
248 TypeName = type_name)
249 function_name = template_function_name % type_name
250 return utility_code, function_name
252 def create_to_py_utility_code(self, env):
253 if self.typedef_is_external:
254 if not self.to_py_utility_code:
255 base_type = self.typedef_base_type
256 if base_type.is_int:
257 self.to_py_utility_code, self.to_py_function = \
258 self._create_utility_code(c_typedef_int_to_py_function,
259 '__Pyx_PyInt_to_py_%s')
260 elif base_type.is_float:
261 pass # XXX implement!
262 elif base_type.is_complex:
263 pass # XXX implement!
264 pass
265 if self.to_py_utility_code:
266 env.use_utility_code(self.to_py_utility_code)
267 return True
268 # delegation
269 return self.typedef_base_type.create_to_py_utility_code(env)
271 def create_from_py_utility_code(self, env):
272 if self.typedef_is_external:
273 if not self.from_py_utility_code:
274 base_type = self.typedef_base_type
275 if base_type.is_int:
276 self.from_py_utility_code, self.from_py_function = \
277 self._create_utility_code(c_typedef_int_from_py_function,
278 '__Pyx_PyInt_from_py_%s')
279 elif base_type.is_float:
280 pass # XXX implement!
281 elif base_type.is_complex:
282 pass # XXX implement!
283 if self.from_py_utility_code:
284 env.use_utility_code(self.from_py_utility_code)
285 return True
286 # delegation
287 return self.typedef_base_type.create_from_py_utility_code(env)
289 def error_condition(self, result_code):
290 if self.typedef_is_external:
291 if self.exception_value:
292 condition = "(%s == (%s)%s)" % (
293 result_code, self.typedef_cname, self.exception_value)
294 if self.exception_check:
295 condition += " && PyErr_Occurred()"
296 return condition
297 # delegation
298 return self.typedef_base_type.error_condition(result_code)
300 def __getattr__(self, name):
301 return getattr(self.typedef_base_type, name)
303 class BufferType(BaseType):
304 #
305 # Delegates most attribute
306 # lookups to the base type. ANYTHING NOT DEFINED
307 # HERE IS DELEGATED!
309 # dtype PyrexType
310 # ndim int
311 # mode str
312 # negative_indices bool
313 # cast bool
314 # is_buffer bool
315 # writable bool
317 is_buffer = 1
318 writable = True
319 def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
320 self.base = base
321 self.dtype = dtype
322 self.ndim = ndim
323 self.buffer_ptr_type = CPtrType(dtype)
324 self.mode = mode
325 self.negative_indices = negative_indices
326 self.cast = cast
328 def as_argument_type(self):
329 return self
331 def __getattr__(self, name):
332 return getattr(self.base, name)
334 def __repr__(self):
335 return "<BufferType %r>" % self.base
337 def public_decl(base, dll_linkage):
338 if dll_linkage:
339 return "%s(%s)" % (dll_linkage, base)
340 else:
341 return base
343 class PyObjectType(PyrexType):
344 #
345 # Base class for all Python object types (reference-counted).
346 #
347 # buffer_defaults dict or None Default options for bu
349 name = "object"
350 is_pyobject = 1
351 default_value = "0"
352 pymemberdef_typecode = "T_OBJECT"
353 buffer_defaults = None
354 is_extern = False
355 is_subclassed = False
357 def __str__(self):
358 return "Python object"
360 def __repr__(self):
361 return "<PyObjectType>"
363 def can_coerce_to_pyobject(self, env):
364 return True
366 def assignable_from(self, src_type):
367 # except for pointers, conversion will be attempted
368 return not src_type.is_ptr or src_type.is_string
370 def declaration_code(self, entity_code,
371 for_display = 0, dll_linkage = None, pyrex = 0):
372 if pyrex or for_display:
373 return self.base_declaration_code("object", entity_code)
374 else:
375 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
377 def as_pyobject(self, cname):
378 if (not self.is_complete()) or self.is_extension_type:
379 return "(PyObject *)" + cname
380 else:
381 return cname
383 class BuiltinObjectType(PyObjectType):
385 is_builtin_type = 1
386 has_attributes = 1
387 base_type = None
388 module_name = '__builtin__'
390 alternative_name = None # used for str/bytes duality
392 def __init__(self, name, cname):
393 self.name = name
394 if name == 'str':
395 self.alternative_name = 'bytes'
396 elif name == 'bytes':
397 self.alternative_name = 'str'
398 self.cname = cname
399 self.typeptr_cname = "&" + cname
401 def set_scope(self, scope):
402 self.scope = scope
403 if scope:
404 scope.parent_type = self
406 def __str__(self):
407 return "%s object" % self.name
409 def __repr__(self):
410 return "<%s>"% self.cname
412 def assignable_from(self, src_type):
413 if isinstance(src_type, BuiltinObjectType):
414 return src_type.name == self.name or (
415 src_type.name == self.alternative_name and
416 src_type.name is not None)
417 elif src_type.is_extension_type:
418 return (src_type.module_name == '__builtin__' and
419 src_type.name == self.name)
420 else:
421 return True
423 def typeobj_is_available(self):
424 return True
426 def attributes_known(self):
427 return True
429 def subtype_of(self, type):
430 return type.is_pyobject and self.assignable_from(type)
432 def type_test_code(self, arg, notnone=False):
433 type_name = self.name
434 if type_name == 'str':
435 type_check = 'PyString_CheckExact'
436 elif type_name == 'set':
437 type_check = 'PyAnySet_CheckExact'
438 elif type_name == 'frozenset':
439 type_check = 'PyFrozenSet_CheckExact'
440 elif type_name == 'bool':
441 type_check = 'PyBool_Check'
442 else:
443 type_check = 'Py%s_CheckExact' % type_name.capitalize()
445 check = 'likely(%s(%s))' % (type_check, arg)
446 if not notnone:
447 check = check + ('||((%s) == Py_None)' % arg)
448 error = '(PyErr_Format(PyExc_TypeError, "Expected %s, got %%.200s", Py_TYPE(%s)->tp_name), 0)' % (self.name, arg)
449 return check + '||' + error
451 def declaration_code(self, entity_code,
452 for_display = 0, dll_linkage = None, pyrex = 0):
453 if pyrex or for_display:
454 return self.base_declaration_code(self.name, entity_code)
455 else:
456 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
459 class PyExtensionType(PyObjectType):
460 #
461 # A Python extension type.
462 #
463 # name string
464 # scope CClassScope Attribute namespace
465 # visibility string
466 # typedef_flag boolean
467 # base_type PyExtensionType or None
468 # module_name string or None Qualified name of defining module
469 # objstruct_cname string Name of PyObject struct
470 # objtypedef_cname string Name of PyObject struct typedef
471 # typeobj_cname string or None C code fragment referring to type object
472 # typeptr_cname string or None Name of pointer to external type object
473 # vtabslot_cname string Name of C method table member
474 # vtabstruct_cname string Name of C method table struct
475 # vtabptr_cname string Name of pointer to C method table
476 # vtable_cname string Name of C method table definition
478 is_extension_type = 1
479 has_attributes = 1
481 objtypedef_cname = None
483 def __init__(self, name, typedef_flag, base_type, is_external=0):
484 self.name = name
485 self.scope = None
486 self.typedef_flag = typedef_flag
487 if base_type is not None:
488 base_type.is_subclassed = True
489 self.base_type = base_type
490 self.module_name = None
491 self.objstruct_cname = None
492 self.typeobj_cname = None
493 self.typeptr_cname = None
494 self.vtabslot_cname = None
495 self.vtabstruct_cname = None
496 self.vtabptr_cname = None
497 self.vtable_cname = None
498 self.is_external = is_external
500 def set_scope(self, scope):
501 self.scope = scope
502 if scope:
503 scope.parent_type = self
505 def subtype_of_resolved_type(self, other_type):
506 if other_type.is_extension_type:
507 return self is other_type or (
508 self.base_type and self.base_type.subtype_of(other_type))
509 else:
510 return other_type is py_object_type
512 def typeobj_is_available(self):
513 # Do we have a pointer to the type object?
514 return self.typeptr_cname
516 def typeobj_is_imported(self):
517 # If we don't know the C name of the type object but we do
518 # know which module it's defined in, it will be imported.
519 return self.typeobj_cname is None and self.module_name is not None
521 def declaration_code(self, entity_code,
522 for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
523 if pyrex or for_display:
524 return self.base_declaration_code(self.name, entity_code)
525 else:
526 if self.typedef_flag:
527 base_format = "%s"
528 else:
529 base_format = "struct %s"
530 base = public_decl(base_format % self.objstruct_cname, dll_linkage)
531 if deref:
532 return "%s %s" % (base, entity_code)
533 else:
534 return "%s *%s" % (base, entity_code)
536 def type_test_code(self, py_arg, notnone=False):
538 none_check = "((%s) == Py_None)" % py_arg
539 type_check = "likely(__Pyx_TypeTest(%s, %s))" % (
540 py_arg, self.typeptr_cname)
541 if notnone:
542 return type_check
543 else:
544 return "likely(%s || %s)" % (none_check, type_check)
546 def attributes_known(self):
547 return self.scope is not None
549 def __str__(self):
550 return self.name
552 def __repr__(self):
553 return "<PyExtensionType %s%s>" % (self.scope.class_name,
554 ("", " typedef")[self.typedef_flag])
557 class CType(PyrexType):
558 #
559 # Base class for all C types (non-reference-counted).
560 #
561 # to_py_function string C function for converting to Python object
562 # from_py_function string C function for constructing from Python object
563 #
565 to_py_function = None
566 from_py_function = None
567 exception_value = None
568 exception_check = 1
570 def create_to_py_utility_code(self, env):
571 return self.to_py_function is not None
573 def create_from_py_utility_code(self, env):
574 return self.from_py_function is not None
576 def can_coerce_to_pyobject(self, env):
577 return self.create_to_py_utility_code(env)
579 def error_condition(self, result_code):
580 conds = []
581 if self.is_string:
582 conds.append("(!%s)" % result_code)
583 elif self.exception_value is not None:
584 conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
585 if self.exception_check:
586 conds.append("PyErr_Occurred()")
587 if len(conds) > 0:
588 return " && ".join(conds)
589 else:
590 return 0
593 class CVoidType(CType):
594 is_void = 1
596 def __repr__(self):
597 return "<CVoidType>"
599 def declaration_code(self, entity_code,
600 for_display = 0, dll_linkage = None, pyrex = 0):
601 base = public_decl("void", dll_linkage)
602 return self.base_declaration_code(base, entity_code)
604 def is_complete(self):
605 return 0
608 class CNumericType(CType):
609 #
610 # Base class for all C numeric types.
611 #
612 # rank integer Relative size
613 # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
614 #
616 is_numeric = 1
617 default_value = "0"
619 sign_words = ("unsigned ", "", "signed ")
621 def __init__(self, rank, signed = 1, pymemberdef_typecode = None):
622 self.rank = rank
623 self.signed = signed
624 self.pymemberdef_typecode = pymemberdef_typecode
626 def sign_and_name(self):
627 s = self.sign_words[self.signed]
628 n = rank_to_type_name[self.rank]
629 return s + n
631 def __repr__(self):
632 return "<CNumericType %s>" % self.sign_and_name()
634 def declaration_code(self, entity_code,
635 for_display = 0, dll_linkage = None, pyrex = 0):
636 base = public_decl(self.sign_and_name(), dll_linkage)
637 if for_display:
638 base = base.replace('PY_LONG_LONG', 'long long')
639 return self.base_declaration_code(base, entity_code)
642 type_conversion_predeclarations = ""
643 type_conversion_functions = ""
645 c_int_from_py_function = UtilityCode(
646 proto="""
647 static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
648 """,
649 impl="""
650 static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
651 const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
652 const int is_unsigned = neg_one > const_zero;
653 if (sizeof(%(type)s) < sizeof(long)) {
654 long val = __Pyx_PyInt_AsLong(x);
655 if (unlikely(val != (long)(%(type)s)val)) {
656 if (!unlikely(val == -1 && PyErr_Occurred())) {
657 PyErr_SetString(PyExc_OverflowError,
658 (is_unsigned && unlikely(val < 0)) ?
659 "can't convert negative value to %(type)s" :
660 "value too large to convert to %(type)s");
661 }
662 return (%(type)s)-1;
663 }
664 return (%(type)s)val;
665 }
666 return (%(type)s)__Pyx_PyInt_As%(SignWord)sLong(x);
667 }
668 """) #fool emacs: '
670 c_long_from_py_function = UtilityCode(
671 proto="""
672 static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
673 """,
674 impl="""
675 static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
676 const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
677 const int is_unsigned = neg_one > const_zero;
678 #if PY_VERSION_HEX < 0x03000000
679 if (likely(PyInt_Check(x))) {
680 long val = PyInt_AS_LONG(x);
681 if (is_unsigned && unlikely(val < 0)) {
682 PyErr_SetString(PyExc_OverflowError,
683 "can't convert negative value to %(type)s");
684 return (%(type)s)-1;
685 }
686 return (%(type)s)val;
687 } else
688 #endif
689 if (likely(PyLong_Check(x))) {
690 if (is_unsigned) {
691 if (unlikely(Py_SIZE(x) < 0)) {
692 PyErr_SetString(PyExc_OverflowError,
693 "can't convert negative value to %(type)s");
694 return (%(type)s)-1;
695 }
696 return PyLong_AsUnsigned%(TypeName)s(x);
697 } else {
698 return PyLong_As%(TypeName)s(x);
699 }
700 } else {
701 %(type)s val;
702 PyObject *tmp = __Pyx_PyNumber_Int(x);
703 if (!tmp) return (%(type)s)-1;
704 val = __Pyx_PyInt_As%(SignWord)s%(TypeName)s(tmp);
705 Py_DECREF(tmp);
706 return val;
707 }
708 }
709 """)
711 c_typedef_int_from_py_function = UtilityCode(
712 proto="""
713 static CYTHON_INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject *);
714 """,
715 impl="""
716 static CYTHON_INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject* x) {
717 const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
718 const int is_unsigned = neg_one > const_zero;
719 if (sizeof(%(type)s) == sizeof(char)) {
720 if (is_unsigned)
721 return (%(type)s)__Pyx_PyInt_AsUnsignedChar(x);
722 else
723 return (%(type)s)__Pyx_PyInt_AsSignedChar(x);
724 } else if (sizeof(%(type)s) == sizeof(short)) {
725 if (is_unsigned)
726 return (%(type)s)__Pyx_PyInt_AsUnsignedShort(x);
727 else
728 return (%(type)s)__Pyx_PyInt_AsSignedShort(x);
729 } else if (sizeof(%(type)s) == sizeof(int)) {
730 if (is_unsigned)
731 return (%(type)s)__Pyx_PyInt_AsUnsignedInt(x);
732 else
733 return (%(type)s)__Pyx_PyInt_AsSignedInt(x);
734 } else if (sizeof(%(type)s) == sizeof(long)) {
735 if (is_unsigned)
736 return (%(type)s)__Pyx_PyInt_AsUnsignedLong(x);
737 else
738 return (%(type)s)__Pyx_PyInt_AsSignedLong(x);
739 } else if (sizeof(%(type)s) == sizeof(PY_LONG_LONG)) {
740 if (is_unsigned)
741 return (%(type)s)__Pyx_PyInt_AsUnsignedLongLong(x);
742 else
743 return (%(type)s)__Pyx_PyInt_AsSignedLongLong(x);
744 #if 0
745 } else if (sizeof(%(type)s) > sizeof(short) &&
746 sizeof(%(type)s) < sizeof(int)) { /* __int32 ILP64 ? */
747 if (is_unsigned)
748 return (%(type)s)__Pyx_PyInt_AsUnsignedInt(x);
749 else
750 return (%(type)s)__Pyx_PyInt_AsSignedInt(x);
751 #endif
752 }
753 PyErr_SetString(PyExc_TypeError, "%(TypeName)s");
754 return (%(type)s)-1;
755 }
756 """)
758 c_typedef_int_to_py_function = UtilityCode(
759 proto="""
760 static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s);
761 """,
762 impl="""
763 static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s val) {
764 const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
765 const int is_unsigned = neg_one > const_zero;
766 if (sizeof(%(type)s) < sizeof(long)) {
767 return PyInt_FromLong((long)val);
768 } else if (sizeof(%(type)s) == sizeof(long)) {
769 if (is_unsigned)
770 return PyLong_FromUnsignedLong((unsigned long)val);
771 else
772 return PyInt_FromLong((long)val);
773 } else { /* (sizeof(%(type)s) > sizeof(long)) */
774 if (is_unsigned)
775 return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)val);
776 else
777 return PyLong_FromLongLong((PY_LONG_LONG)val);
778 }
779 }
780 """)
782 class CIntType(CNumericType):
784 is_int = 1
785 typedef_flag = 0
786 to_py_function = "PyInt_FromLong"
787 from_py_function = "__Pyx_PyInt_AsInt"
788 exception_value = -1
790 def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
791 CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
792 self.is_returncode = is_returncode
793 if self.from_py_function == "__Pyx_PyInt_AsInt":
794 self.from_py_function = self.get_type_conversion()
796 def get_type_conversion(self):
797 ctype = self.declaration_code('')
798 bits = ctype.split(" ", 1)
799 if len(bits) == 1:
800 sign_word, type_name = "", bits[0]
801 else:
802 sign_word, type_name = bits
803 type_name = type_name.replace("PY_LONG_LONG","long long")
804 SignWord = sign_word.title()
805 TypeName = type_name.title().replace(" ", "")
806 if "Long" in TypeName:
807 utility_code = c_long_from_py_function
808 else:
809 utility_code = c_int_from_py_function
810 utility_code.specialize(self,
811 SignWord=SignWord,
812 TypeName=TypeName)
813 func_name = "__Pyx_PyInt_As%s%s" % (SignWord, TypeName)
814 return func_name
816 def assignable_from_resolved_type(self, src_type):
817 return src_type.is_int or src_type.is_enum or src_type is error_type
820 class CBIntType(CIntType):
822 to_py_function = "__Pyx_PyBool_FromLong"
823 from_py_function = "__Pyx_PyObject_IsTrue"
824 exception_check = 0
826 def __repr__(self):
827 return "<CNumericType bint>"
830 class CAnonEnumType(CIntType):
832 is_enum = 1
834 def sign_and_name(self):
835 return 'int'
838 class CUIntType(CIntType):
840 to_py_function = "PyLong_FromUnsignedLong"
841 exception_value = -1
844 class CLongType(CIntType):
846 to_py_function = "PyInt_FromLong"
849 class CULongType(CUIntType):
851 to_py_function = "PyLong_FromUnsignedLong"
854 class CLongLongType(CIntType):
856 to_py_function = "PyLong_FromLongLong"
859 class CULongLongType(CUIntType):
861 to_py_function = "PyLong_FromUnsignedLongLong"
864 class CPySSizeTType(CIntType):
866 to_py_function = "PyInt_FromSsize_t"
867 from_py_function = "__Pyx_PyIndex_AsSsize_t"
869 def sign_and_name(self):
870 return rank_to_type_name[self.rank]
873 class CSizeTType(CUIntType):
875 to_py_function = "__Pyx_PyInt_FromSize_t"
876 from_py_function = "__Pyx_PyInt_AsSize_t"
878 def sign_and_name(self):
879 return rank_to_type_name[self.rank]
882 class CFloatType(CNumericType):
884 is_float = 1
885 to_py_function = "PyFloat_FromDouble"
886 from_py_function = "__pyx_PyFloat_AsDouble"
888 exception_value = -1
890 def __init__(self, rank, pymemberdef_typecode = None, math_h_modifier = ''):
891 CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
892 self.math_h_modifier = math_h_modifier
894 def assignable_from_resolved_type(self, src_type):
895 return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type
898 class CComplexType(CNumericType):
900 is_complex = 1
901 to_py_function = "__pyx_PyComplex_FromComplex"
902 has_attributes = 1
903 scope = None
905 def __init__(self, real_type):
906 while real_type.is_typedef and not real_type.typedef_is_external:
907 real_type = real_type.typedef_base_type
908 if real_type.is_typedef and real_type.typedef_is_external:
909 # The below is not actually used: Coercions are currently disabled
910 # so that complex types of external types can not be created
911 self.funcsuffix = "_%s" % real_type.specalization_name()
912 elif hasattr(real_type, 'math_h_modifier'):
913 self.funcsuffix = real_type.math_h_modifier
914 else:
915 self.funcsuffix = "_%s" % real_type.specalization_name()
917 self.real_type = real_type
918 CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
919 self.binops = {}
920 self.from_parts = "%s_from_parts" % self.specalization_name()
921 self.default_value = "%s(0, 0)" % self.from_parts
923 def __eq__(self, other):
924 if isinstance(self, CComplexType) and isinstance(other, CComplexType):
925 return self.real_type == other.real_type
926 else:
927 return False
929 def __ne__(self, other):
930 if isinstance(self, CComplexType) and isinstance(other, CComplexType):
931 return self.real_type != other.real_type
932 else:
933 return True
935 def __lt__(self, other):
936 if isinstance(self, CComplexType) and isinstance(other, CComplexType):
937 return self.real_type < other.real_type
938 else:
939 # this is arbitrary, but it makes sure we always have
940 # *some* kind of order
941 return False
943 def __hash__(self):
944 return ~hash(self.real_type)
946 def declaration_code(self, entity_code,
947 for_display = 0, dll_linkage = None, pyrex = 0):
948 if for_display:
949 base = public_decl(self.real_type.sign_and_name() + " complex", dll_linkage)
950 else:
951 base = public_decl(self.sign_and_name(), dll_linkage)
952 return self.base_declaration_code(base, entity_code)
954 def sign_and_name(self):
955 real_type_name = self.real_type.specalization_name()
956 real_type_name = real_type_name.replace('long__double','long_double')
957 return Naming.type_prefix + real_type_name + "_complex"
959 def assignable_from(self, src_type):
960 # Temporary hack/feature disabling, see #441
961 if (not src_type.is_complex and src_type.is_numeric and src_type.is_typedef
962 and src_type.typedef_is_external):
963 return False
964 else:
965 return super(CComplexType, self).assignable_from(src_type)
967 def assignable_from_resolved_type(self, src_type):
968 return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type)
969 or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type)
970 or src_type is error_type)
972 def attributes_known(self):
973 if self.scope is None:
974 import Symtab
975 self.scope = scope = Symtab.CClassScope(
976 '',
977 None,
978 visibility="extern")
979 scope.parent_type = self
980 scope.declare_var("real", self.real_type, None, "real", is_cdef=True)
981 scope.declare_var("imag", self.real_type, None, "imag", is_cdef=True)
982 entry = scope.declare_cfunction(
983 "conjugate",
984 CFuncType(self, [CFuncTypeArg("self", self, None)]),
985 pos=None,
986 defining=1,
987 cname="__Pyx_c_conj%s" % self.funcsuffix)
989 return True
991 def create_declaration_utility_code(self, env):
992 # This must always be run, because a single CComplexType instance can be shared
993 # across multiple compilations (the one created in the module scope)
994 env.use_utility_code(complex_header_utility_code)
995 env.use_utility_code(complex_real_imag_utility_code)
996 for utility_code in (complex_type_utility_code,
997 complex_from_parts_utility_code,
998 complex_arithmetic_utility_code):
999 env.use_utility_code(
1000 utility_code.specialize(
1001 self,
1002 real_type = self.real_type.declaration_code(''),
1003 m = self.funcsuffix))
1004 return True
1006 def create_to_py_utility_code(self, env):
1007 env.use_utility_code(complex_real_imag_utility_code)
1008 env.use_utility_code(complex_to_py_utility_code)
1009 return True
1011 def create_from_py_utility_code(self, env):
1012 self.real_type.create_from_py_utility_code(env)
1014 for utility_code in (complex_from_parts_utility_code,
1015 complex_from_py_utility_code):
1016 env.use_utility_code(
1017 utility_code.specialize(
1018 self,
1019 real_type = self.real_type.declaration_code(''),
1020 m = self.funcsuffix))
1021 self.from_py_function = "__Pyx_PyComplex_As_" + self.specalization_name()
1022 return True
1024 def lookup_op(self, nargs, op):
1025 try:
1026 return self.binops[nargs, op]
1027 except KeyError:
1028 pass
1029 try:
1030 op_name = complex_ops[nargs, op]
1031 self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, self.funcsuffix)
1032 return func_name
1033 except KeyError:
1034 return None
1036 def unary_op(self, op):
1037 return self.lookup_op(1, op)
1039 def binary_op(self, op):
1040 return self.lookup_op(2, op)
1042 complex_ops = {
1043 (1, '-'): 'neg',
1044 (1, 'zero'): 'is_zero',
1045 (2, '+'): 'sum',
1046 (2, '-'): 'diff',
1047 (2, '*'): 'prod',
1048 (2, '/'): 'quot',
1049 (2, '=='): 'eq',
1050 }
1052 complex_header_utility_code = UtilityCode(
1053 proto_block='h_code',
1054 proto="""
1055 #if !defined(CYTHON_CCOMPLEX)
1056 #if defined(__cplusplus)
1057 #define CYTHON_CCOMPLEX 1
1058 #elif defined(_Complex_I)
1059 #define CYTHON_CCOMPLEX 1
1060 #else
1061 #define CYTHON_CCOMPLEX 0
1062 #endif
1063 #endif
1065 #if CYTHON_CCOMPLEX
1066 #ifdef __cplusplus
1067 #include <complex>
1068 #else
1069 #include <complex.h>
1070 #endif
1071 #endif
1073 #if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
1074 #undef _Complex_I
1075 #define _Complex_I 1.0fj
1076 #endif
1077 """)
1079 complex_real_imag_utility_code = UtilityCode(
1080 proto="""
1081 #if CYTHON_CCOMPLEX
1082 #ifdef __cplusplus
1083 #define __Pyx_CREAL(z) ((z).real())
1084 #define __Pyx_CIMAG(z) ((z).imag())
1085 #else
1086 #define __Pyx_CREAL(z) (__real__(z))
1087 #define __Pyx_CIMAG(z) (__imag__(z))
1088 #endif
1089 #else
1090 #define __Pyx_CREAL(z) ((z).real)
1091 #define __Pyx_CIMAG(z) ((z).imag)
1092 #endif
1094 #if defined(_WIN32) && defined(__cplusplus) && CYTHON_CCOMPLEX
1095 #define __Pyx_SET_CREAL(z,x) ((z).real(x))
1096 #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
1097 #else
1098 #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
1099 #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
1100 #endif
1101 """)
1103 complex_type_utility_code = UtilityCode(
1104 proto_block='complex_type_declarations',
1105 proto="""
1106 #if CYTHON_CCOMPLEX
1107 #ifdef __cplusplus
1108 typedef ::std::complex< %(real_type)s > %(type_name)s;
1109 #else
1110 typedef %(real_type)s _Complex %(type_name)s;
1111 #endif
1112 #else
1113 typedef struct { %(real_type)s real, imag; } %(type_name)s;
1114 #endif
1115 """)
1117 complex_from_parts_utility_code = UtilityCode(
1118 proto_block='utility_code_proto',
1119 proto="""
1120 static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
1121 """,
1122 impl="""
1123 #if CYTHON_CCOMPLEX
1124 #ifdef __cplusplus
1125 static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1126 return ::std::complex< %(real_type)s >(x, y);
1127 }
1128 #else
1129 static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1130 return x + y*(%(type)s)_Complex_I;
1131 }
1132 #endif
1133 #else
1134 static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1135 %(type)s z;
1136 z.real = x;
1137 z.imag = y;
1138 return z;
1139 }
1140 #endif
1141 """)
1143 complex_to_py_utility_code = UtilityCode(
1144 proto="""
1145 #define __pyx_PyComplex_FromComplex(z) \\
1146 PyComplex_FromDoubles((double)__Pyx_CREAL(z), \\
1147 (double)__Pyx_CIMAG(z))
1148 """)
1150 complex_from_py_utility_code = UtilityCode(
1151 proto="""
1152 static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject*);
1153 """,
1154 impl="""
1155 static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject* o) {
1156 Py_complex cval;
1157 if (PyComplex_CheckExact(o))
1158 cval = ((PyComplexObject *)o)->cval;
1159 else
1160 cval = PyComplex_AsCComplex(o);
1161 return %(type_name)s_from_parts(
1162 (%(real_type)s)cval.real,
1163 (%(real_type)s)cval.imag);
1164 }
1165 """)
1167 complex_arithmetic_utility_code = UtilityCode(
1168 proto="""
1169 #if CYTHON_CCOMPLEX
1170 #define __Pyx_c_eq%(m)s(a, b) ((a)==(b))
1171 #define __Pyx_c_sum%(m)s(a, b) ((a)+(b))
1172 #define __Pyx_c_diff%(m)s(a, b) ((a)-(b))
1173 #define __Pyx_c_prod%(m)s(a, b) ((a)*(b))
1174 #define __Pyx_c_quot%(m)s(a, b) ((a)/(b))
1175 #define __Pyx_c_neg%(m)s(a) (-(a))
1176 #ifdef __cplusplus
1177 #define __Pyx_c_is_zero%(m)s(z) ((z)==(%(real_type)s)0)
1178 #define __Pyx_c_conj%(m)s(z) (::std::conj(z))
1179 /*#define __Pyx_c_abs%(m)s(z) (::std::abs(z))*/
1180 #else
1181 #define __Pyx_c_is_zero%(m)s(z) ((z)==0)
1182 #define __Pyx_c_conj%(m)s(z) (conj%(m)s(z))
1183 /*#define __Pyx_c_abs%(m)s(z) (cabs%(m)s(z))*/
1184 #endif
1185 #else
1186 static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s, %(type)s);
1187 static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s, %(type)s);
1188 static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s, %(type)s);
1189 static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s, %(type)s);
1190 static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s, %(type)s);
1191 static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s);
1192 static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s);
1193 static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s);
1194 /*static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s);*/
1195 #endif
1196 """,
1197 impl="""
1198 #if CYTHON_CCOMPLEX
1199 #else
1200 static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s a, %(type)s b) {
1201 return (a.real == b.real) && (a.imag == b.imag);
1202 }
1203 static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s a, %(type)s b) {
1204 %(type)s z;
1205 z.real = a.real + b.real;
1206 z.imag = a.imag + b.imag;
1207 return z;
1208 }
1209 static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s a, %(type)s b) {
1210 %(type)s z;
1211 z.real = a.real - b.real;
1212 z.imag = a.imag - b.imag;
1213 return z;
1214 }
1215 static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s a, %(type)s b) {
1216 %(type)s z;
1217 z.real = a.real * b.real - a.imag * b.imag;
1218 z.imag = a.real * b.imag + a.imag * b.real;
1219 return z;
1220 }
1221 static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s a, %(type)s b) {
1222 %(type)s z;
1223 %(real_type)s denom = b.real * b.real + b.imag * b.imag;
1224 z.real = (a.real * b.real + a.imag * b.imag) / denom;
1225 z.imag = (a.imag * b.real - a.real * b.imag) / denom;
1226 return z;
1227 }
1228 static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s a) {
1229 %(type)s z;
1230 z.real = -a.real;
1231 z.imag = -a.imag;
1232 return z;
1233 }
1234 static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s a) {
1235 return (a.real == 0) && (a.imag == 0);
1236 }
1237 static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s a) {
1238 %(type)s z;
1239 z.real = a.real;
1240 z.imag = -a.imag;
1241 return z;
1242 }
1243 /*
1244 static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) {
1245 #if HAVE_HYPOT
1246 return hypot%(m)s(z.real, z.imag);
1247 #else
1248 return sqrt%(m)s(z.real*z.real + z.imag*z.imag);
1249 #endif
1250 }
1251 */
1252 #endif
1253 """)
1255 class CArrayType(CType):
1256 # base_type CType Element type
1257 # size integer or None Number of elements
1259 is_array = 1
1261 def __init__(self, base_type, size):
1262 self.base_type = base_type
1263 self.size = size
1264 if base_type is c_char_type:
1265 self.is_string = 1
1267 def __repr__(self):
1268 return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
1270 def same_as_resolved_type(self, other_type):
1271 return ((other_type.is_array and
1272 self.base_type.same_as(other_type.base_type))
1273 or other_type is error_type)
1275 def assignable_from_resolved_type(self, src_type):
1276 # Can't assign to a variable of an array type
1277 return 0
1279 def element_ptr_type(self):
1280 return c_ptr_type(self.base_type)
1282 def declaration_code(self, entity_code,
1283 for_display = 0, dll_linkage = None, pyrex = 0):
1284 if self.size is not None:
1285 dimension_code = self.size
1286 else:
1287 dimension_code = ""
1288 if entity_code.startswith("*"):
1289 entity_code = "(%s)" % entity_code
1290 return self.base_type.declaration_code(
1291 "%s[%s]" % (entity_code, dimension_code),
1292 for_display, dll_linkage, pyrex)
1294 def as_argument_type(self):
1295 return c_ptr_type(self.base_type)
1297 def is_complete(self):
1298 return self.size is not None
1301 class CPtrType(CType):
1302 # base_type CType Referenced type
1304 is_ptr = 1
1305 default_value = "0"
1307 def __init__(self, base_type):
1308 self.base_type = base_type
1310 def __repr__(self):
1311 return "<CPtrType %s>" % repr(self.base_type)
1313 def same_as_resolved_type(self, other_type):
1314 return ((other_type.is_ptr and
1315 self.base_type.same_as(other_type.base_type))
1316 or other_type is error_type)
1318 def declaration_code(self, entity_code,
1319 for_display = 0, dll_linkage = None, pyrex = 0):
1320 #print "CPtrType.declaration_code: pointer to", self.base_type ###
1321 return self.base_type.declaration_code(
1322 "*%s" % entity_code,
1323 for_display, dll_linkage, pyrex)
1325 def assignable_from_resolved_type(self, other_type):
1326 if other_type is error_type:
1327 return 1
1328 if other_type.is_null_ptr:
1329 return 1
1330 if self.base_type.is_cfunction:
1331 if other_type.is_ptr:
1332 other_type = other_type.base_type.resolve()
1333 if other_type.is_cfunction:
1334 return self.base_type.pointer_assignable_from_resolved_type(other_type)
1335 else:
1336 return 0
1337 if (self.base_type.is_cpp_class and other_type.is_ptr
1338 and other_type.base_type.is_cpp_class and other_type.base_type.is_subclass(self.base_type)):
1339 return 1
1340 if other_type.is_array or other_type.is_ptr:
1341 return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
1342 return 0
1344 def specialize(self, values):
1345 base_type = self.base_type.specialize(values)
1346 if base_type == self.base_type:
1347 return self
1348 else:
1349 return CPtrType(base_type)
1352 class CNullPtrType(CPtrType):
1354 is_null_ptr = 1
1357 class CReferenceType(BaseType):
1359 is_reference = 1
1361 def __init__(self, base_type):
1362 self.ref_base_type = base_type
1364 def __repr__(self):
1365 return "<CReferenceType %s>" % repr(self.ref_base_type)
1367 def __str__(self):
1368 return "%s &" % self.ref_base_type
1370 def as_argument_type(self):
1371 return self
1373 def declaration_code(self, entity_code,
1374 for_display = 0, dll_linkage = None, pyrex = 0):
1375 #print "CReferenceType.declaration_code: pointer to", self.base_type ###
1376 return self.ref_base_type.declaration_code(
1377 "&%s" % entity_code,
1378 for_display, dll_linkage, pyrex)
1380 def specialize(self, values):
1381 base_type = self.ref_base_type.specialize(values)
1382 if base_type == self.ref_base_type:
1383 return self
1384 else:
1385 return CReferenceType(base_type)
1387 def __getattr__(self, name):
1388 return getattr(self.ref_base_type, name)
1391 class CFuncType(CType):
1392 # return_type CType
1393 # args [CFuncTypeArg]
1394 # has_varargs boolean
1395 # exception_value string
1396 # exception_check boolean True if PyErr_Occurred check needed
1397 # calling_convention string Function calling convention
1398 # nogil boolean Can be called without gil
1399 # with_gil boolean Acquire gil around function body
1400 # templates [string] or None
1402 is_cfunction = 1
1403 original_sig = None
1405 def __init__(self, return_type, args, has_varargs = 0,
1406 exception_value = None, exception_check = 0, calling_convention = "",
1407 nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0,
1408 templates = None):
1409 self.return_type = return_type
1410 self.args = args
1411 self.has_varargs = has_varargs
1412 self.optional_arg_count = optional_arg_count
1413 self.exception_value = exception_value
1414 self.exception_check = exception_check
1415 self.calling_convention = calling_convention
1416 self.nogil = nogil
1417 self.with_gil = with_gil
1418 self.is_overridable = is_overridable
1419 self.templates = templates
1421 def __repr__(self):
1422 arg_reprs = map(repr, self.args)
1423 if self.has_varargs:
1424 arg_reprs.append("...")
1425 if self.exception_value:
1426 except_clause = " %r" % self.exception_value
1427 else:
1428 except_clause = ""
1429 if self.exception_check:
1430 except_clause += "?"
1431 return "<CFuncType %s %s[%s]%s>" % (
1432 repr(self.return_type),
1433 self.calling_convention_prefix(),
1434 ",".join(arg_reprs),
1435 except_clause)
1437 def calling_convention_prefix(self):
1438 cc = self.calling_convention
1439 if cc:
1440 return cc + " "
1441 else:
1442 return ""
1444 def same_c_signature_as(self, other_type, as_cmethod = 0):
1445 return self.same_c_signature_as_resolved_type(
1446 other_type.resolve(), as_cmethod)
1448 def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
1449 #print "CFuncType.same_c_signature_as_resolved_type:", \
1450 # self, other_type, "as_cmethod =", as_cmethod ###
1451 if other_type is error_type:
1452 return 1
1453 if not other_type.is_cfunction:
1454 return 0
1455 if self.is_overridable != other_type.is_overridable:
1456 return 0
1457 nargs = len(self.args)
1458 if nargs != len(other_type.args):
1459 return 0
1460 # When comparing C method signatures, the first argument
1461 # is exempt from compatibility checking (the proper check
1462 # is performed elsewhere).
1463 for i in range(as_cmethod, nargs):
1464 if not self.args[i].type.same_as(
1465 other_type.args[i].type):
1466 return 0
1467 if self.has_varargs != other_type.has_varargs:
1468 return 0
1469 if self.optional_arg_count != other_type.optional_arg_count:
1470 return 0
1471 if not self.return_type.same_as(other_type.return_type):
1472 return 0
1473 if not self.same_calling_convention_as(other_type):
1474 return 0
1475 return 1
1477 def compatible_signature_with(self, other_type, as_cmethod = 0):
1478 return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
1480 def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
1481 #print "CFuncType.same_c_signature_as_resolved_type:", \
1482 # self, other_type, "as_cmethod =", as_cmethod ###
1483 if other_type is error_type:
1484 return 1
1485 if not other_type.is_cfunction:
1486 return 0
1487 if not self.is_overridable and other_type.is_overridable:
1488 return 0
1489 nargs = len(self.args)
1490 if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
1491 return 0
1492 if self.optional_arg_count < other_type.optional_arg_count:
1493 return 0
1494 # When comparing C method signatures, the first argument
1495 # is exempt from compatibility checking (the proper check
1496 # is performed elsewhere).
1497 for i in range(as_cmethod, len(other_type.args)):
1498 if not self.args[i].type.same_as(
1499 other_type.args[i].type):
1500 return 0
1501 if self.has_varargs != other_type.has_varargs:
1502 return 0
1503 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1504 return 0
1505 if not self.same_calling_convention_as(other_type):
1506 return 0
1507 if self.nogil != other_type.nogil:
1508 return 0
1509 self.original_sig = other_type.original_sig or other_type
1510 if as_cmethod:
1511 self.args[0] = other_type.args[0]
1512 return 1
1515 def narrower_c_signature_than(self, other_type, as_cmethod = 0):
1516 return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
1518 def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
1519 if other_type is error_type:
1520 return 1
1521 if not other_type.is_cfunction:
1522 return 0
1523 nargs = len(self.args)
1524 if nargs != len(other_type.args):
1525 return 0
1526 for i in range(as_cmethod, nargs):
1527 if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
1528 return 0
1529 else:
1530 self.args[i].needs_type_test = other_type.args[i].needs_type_test \
1531 or not self.args[i].type.same_as(other_type.args[i].type)
1532 if self.has_varargs != other_type.has_varargs:
1533 return 0
1534 if self.optional_arg_count != other_type.optional_arg_count:
1535 return 0
1536 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1537 return 0
1538 return 1
1540 def same_calling_convention_as(self, other):
1541 ## XXX Under discussion ...
1542 ## callspec_words = ("__stdcall", "__cdecl", "__fastcall")
1543 ## cs1 = self.calling_convention
1544 ## cs2 = other.calling_convention
1545 ## if (cs1 in callspec_words or
1546 ## cs2 in callspec_words):
1547 ## return cs1 == cs2
1548 ## else:
1549 ## return True
1550 sc1 = self.calling_convention == '__stdcall'
1551 sc2 = other.calling_convention == '__stdcall'
1552 return sc1 == sc2
1554 def same_exception_signature_as(self, other_type):
1555 return self.same_exception_signature_as_resolved_type(
1556 other_type.resolve())
1558 def same_exception_signature_as_resolved_type(self, other_type):
1559 return self.exception_value == other_type.exception_value \
1560 and self.exception_check == other_type.exception_check
1562 def same_as_resolved_type(self, other_type, as_cmethod = 0):
1563 return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
1564 and self.same_exception_signature_as_resolved_type(other_type) \
1565 and self.nogil == other_type.nogil
1567 def pointer_assignable_from_resolved_type(self, other_type):
1568 return self.same_c_signature_as_resolved_type(other_type) \
1569 and self.same_exception_signature_as_resolved_type(other_type) \
1570 and not (self.nogil and not other_type.nogil)
1572 def declaration_code(self, entity_code,
1573 for_display = 0, dll_linkage = None, pyrex = 0,
1574 with_calling_convention = 1):
1575 arg_decl_list = []
1576 for arg in self.args[:len(self.args)-self.optional_arg_count]:
1577 arg_decl_list.append(
1578 arg.type.declaration_code("", for_display, pyrex = pyrex))
1579 if self.is_overridable:
1580 arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
1581 if self.optional_arg_count:
1582 arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
1583 if self.has_varargs:
1584 arg_decl_list.append("...")
1585 arg_decl_code = ", ".join(arg_decl_list)
1586 if not arg_decl_code and not pyrex:
1587 arg_decl_code = "void"
1588 trailer = ""
1589 if (pyrex or for_display) and not self.return_type.is_pyobject:
1590 if self.exception_value and self.exception_check:
1591 trailer = " except? %s" % self.exception_value
1592 elif self.exception_value:
1593 trailer = " except %s" % self.exception_value
1594 elif self.exception_check == '+':
1595 trailer = " except +"
1596 else:
1597 " except *" # ignored
1598 if self.nogil:
1599 trailer += " nogil"
1600 if not with_calling_convention:
1601 cc = ''
1602 else:
1603 cc = self.calling_convention_prefix()
1604 if (not entity_code and cc) or entity_code.startswith("*"):
1605 entity_code = "(%s%s)" % (cc, entity_code)
1606 cc = ""
1607 return self.return_type.declaration_code(
1608 "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
1609 for_display, dll_linkage, pyrex)
1611 def function_header_code(self, func_name, arg_code):
1612 return "%s%s(%s)" % (self.calling_convention_prefix(),
1613 func_name, arg_code)
1615 def signature_string(self):
1616 s = self.declaration_code("")
1617 return s
1619 def signature_cast_string(self):
1620 s = self.declaration_code("(*)", with_calling_convention=False)
1621 return '(%s)' % s
1623 def specialize(self, values):
1624 if self.templates is None:
1625 new_templates = None
1626 else:
1627 new_templates = [v.specialize(values) for v in self.templates]
1628 return CFuncType(self.return_type.specialize(values),
1629 [arg.specialize(values) for arg in self.args],
1630 has_varargs = 0,
1631 exception_value = self.exception_value,
1632 exception_check = self.exception_check,
1633 calling_convention = self.calling_convention,
1634 nogil = self.nogil,
1635 with_gil = self.with_gil,
1636 is_overridable = self.is_overridable,
1637 optional_arg_count = self.optional_arg_count,
1638 templates = new_templates)
1640 def opt_arg_cname(self, arg_name):
1641 return self.op_arg_struct.base_type.scope.lookup(arg_name).cname
1644 class CFuncTypeArg(object):
1645 # name string
1646 # cname string
1647 # type PyrexType
1648 # pos source file position
1650 def __init__(self, name, type, pos, cname=None):
1651 self.name = name
1652 if cname is not None:
1653 self.cname = cname
1654 else:
1655 self.cname = Naming.var_prefix + name
1656 self.type = type
1657 self.pos = pos
1658 self.not_none = False
1659 self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
1661 def __repr__(self):
1662 return "%s:%s" % (self.name, repr(self.type))
1664 def declaration_code(self, for_display = 0):
1665 return self.type.declaration_code(self.cname, for_display)
1667 def specialize(self, values):
1668 return CFuncTypeArg(self.name, self.type.specialize(values), self.pos, self.cname)
1670 class StructUtilityCode(object):
1671 def __init__(self, type, forward_decl):
1672 self.type = type
1673 self.header = "static PyObject* %s(%s)" % (type.to_py_function, type.declaration_code('s'))
1674 self.forward_decl = forward_decl
1676 def __eq__(self, other):
1677 return isinstance(other, StructUtilityCode) and self.header == other.header
1678 def __hash__(self):
1679 return hash(self.header)
1681 def put_code(self, output):
1682 code = output['utility_code_def']
1683 proto = output['utility_code_proto']
1685 code.putln("%s {" % self.header)
1686 code.putln("PyObject* res;")
1687 code.putln("PyObject* member;")
1688 code.putln("res = PyDict_New(); if (res == NULL) return NULL;")
1689 for member in self.type.scope.var_entries:
1690 nameconst_cname = code.get_py_string_const(member.name, identifier=True)
1691 code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % (
1692 member.type.to_py_function, member.cname))
1693 code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % nameconst_cname)
1694 code.putln("Py_DECREF(member);")
1695 code.putln("return res;")
1696 code.putln("bad:")
1697 code.putln("Py_XDECREF(member);")
1698 code.putln("Py_DECREF(res);")
1699 code.putln("return NULL;")
1700 code.putln("}")
1702 # This is a bit of a hack, we need a forward declaration
1703 # due to the way things are ordered in the module...
1704 if self.forward_decl:
1705 proto.putln(self.type.declaration_code('') + ';')
1706 proto.putln(self.header + ";")
1709 class CStructOrUnionType(CType):
1710 # name string
1711 # cname string
1712 # kind string "struct" or "union"
1713 # scope StructOrUnionScope, or None if incomplete
1714 # typedef_flag boolean
1715 # packed boolean
1717 # entry Entry
1719 is_struct_or_union = 1
1720 has_attributes = 1
1722 def __init__(self, name, kind, scope, typedef_flag, cname, packed=False):
1723 self.name = name
1724 self.cname = cname
1725 self.kind = kind
1726 self.scope = scope
1727 self.typedef_flag = typedef_flag
1728 self.is_struct = kind == 'struct'
1729 if self.is_struct:
1730 self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
1731 self.exception_check = True
1732 self._convert_code = None
1733 self.packed = packed
1735 def create_to_py_utility_code(self, env):
1736 if env.outer_scope is None:
1737 return False
1739 if self._convert_code is False: return # tri-state-ish
1741 if self._convert_code is None:
1742 for member in self.scope.var_entries:
1743 if not member.type.to_py_function or not member.type.create_to_py_utility_code(env):
1744 self.to_py_function = None
1745 self._convert_code = False
1746 return False
1747 forward_decl = (self.entry.visibility != 'extern')
1748 self._convert_code = StructUtilityCode(self, forward_decl)
1750 env.use_utility_code(self._convert_code)
1751 return True
1753 def __repr__(self):
1754 return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
1755 ("", " typedef")[self.typedef_flag])
1757 def declaration_code(self, entity_code,
1758 for_display = 0, dll_linkage = None, pyrex = 0):
1759 if pyrex:
1760 return self.base_declaration_code(self.name, entity_code)
1761 else:
1762 if for_display:
1763 base = self.name
1764 elif self.typedef_flag:
1765 base = self.cname
1766 else:
1767 base = "%s %s" % (self.kind, self.cname)
1768 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1770 def __eq__(self, other):
1771 try:
1772 return (isinstance(other, CStructOrUnionType) and
1773 self.name == other.name)
1774 except AttributeError:
1775 return False
1777 def __lt__(self, other):
1778 try:
1779 return self.name < other.name
1780 except AttributeError:
1781 # this is arbitrary, but it makes sure we always have
1782 # *some* kind of order
1783 return False
1785 def __hash__(self):
1786 return hash(self.cname) ^ hash(self.kind)
1788 def is_complete(self):
1789 return self.scope is not None
1791 def attributes_known(self):
1792 return self.is_complete()
1794 def can_be_complex(self):
1795 # Does the struct consist of exactly two identical floats?
1796 fields = self.scope.var_entries
1797 if len(fields) != 2: return False
1798 a, b = fields
1799 return (a.type.is_float and b.type.is_float and
1800 a.type.declaration_code("") ==
1801 b.type.declaration_code(""))
1803 def struct_nesting_depth(self):
1804 child_depths = [x.type.struct_nesting_depth()
1805 for x in self.scope.var_entries]
1806 return max(child_depths) + 1
1808 class CppClassType(CType):
1809 # name string
1810 # cname string
1811 # scope CppClassScope
1812 # templates [string] or None
1814 is_cpp_class = 1
1815 has_attributes = 1
1816 exception_check = True
1817 namespace = None
1819 def __init__(self, name, scope, cname, base_classes, templates = None, template_type = None):
1820 self.name = name
1821 self.cname = cname
1822 self.scope = scope
1823 self.base_classes = base_classes
1824 self.operators = []
1825 self.templates = templates
1826 self.template_type = template_type
1827 self.specializations = {}
1829 def specialize_here(self, pos, template_values = None):
1830 if self.templates is None:
1831 error(pos, "'%s' type is not a template" % self);
1832 return PyrexTypes.error_type
1833 if len(self.templates) != len(template_values):
1834 error(pos, "%s templated type receives %d arguments, got %d" %
1835 (self.name, len(self.templates), len(template_values)))
1836 return error_type
1837 return self.specialize(dict(zip(self.templates, template_values)))
1839 def specialize(self, values):
1840 if not self.templates and not self.namespace:
1841 return self
1842 if self.templates is None:
1843 self.templates = []
1844 key = tuple(values.items())
1845 if key in self.specializations:
1846 return self.specializations[key]
1847 template_values = [t.specialize(values) for t in self.templates]
1848 specialized = self.specializations[key] = \
1849 CppClassType(self.name, None, self.cname, [], template_values, template_type=self)
1850 # Need to do these *after* self.specializations[key] is set
1851 # to avoid infinite recursion on circular references.
1852 specialized.base_classes = [b.specialize(values) for b in self.base_classes]
1853 specialized.scope = self.scope.specialize(values)
1854 if self.namespace is not None:
1855 specialized.namespace = self.namespace.specialize(values)
1856 return specialized
1858 def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0):
1859 if self.templates:
1860 template_strings = [param.declaration_code('', for_display, pyrex) for param in self.templates]
1861 templates = "<" + ",".join(template_strings) + ">"
1862 else:
1863 templates = ""
1864 if for_display or pyrex:
1865 name = self.name
1866 else:
1867 if self.namespace is not None:
1868 name = "%s::%s" % (self.namespace.declaration_code(''), self.cname)
1869 else:
1870 name = self.cname
1871 return "%s%s %s" % (name, templates, entity_code)
1873 def is_subclass(self, other_type):
1874 # TODO(danilo): Handle templates.
1875 if self.same_as_resolved_type(other_type):
1876 return 1
1877 for base_class in self.base_classes:
1878 if base_class.is_subclass(other_type):
1879 return 1
1880 return 0
1882 def same_as_resolved_type(self, other_type):
1883 if other_type.is_cpp_class:
1884 if self == other_type:
1885 return 1
1886 elif self.template_type and self.template_type == other_type.template_type:
1887 if self.templates == other_type.templates:
1888 return 1
1889 for t1, t2 in zip(self.templates, other_type.templates):
1890 if not t1.same_as_resolved_type(t2):
1891 return 0
1892 return 1
1893 return 0
1895 def assignable_from_resolved_type(self, other_type):
1896 # TODO: handle operator=(...) here?
1897 if other_type is error_type:
1898 return True
1899 return other_type.is_cpp_class and other_type.is_subclass(self)
1901 def attributes_known(self):
1902 return self.scope is not None
1905 class TemplatePlaceholderType(CType):
1907 def __init__(self, name):
1908 self.name = name
1910 def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0):
1911 if entity_code:
1912 return self.name + " " + entity_code
1913 else:
1914 return self.name
1916 def specialize(self, values):
1917 if self in values:
1918 return values[self]
1919 else:
1920 return self
1922 def same_as_resolved_type(self, other_type):
1923 if isinstance(other_type, TemplatePlaceholderType):
1924 return self.name == other_type.name
1925 else:
1926 return 0
1928 def __hash__(self):
1929 return hash(self.name)
1931 def __cmp__(self, other):
1932 if isinstance(other, TemplatePlaceholderType):
1933 return cmp(self.name, other.name)
1934 else:
1935 return cmp(type(self), type(other))
1937 class CEnumType(CType):
1938 # name string
1939 # cname string or None
1940 # typedef_flag boolean
1942 is_enum = 1
1943 signed = 1
1944 rank = -1 # Ranks below any integer type
1945 to_py_function = "PyInt_FromLong"
1946 from_py_function = "PyInt_AsLong"
1948 def __init__(self, name, cname, typedef_flag):
1949 self.name = name
1950 self.cname = cname
1951 self.values = []
1952 self.typedef_flag = typedef_flag
1954 def __str__(self):
1955 return self.name
1957 def __repr__(self):
1958 return "<CEnumType %s %s%s>" % (self.name, self.cname,
1959 ("", " typedef")[self.typedef_flag])
1961 def declaration_code(self, entity_code,
1962 for_display = 0, dll_linkage = None, pyrex = 0):
1963 if pyrex:
1964 return self.base_declaration_code(self.cname, entity_code)
1965 else:
1966 if self.typedef_flag:
1967 base = self.cname
1968 else:
1969 base = "enum %s" % self.cname
1970 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1973 class CStringType(object):
1974 # Mixin class for C string types.
1976 is_string = 1
1977 is_unicode = 0
1979 to_py_function = "__Pyx_PyBytes_FromString"
1980 from_py_function = "__Pyx_PyBytes_AsString"
1981 exception_value = "NULL"
1983 def literal_code(self, value):
1984 assert isinstance(value, str)
1985 return '"%s"' % StringEncoding.escape_byte_string(value)
1988 class CUTF8CharArrayType(CStringType, CArrayType):
1989 # C 'char []' type.
1991 pymemberdef_typecode = "T_STRING_INPLACE"
1992 is_unicode = 1
1994 to_py_function = "PyUnicode_DecodeUTF8"
1995 exception_value = "NULL"
1997 def __init__(self, size):
1998 CArrayType.__init__(self, c_char_type, size)
2000 class CCharArrayType(CStringType, CArrayType):
2001 # C 'char []' type.
2003 pymemberdef_typecode = "T_STRING_INPLACE"
2005 def __init__(self, size):
2006 CArrayType.__init__(self, c_char_type, size)
2009 class CCharPtrType(CStringType, CPtrType):
2010 # C 'char *' type.
2012 pymemberdef_typecode = "T_STRING"
2014 def __init__(self):
2015 CPtrType.__init__(self, c_char_type)
2018 class CUCharPtrType(CStringType, CPtrType):
2019 # C 'unsigned char *' type.
2021 pymemberdef_typecode = "T_STRING"
2023 to_py_function = "__Pyx_PyBytes_FromUString"
2024 from_py_function = "__Pyx_PyBytes_AsUString"
2026 def __init__(self):
2027 CPtrType.__init__(self, c_uchar_type)
2030 class UnspecifiedType(PyrexType):
2031 # Used as a placeholder until the type can be determined.
2033 is_unspecified = 1
2035 def declaration_code(self, entity_code,
2036 for_display = 0, dll_linkage = None, pyrex = 0):
2037 return "<unspecified>"
2039 def same_as_resolved_type(self, other_type):
2040 return False
2043 class ErrorType(PyrexType):
2044 # Used to prevent propagation of error messages.
2046 is_error = 1
2047 exception_value = "0"
2048 exception_check = 0
2049 to_py_function = "dummy"
2050 from_py_function = "dummy"
2052 def create_to_py_utility_code(self, env):
2053 return True
2055 def create_from_py_utility_code(self, env):
2056 return True
2058 def declaration_code(self, entity_code,
2059 for_display = 0, dll_linkage = None, pyrex = 0):
2060 return "<error>"
2062 def same_as_resolved_type(self, other_type):
2063 return 1
2065 def error_condition(self, result_code):
2066 return "dummy"
2069 rank_to_type_name = (
2070 "char", # 0
2071 "short", # 1
2072 "int", # 2
2073 "long", # 3
2074 "Py_ssize_t", # 4
2075 "size_t", # 5
2076 "PY_LONG_LONG", # 6
2077 "float", # 7
2078 "double", # 8
2079 "long double", # 9
2080 )
2082 py_object_type = PyObjectType()
2084 c_void_type = CVoidType()
2085 c_void_ptr_type = CPtrType(c_void_type)
2086 c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
2088 c_uchar_type = CIntType(0, 0, "T_UBYTE")
2089 c_ushort_type = CIntType(1, 0, "T_USHORT")
2090 c_uint_type = CUIntType(2, 0, "T_UINT")
2091 c_ulong_type = CULongType(3, 0, "T_ULONG")
2092 c_ulonglong_type = CULongLongType(6, 0, "T_ULONGLONG")
2094 c_char_type = CIntType(0, 1, "T_CHAR")
2095 c_short_type = CIntType(1, 1, "T_SHORT")
2096 c_int_type = CIntType(2, 1, "T_INT")
2097 c_long_type = CLongType(3, 1, "T_LONG")
2098 c_longlong_type = CLongLongType(6, 1, "T_LONGLONG")
2099 c_bint_type = CBIntType(2, 1, "T_INT")
2101 c_schar_type = CIntType(0, 2, "T_CHAR")
2102 c_sshort_type = CIntType(1, 2, "T_SHORT")
2103 c_sint_type = CIntType(2, 2, "T_INT")
2104 c_slong_type = CLongType(3, 2, "T_LONG")
2105 c_slonglong_type = CLongLongType(6, 2, "T_LONGLONG")
2107 c_py_ssize_t_type = CPySSizeTType(4, 2, "T_PYSSIZET")
2108 c_size_t_type = CSizeTType(5, 0, "T_SIZET")
2110 c_float_type = CFloatType(7, "T_FLOAT", math_h_modifier='f')
2111 c_double_type = CFloatType(8, "T_DOUBLE")
2112 c_longdouble_type = CFloatType(9, math_h_modifier='l')
2114 c_double_complex_type = CComplexType(c_double_type)
2116 c_null_ptr_type = CNullPtrType(c_void_type)
2117 c_char_array_type = CCharArrayType(None)
2118 c_char_ptr_type = CCharPtrType()
2119 c_uchar_ptr_type = CUCharPtrType()
2120 c_utf8_char_array_type = CUTF8CharArrayType(None)
2121 c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
2122 c_int_ptr_type = CPtrType(c_int_type)
2123 c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
2124 c_size_t_ptr_type = CPtrType(c_size_t_type)
2126 c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1)
2128 c_anon_enum_type = CAnonEnumType(-1, 1)
2130 # the Py_buffer type is defined in Builtin.py
2131 c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
2132 c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
2134 error_type = ErrorType()
2135 unspecified_type = UnspecifiedType()
2137 sign_and_rank_to_type = {
2138 #(signed, rank)
2139 (0, 0): c_uchar_type,
2140 (0, 1): c_ushort_type,
2141 (0, 2): c_uint_type,
2142 (0, 3): c_ulong_type,
2143 (0, 6): c_ulonglong_type,
2145 (1, 0): c_char_type,
2146 (1, 1): c_short_type,
2147 (1, 2): c_int_type,
2148 (1, 3): c_long_type,
2149 (1, 6): c_longlong_type,
2151 (2, 0): c_schar_type,
2152 (2, 1): c_sshort_type,
2153 (2, 2): c_sint_type,
2154 (2, 3): c_slong_type,
2155 (2, 6): c_slonglong_type,
2157 (0, 4): c_py_ssize_t_type,
2158 (1, 4): c_py_ssize_t_type,
2159 (2, 4): c_py_ssize_t_type,
2160 (0, 5): c_size_t_type,
2161 (1, 5): c_size_t_type,
2162 (2, 5): c_size_t_type,
2164 (1, 7): c_float_type,
2165 (1, 8): c_double_type,
2166 (1, 9): c_longdouble_type,
2167 # In case we're mixing unsigned ints and floats...
2168 (0, 7): c_float_type,
2169 (0, 8): c_double_type,
2170 (0, 9): c_longdouble_type,
2171 }
2173 modifiers_and_name_to_type = {
2174 #(signed, longness, name)
2175 (0, 0, "char"): c_uchar_type,
2176 (0, -1, "int"): c_ushort_type,
2177 (0, 0, "int"): c_uint_type,
2178 (0, 1, "int"): c_ulong_type,
2179 (0, 2, "int"): c_ulonglong_type,
2180 (1, 0, "void"): c_void_type,
2181 (1, 0, "char"): c_char_type,
2182 (1, -1, "int"): c_short_type,
2183 (1, 0, "int"): c_int_type,
2184 (1, 1, "int"): c_long_type,
2185 (1, 2, "int"): c_longlong_type,
2186 (1, 0, "float"): c_float_type,
2187 (1, 0, "double"): c_double_type,
2188 (1, 1, "double"): c_longdouble_type,
2189 (1, 0, "object"): py_object_type,
2190 (1, 0, "bint"): c_bint_type,
2191 (2, 0, "char"): c_schar_type,
2192 (2, -1, "int"): c_sshort_type,
2193 (2, 0, "int"): c_sint_type,
2194 (2, 1, "int"): c_slong_type,
2195 (2, 2, "int"): c_slonglong_type,
2197 (2, 0, "Py_ssize_t"): c_py_ssize_t_type,
2198 (0, 0, "size_t") : c_size_t_type,
2200 (1, 0, "long"): c_long_type,
2201 (1, 0, "short"): c_short_type,
2202 (1, 0, "longlong"): c_longlong_type,
2203 (1, 0, "bint"): c_bint_type,
2204 }
2206 def is_promotion0(src_type, dst_type):
2207 if src_type.is_numeric and dst_type.is_numeric:
2208 if src_type.is_int and dst_type.is_int:
2209 if src_type.is_enum:
2210 return True
2211 elif src_type.signed:
2212 return dst_type.signed and src_type.rank <= dst_type.rank
2213 elif dst_type.signed: # and not src_type.signed
2214 src_type.rank < dst_type.rank
2215 else:
2216 return src_type.rank <= dst_type.rank
2217 elif src_type.is_float and dst_type.is_float:
2218 return src_type.rank <= dst_type.rank
2219 else:
2220 return False
2221 else:
2222 return False
2224 def is_promotion(src_type, dst_type):
2225 # It's hard to find a hard definition of promotion, but empirical
2226 # evidence suggests that the below is all that's allowed.
2227 if src_type.is_numeric:
2228 if dst_type.same_as(c_int_type):
2229 return src_type.is_enum or (src_type.is_int and (not src_type.signed) + src_type.rank < dst_type.rank)
2230 elif dst_type.same_as(c_double_type):
2231 return src_type.is_float and src_type.rank <= dst_type.rank
2232 return False
2234 def best_match(args, functions, pos=None):
2235 """
2236 Given a list args of arguments and a list of functions, choose one
2237 to call which seems to be the "best" fit for this list of arguments.
2238 This function is used, e.g., when deciding which overloaded method
2239 to dispatch for C++ classes.
2241 We first eliminate functions based on arity, and if only one
2242 function has the correct arity, we return it. Otherwise, we weight
2243 functions based on how much work must be done to convert the
2244 arguments, with the following priorities:
2245 * identical types or pointers to identical types
2246 * promotions
2247 * non-Python types
2248 That is, we prefer functions where no arguments need converted,
2249 and failing that, functions where only promotions are required, and
2250 so on.
2252 If no function is deemed a good fit, or if two or more functions have
2253 the same weight, we return None (as there is no best match). If pos
2254 is not None, we also generate an error.
2255 """
2256 # TODO: args should be a list of types, not a list of Nodes.
2257 actual_nargs = len(args)
2259 candidates = []
2260 errors = []
2261 for func in functions:
2262 error_mesg = ""
2263 func_type = func.type
2264 if func_type.is_ptr:
2265 func_type = func_type.base_type
2266 # Check function type
2267 if not func_type.is_cfunction:
2268 if not func_type.is_error and pos is not None:
2269 error_mesg = "Calling non-function type '%s'" % func_type
2270 errors.append((func, error_mesg))
2271 continue
2272 # Check no. of args
2273 max_nargs = len(func_type.args)
2274 min_nargs = max_nargs - func_type.optional_arg_count
2275 if actual_nargs < min_nargs or \
2276 (not func_type.has_varargs and actual_nargs > max_nargs):
2277 if max_nargs == min_nargs and not func_type.has_varargs:
2278 expectation = max_nargs
2279 elif actual_nargs < min_nargs:
2280 expectation = "at least %s" % min_nargs
2281 else:
2282 expectation = "at most %s" % max_nargs
2283 error_mesg = "Call with wrong number of arguments (expected %s, got %s)" \
2284 % (expectation, actual_nargs)
2285 errors.append((func, error_mesg))
2286 continue
2287 candidates.append((func, func_type))
2289 # Optimize the most common case of no overloading...
2290 if len(candidates) == 1:
2291 return candidates[0][0]
2292 elif len(candidates) == 0:
2293 if len(errors) == 1 and pos is not None:
2294 error(pos, errors[0][1])
2295 return None
2297 possibilities = []
2298 bad_types = []
2299 for func, func_type in candidates:
2300 score = [0,0,0]
2301 for i in range(min(len(args), len(func_type.args))):
2302 src_type = args[i].type
2303 dst_type = func_type.args[i].type
2304 if dst_type.assignable_from(src_type):
2305 if src_type == dst_type or dst_type.same_as(src_type):
2306 pass # score 0
2307 elif is_promotion(src_type, dst_type):
2308 score[2] += 1
2309 elif not src_type.is_pyobject:
2310 score[1] += 1
2311 else:
2312 score[0] += 1
2313 else:
2314 error_mesg = "Invalid conversion from '%s' to '%s'"%(src_type,
2315 dst_type)
2316 bad_types.append((func, error_mesg))
2317 break
2318 else:
2319 possibilities.append((score, func)) # so we can sort it
2320 if possibilities:
2321 possibilities.sort()
2322 if len(possibilities) > 1 and possibilities[0][0] == possibilities[1][0]:
2323 if pos is not None:
2324 error(pos, "ambiguous overloaded method")
2325 return None
2326 return possibilities[0][1]
2327 if pos is not None:
2328 if len(bad_types) == 1:
2329 error(pos, bad_types[0][1])
2330 else:
2331 error(pos, "no suitable method found")
2332 return None
2335 def widest_numeric_type(type1, type2):
2336 # Given two numeric types, return the narrowest type
2337 # encompassing both of them.
2338 if type1 == type2:
2339 return type1
2340 if type1.is_complex:
2341 if type2.is_complex:
2342 return CComplexType(widest_numeric_type(type1.real_type, type2.real_type))
2343 else:
2344 return CComplexType(widest_numeric_type(type1.real_type, type2))
2345 elif type2.is_complex:
2346 return CComplexType(widest_numeric_type(type1, type2.real_type))
2347 if type1.is_enum and type2.is_enum:
2348 return c_int_type
2349 elif type1 is type2:
2350 return type1
2351 elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
2352 if type2.rank > type1.rank:
2353 return type2
2354 else:
2355 return type1
2356 else:
2357 return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
2359 def spanning_type(type1, type2):
2360 # Return a type assignable from both type1 and type2.
2361 if type1 is py_object_type or type2 is py_object_type:
2362 return py_object_type
2363 elif type1 == type2:
2364 return type1
2365 elif type1.is_numeric and type2.is_numeric:
2366 return widest_numeric_type(type1, type2)
2367 elif type1.is_builtin_type and type1.name == 'float' and type2.is_numeric:
2368 return widest_numeric_type(c_double_type, type2)
2369 elif type2.is_builtin_type and type2.name == 'float' and type1.is_numeric:
2370 return widest_numeric_type(type1, c_double_type)
2371 elif type1.is_pyobject ^ type2.is_pyobject:
2372 return py_object_type
2373 elif type1.is_extension_type and type2.is_extension_type:
2374 if type1.typeobj_is_imported() or type2.typeobj_is_imported():
2375 return py_object_type
2376 while True:
2377 if type1.subtype_of(type2):
2378 return type2
2379 elif type2.subtype_of(type1):
2380 return type1
2381 type1, type2 = type1.base_type, type2.base_type
2382 if type1 is None or type2 is None:
2383 return py_object_type
2384 elif type1.assignable_from(type2):
2385 if type1.is_extension_type and type1.typeobj_is_imported():
2386 # external types are unsafe, so we use PyObject instead
2387 return py_object_type
2388 return type1
2389 elif type2.assignable_from(type1):
2390 if type2.is_extension_type and type2.typeobj_is_imported():
2391 # external types are unsafe, so we use PyObject instead
2392 return py_object_type
2393 return type2
2394 else:
2395 return py_object_type
2397 def simple_c_type(signed, longness, name):
2398 # Find type descriptor for simple type given name and modifiers.
2399 # Returns None if arguments don't make sense.
2400 return modifiers_and_name_to_type.get((signed, longness, name))
2402 def parse_basic_type(name):
2403 base = None
2404 if name.startswith('p_'):
2405 base = parse_basic_type(name[2:])
2406 elif name.startswith('p'):
2407 base = parse_basic_type(name[1:])
2408 elif name.endswith('*'):
2409 base = parse_basic_type(name[:-1])
2410 if base:
2411 return CPtrType(base)
2412 elif name.startswith('u'):
2413 return simple_c_type(0, 0, name[1:])
2414 else:
2415 return simple_c_type(1, 0, name)
2417 def c_array_type(base_type, size):
2418 # Construct a C array type.
2419 if base_type is c_char_type:
2420 return CCharArrayType(size)
2421 elif base_type is error_type:
2422 return error_type
2423 else:
2424 return CArrayType(base_type, size)
2426 def c_ptr_type(base_type):
2427 # Construct a C pointer type.
2428 if base_type is c_char_type:
2429 return c_char_ptr_type
2430 elif base_type is c_uchar_type:
2431 return c_uchar_ptr_type
2432 elif base_type is error_type:
2433 return error_type
2434 else:
2435 return CPtrType(base_type)
2437 def c_ref_type(base_type):
2438 # Construct a C reference type
2439 if base_type is error_type:
2440 return error_type
2441 else:
2442 return CReferenceType(base_type)
2444 def Node_to_type(node, env):
2445 from ExprNodes import NameNode, AttributeNode, StringNode, error
2446 if isinstance(node, StringNode):
2447 node = NameNode(node.pos, name=node.value)
2448 if isinstance(node, NameNode) and node.name in rank_to_type_name:
2449 return simple_c_type(1, 0, node.name)
2450 elif isinstance(node, (AttributeNode, NameNode)):
2451 node.analyze_types(env)
2452 if not node.entry.is_type:
2453 pass
2454 else:
2455 error(node.pos, "Bad type")
2457 def same_type(type1, type2):
2458 return type1.same_as(type2)
2460 def assignable_from(type1, type2):
2461 return type1.assignable_from(type2)
2463 def typecast(to_type, from_type, expr_code):
2464 # Return expr_code cast to a C type which can be
2465 # assigned to to_type, assuming its existing C type
2466 # is from_type.
2467 if to_type is from_type or \
2468 (not to_type.is_pyobject and assignable_from(to_type, from_type)):
2469 return expr_code
2470 else:
2471 #print "typecast: to", to_type, "from", from_type ###
2472 return to_type.cast_code(expr_code)
2475 type_conversion_predeclarations = """
2476 /* Type Conversion Predeclarations */
2478 #if PY_MAJOR_VERSION < 3
2479 #define __Pyx_PyBytes_FromString PyString_FromString
2480 #define __Pyx_PyBytes_FromStringAndSize PyString_FromStringAndSize
2481 #define __Pyx_PyBytes_AsString PyString_AsString
2482 #else
2483 #define __Pyx_PyBytes_FromString PyBytes_FromString
2484 #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
2485 #define __Pyx_PyBytes_AsString PyBytes_AsString
2486 #endif
2488 #define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((char*)s)
2489 #define __Pyx_PyBytes_AsUString(s) ((unsigned char*) __Pyx_PyBytes_AsString(s))
2491 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
2492 static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
2493 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
2495 #if !defined(T_PYSSIZET)
2496 #if PY_VERSION_HEX < 0x02050000
2497 #define T_PYSSIZET T_INT
2498 #elif !defined(T_LONGLONG)
2499 #define T_PYSSIZET \\
2500 ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
2501 ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : -1))
2502 #else
2503 #define T_PYSSIZET \\
2504 ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
2505 ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : \\
2506 ((sizeof(Py_ssize_t) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))
2507 #endif
2508 #endif
2511 #if !defined(T_ULONGLONG)
2512 #define __Pyx_T_UNSIGNED_INT(x) \\
2513 ((sizeof(x) == sizeof(unsigned char)) ? T_UBYTE : \\
2514 ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
2515 ((sizeof(x) == sizeof(unsigned int)) ? T_UINT : \\
2516 ((sizeof(x) == sizeof(unsigned long)) ? T_ULONG : -1))))
2517 #else
2518 #define __Pyx_T_UNSIGNED_INT(x) \\
2519 ((sizeof(x) == sizeof(unsigned char)) ? T_UBYTE : \\
2520 ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
2521 ((sizeof(x) == sizeof(unsigned int)) ? T_UINT : \\
2522 ((sizeof(x) == sizeof(unsigned long)) ? T_ULONG : \\
2523 ((sizeof(x) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))))
2524 #endif
2525 #if !defined(T_LONGLONG)
2526 #define __Pyx_T_SIGNED_INT(x) \\
2527 ((sizeof(x) == sizeof(char)) ? T_BYTE : \\
2528 ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
2529 ((sizeof(x) == sizeof(int)) ? T_INT : \\
2530 ((sizeof(x) == sizeof(long)) ? T_LONG : -1))))
2531 #else
2532 #define __Pyx_T_SIGNED_INT(x) \\
2533 ((sizeof(x) == sizeof(char)) ? T_BYTE : \\
2534 ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
2535 ((sizeof(x) == sizeof(int)) ? T_INT : \\
2536 ((sizeof(x) == sizeof(long)) ? T_LONG : \\
2537 ((sizeof(x) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))))
2538 #endif
2540 #define __Pyx_T_FLOATING(x) \\
2541 ((sizeof(x) == sizeof(float)) ? T_FLOAT : \\
2542 ((sizeof(x) == sizeof(double)) ? T_DOUBLE : -1))
2544 #if !defined(T_SIZET)
2545 #if !defined(T_ULONGLONG)
2546 #define T_SIZET \\
2547 ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
2548 ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : -1))
2549 #else
2550 #define T_SIZET \\
2551 ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
2552 ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : \\
2553 ((sizeof(size_t) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))
2554 #endif
2555 #endif
2557 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
2558 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
2559 static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
2561 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
2563 """ + type_conversion_predeclarations
2565 type_conversion_functions = """
2566 /* Type Conversion Functions */
2568 static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
2569 if (x == Py_True) return 1;
2570 else if ((x == Py_False) | (x == Py_None)) return 0;
2571 else return PyObject_IsTrue(x);
2572 }
2574 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
2575 PyNumberMethods *m;
2576 const char *name = NULL;
2577 PyObject *res = NULL;
2578 #if PY_VERSION_HEX < 0x03000000
2579 if (PyInt_Check(x) || PyLong_Check(x))
2580 #else
2581 if (PyLong_Check(x))
2582 #endif
2583 return Py_INCREF(x), x;
2584 m = Py_TYPE(x)->tp_as_number;
2585 #if PY_VERSION_HEX < 0x03000000
2586 if (m && m->nb_int) {
2587 name = "int";
2588 res = PyNumber_Int(x);
2589 }
2590 else if (m && m->nb_long) {
2591 name = "long";
2592 res = PyNumber_Long(x);
2593 }
2594 #else
2595 if (m && m->nb_int) {
2596 name = "int";
2597 res = PyNumber_Long(x);
2598 }
2599 #endif
2600 if (res) {
2601 #if PY_VERSION_HEX < 0x03000000
2602 if (!PyInt_Check(res) && !PyLong_Check(res)) {
2603 #else
2604 if (!PyLong_Check(res)) {
2605 #endif
2606 PyErr_Format(PyExc_TypeError,
2607 "__%s__ returned non-%s (type %.200s)",
2608 name, name, Py_TYPE(res)->tp_name);
2609 Py_DECREF(res);
2610 return NULL;
2611 }
2612 }
2613 else if (!PyErr_Occurred()) {
2614 PyErr_SetString(PyExc_TypeError,
2615 "an integer is required");
2616 }
2617 return res;
2618 }
2620 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
2621 Py_ssize_t ival;
2622 PyObject* x = PyNumber_Index(b);
2623 if (!x) return -1;
2624 ival = PyInt_AsSsize_t(x);
2625 Py_DECREF(x);
2626 return ival;
2627 }
2629 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
2630 #if PY_VERSION_HEX < 0x02050000
2631 if (ival <= LONG_MAX)
2632 return PyInt_FromLong((long)ival);
2633 else {
2634 unsigned char *bytes = (unsigned char *) &ival;
2635 int one = 1; int little = (int)*(unsigned char*)&one;
2636 return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
2637 }
2638 #else
2639 return PyInt_FromSize_t(ival);
2640 #endif
2641 }
2643 static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
2644 unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
2645 if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
2646 return (size_t)-1;
2647 } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
2648 PyErr_SetString(PyExc_OverflowError,
2649 "value too large to convert to size_t");
2650 return (size_t)-1;
2651 }
2652 return (size_t)val;
2653 }
2655 """ + type_conversion_functions
