Cython has moved to github.
cython-devel
view Cython/Compiler/PyrexTypes.py @ 2194:b9d8cecc8975
general optimisation support for calls to builtin types and their methods
currently providing optimisations for
- getattr(o,a)
- getattr(o,a,d)
- X.append(o)
- L.append(o)
- list.append(L,x)
currently providing optimisations for
- getattr(o,a)
- getattr(o,a,d)
- X.append(o)
- L.append(o)
- list.append(L,x)
| author | Stefan Behnel <scoder@users.berlios.de> |
|---|---|
| date | Sun Mar 29 13:27:55 2009 +0200 (3 years ago) |
| parents | 2289ab00261d |
| children | 2db7bd0dc99d |
line source
1 #
2 # Pyrex - Types
3 #
5 from Cython.Utils import UtilityCode
6 import StringEncoding
7 import Naming
8 import copy
10 class BaseType(object):
11 #
12 # Base class for all Pyrex types including pseudo-types.
14 def cast_code(self, expr_code):
15 return "((%s)%s)" % (self.declaration_code(""), expr_code)
17 def specalization_name(self):
18 return self.declaration_code("").replace(" ", "__")
20 def base_declaration_code(self, base_code, entity_code):
21 if entity_code:
22 return "%s %s" % (base_code, entity_code)
23 else:
24 return base_code
26 class PyrexType(BaseType):
27 #
28 # Base class for all Pyrex types.
29 #
30 # is_pyobject boolean Is a Python object type
31 # is_extension_type boolean Is a Python extension type
32 # is_numeric boolean Is a C numeric type
33 # is_int boolean Is a C integer type
34 # is_longlong boolean Is a long long or unsigned long long.
35 # is_float boolean Is a C floating point type
36 # is_void boolean Is the C void type
37 # is_array boolean Is a C array type
38 # is_ptr boolean Is a C pointer type
39 # is_null_ptr boolean Is the type of NULL
40 # is_cfunction boolean Is a C function type
41 # is_struct_or_union boolean Is a C struct or union type
42 # is_struct boolean Is a C struct type
43 # is_enum boolean Is a C enum type
44 # is_typedef boolean Is a typedef type
45 # is_string boolean Is a C char * type
46 # is_unicode boolean Is a UTF-8 encoded C char * type
47 # is_returncode boolean Is used only to signal exceptions
48 # is_error boolean Is the dummy error type
49 # is_buffer boolean Is buffer access type
50 # has_attributes boolean Has C dot-selectable attributes
51 # default_value string Initial value
52 # pymemberdef_typecode string Type code for PyMemberDef struct
53 #
54 # declaration_code(entity_code,
55 # for_display = 0, dll_linkage = None, pyrex = 0)
56 # Returns a code fragment for the declaration of an entity
57 # of this type, given a code fragment for the entity.
58 # * If for_display, this is for reading by a human in an error
59 # message; otherwise it must be valid C code.
60 # * If dll_linkage is not None, it must be 'DL_EXPORT' or
61 # 'DL_IMPORT', and will be added to the base type part of
62 # the declaration.
63 # * If pyrex = 1, this is for use in a 'cdef extern'
64 # statement of a Pyrex include file.
65 #
66 # assignable_from(src_type)
67 # Tests whether a variable of this type can be
68 # assigned a value of type src_type.
69 #
70 # same_as(other_type)
71 # Tests whether this type represents the same type
72 # as other_type.
73 #
74 # as_argument_type():
75 # Coerces array type into pointer type for use as
76 # a formal argument type.
77 #
79 is_pyobject = 0
80 is_extension_type = 0
81 is_builtin_type = 0
82 is_numeric = 0
83 is_int = 0
84 is_longlong = 0
85 is_float = 0
86 is_void = 0
87 is_array = 0
88 is_ptr = 0
89 is_null_ptr = 0
90 is_cfunction = 0
91 is_struct_or_union = 0
92 is_struct = 0
93 is_enum = 0
94 is_typedef = 0
95 is_string = 0
96 is_unicode = 0
97 is_returncode = 0
98 is_error = 0
99 is_buffer = 0
100 has_attributes = 0
101 default_value = ""
102 pymemberdef_typecode = None
104 def resolve(self):
105 # If a typedef, returns the base type.
106 return self
108 def literal_code(self, value):
109 # Returns a C code fragment representing a literal
110 # value of this type.
111 return str(value)
113 def __str__(self):
114 return self.declaration_code("", for_display = 1).strip()
116 def same_as(self, other_type, **kwds):
117 return self.same_as_resolved_type(other_type.resolve(), **kwds)
119 def same_as_resolved_type(self, other_type):
120 return self == other_type or other_type is error_type
122 def subtype_of(self, other_type):
123 return self.subtype_of_resolved_type(other_type.resolve())
125 def subtype_of_resolved_type(self, other_type):
126 return self.same_as(other_type)
128 def assignable_from(self, src_type):
129 return self.assignable_from_resolved_type(src_type.resolve())
131 def assignable_from_resolved_type(self, src_type):
132 return self.same_as(src_type)
134 def as_argument_type(self):
135 return self
137 def is_complete(self):
138 # A type is incomplete if it is an unsized array,
139 # a struct whose attributes are not defined, etc.
140 return 1
142 def is_simple_buffer_dtype(self):
143 return (self.is_int or self.is_float or self.is_pyobject or
144 self.is_extension_type or self.is_ptr)
146 class CTypedefType(BaseType):
147 #
148 # Pseudo-type defined with a ctypedef statement in a
149 # 'cdef extern from' block. Delegates most attribute
150 # lookups to the base type. ANYTHING NOT DEFINED
151 # HERE IS DELEGATED!
152 #
153 # qualified_name string
154 # typedef_cname string
155 # typedef_base_type PyrexType
157 is_typedef = 1
159 def __init__(self, cname, base_type):
160 self.typedef_cname = cname
161 self.typedef_base_type = base_type
163 def resolve(self):
164 return self.typedef_base_type.resolve()
166 def declaration_code(self, entity_code,
167 for_display = 0, dll_linkage = None, pyrex = 0):
168 name = self.declaration_name(for_display, pyrex)
169 return self.base_declaration_code(name, entity_code)
171 def declaration_name(self, for_display = 0, pyrex = 0):
172 if pyrex or for_display:
173 return self.qualified_name
174 else:
175 return self.typedef_cname
177 def as_argument_type(self):
178 return self
180 def cast_code(self, expr_code):
181 # If self is really an array (rather than pointer), we can't cast.
182 # For example, the gmp mpz_t.
183 if self.typedef_base_type.is_ptr:
184 return self.typedef_base_type.cast_code(expr_code)
185 else:
186 return BaseType.cast_code(self, expr_code)
188 def __repr__(self):
189 return "<CTypedefType %s>" % self.typedef_cname
191 def __str__(self):
192 return self.declaration_name(for_display = 1)
194 def __getattr__(self, name):
195 return getattr(self.typedef_base_type, name)
197 class BufferType(BaseType):
198 #
199 # Delegates most attribute
200 # lookups to the base type. ANYTHING NOT DEFINED
201 # HERE IS DELEGATED!
203 # dtype PyrexType
204 # ndim int
205 # mode str
206 # negative_indices bool
207 # cast bool
208 # is_buffer bool
209 # writable bool
211 is_buffer = 1
212 writable = True
213 def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
214 self.base = base
215 self.dtype = dtype
216 self.ndim = ndim
217 self.buffer_ptr_type = CPtrType(dtype)
218 self.mode = mode
219 self.negative_indices = negative_indices
220 self.cast = cast
222 def as_argument_type(self):
223 return self
225 def __getattr__(self, name):
226 return getattr(self.base, name)
228 def __repr__(self):
229 return "<BufferType %r>" % self.base
232 class PyObjectType(PyrexType):
233 #
234 # Base class for all Python object types (reference-counted).
235 #
236 # buffer_defaults dict or None Default options for bu
238 name = "object"
239 is_pyobject = 1
240 default_value = "0"
241 pymemberdef_typecode = "T_OBJECT"
242 buffer_defaults = None
244 def __str__(self):
245 return "Python object"
247 def __repr__(self):
248 return "<PyObjectType>"
250 def assignable_from(self, src_type):
251 return 1 # Conversion will be attempted
253 def declaration_code(self, entity_code,
254 for_display = 0, dll_linkage = None, pyrex = 0):
255 if pyrex or for_display:
256 return self.base_declaration_code("object", entity_code)
257 else:
258 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
260 def as_pyobject(self, cname):
261 if (not self.is_complete()) or self.is_extension_type:
262 return "(PyObject *)" + cname
263 else:
264 return cname
266 class BuiltinObjectType(PyObjectType):
268 is_builtin_type = 1
269 has_attributes = 1
270 base_type = None
271 module_name = '__builtin__'
273 def __init__(self, name, cname):
274 self.name = name
275 self.cname = cname
276 self.typeptr_cname = "&" + cname
278 def set_scope(self, scope):
279 self.scope = scope
280 if scope:
281 scope.parent_type = self
283 def __str__(self):
284 return "%s object" % self.name
286 def __repr__(self):
287 return "<%s>"% self.cname
289 def assignable_from(self, src_type):
290 if isinstance(src_type, BuiltinObjectType):
291 return src_type.name == self.name
292 else:
293 return not src_type.is_extension_type
295 def typeobj_is_available(self):
296 return True
298 def attributes_known(self):
299 return True
301 def subtype_of(self, type):
302 return type.is_pyobject and self.assignable_from(type)
304 def type_test_code(self, arg):
305 type_name = self.name
306 if type_name == 'str':
307 check = 'PyString_CheckExact'
308 elif type_name == 'set':
309 check = 'PyAnySet_CheckExact'
310 elif type_name == 'frozenset':
311 check = 'PyFrozenSet_CheckExact'
312 elif type_name == 'bool':
313 check = 'PyBool_Check'
314 else:
315 check = 'Py%s_CheckExact' % type_name.capitalize()
316 return 'likely(%s(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", Py_TYPE(%s)->tp_name), 0)' % (check, arg, arg, self.name, arg)
318 def declaration_code(self, entity_code,
319 for_display = 0, dll_linkage = None, pyrex = 0):
320 if pyrex or for_display:
321 return self.base_declaration_code(self.name, entity_code)
322 else:
323 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
326 class PyExtensionType(PyObjectType):
327 #
328 # A Python extension type.
329 #
330 # name string
331 # scope CClassScope Attribute namespace
332 # visibility string
333 # typedef_flag boolean
334 # base_type PyExtensionType or None
335 # module_name string or None Qualified name of defining module
336 # objstruct_cname string Name of PyObject struct
337 # typeobj_cname string or None C code fragment referring to type object
338 # typeptr_cname string or None Name of pointer to external type object
339 # vtabslot_cname string Name of C method table member
340 # vtabstruct_cname string Name of C method table struct
341 # vtabptr_cname string Name of pointer to C method table
342 # vtable_cname string Name of C method table definition
344 is_extension_type = 1
345 has_attributes = 1
347 def __init__(self, name, typedef_flag, base_type):
348 self.name = name
349 self.scope = None
350 self.typedef_flag = typedef_flag
351 self.base_type = base_type
352 self.module_name = None
353 self.objstruct_cname = None
354 self.typeobj_cname = None
355 self.typeptr_cname = None
356 self.vtabslot_cname = None
357 self.vtabstruct_cname = None
358 self.vtabptr_cname = None
359 self.vtable_cname = None
361 def set_scope(self, scope):
362 self.scope = scope
363 if scope:
364 scope.parent_type = self
366 def subtype_of_resolved_type(self, other_type):
367 if other_type.is_extension_type:
368 return self is other_type or (
369 self.base_type and self.base_type.subtype_of(other_type))
370 else:
371 return other_type is py_object_type
373 def typeobj_is_available(self):
374 # Do we have a pointer to the type object?
375 return self.typeptr_cname
377 def typeobj_is_imported(self):
378 # If we don't know the C name of the type object but we do
379 # know which module it's defined in, it will be imported.
380 return self.typeobj_cname is None and self.module_name is not None
382 def declaration_code(self, entity_code,
383 for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
384 if pyrex or for_display:
385 return self.base_declaration_code(self.name, entity_code)
386 else:
387 if self.typedef_flag:
388 base_format = "%s"
389 else:
390 base_format = "struct %s"
391 base = public_decl(base_format % self.objstruct_cname, dll_linkage)
392 if deref:
393 return "%s %s" % (base, entity_code)
394 else:
395 return "%s *%s" % (base, entity_code)
397 def type_test_code(self, py_arg):
398 return "__Pyx_TypeTest(%s, %s)" % (py_arg, self.typeptr_cname)
400 def attributes_known(self):
401 return self.scope is not None
403 def __str__(self):
404 return self.name
406 def __repr__(self):
407 return "<PyExtensionType %s%s>" % (self.scope.class_name,
408 ("", " typedef")[self.typedef_flag])
411 class CType(PyrexType):
412 #
413 # Base class for all C types (non-reference-counted).
414 #
415 # to_py_function string C function for converting to Python object
416 # from_py_function string C function for constructing from Python object
417 #
419 to_py_function = None
420 from_py_function = None
421 exception_value = None
422 exception_check = 1
424 def create_convert_utility_code(self, env):
425 return True
427 def error_condition(self, result_code):
428 conds = []
429 if self.is_string:
430 conds.append("(!%s)" % result_code)
431 elif self.exception_value is not None:
432 conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
433 if self.exception_check:
434 conds.append("PyErr_Occurred()")
435 if len(conds) > 0:
436 return " && ".join(conds)
437 else:
438 return 0
441 class CVoidType(CType):
442 is_void = 1
444 def __repr__(self):
445 return "<CVoidType>"
447 def declaration_code(self, entity_code,
448 for_display = 0, dll_linkage = None, pyrex = 0):
449 base = public_decl("void", dll_linkage)
450 return self.base_declaration_code(base, entity_code)
452 def is_complete(self):
453 return 0
456 class CNumericType(CType):
457 #
458 # Base class for all C numeric types.
459 #
460 # rank integer Relative size
461 # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
462 #
464 is_numeric = 1
465 default_value = "0"
467 sign_words = ("unsigned ", "", "signed ")
469 def __init__(self, rank, signed = 1, pymemberdef_typecode = None):
470 self.rank = rank
471 self.signed = signed
472 self.pymemberdef_typecode = pymemberdef_typecode
474 def sign_and_name(self):
475 s = self.sign_words[self.signed]
476 n = rank_to_type_name[self.rank]
477 return s + n
479 def __repr__(self):
480 return "<CNumericType %s>" % self.sign_and_name()
482 def declaration_code(self, entity_code,
483 for_display = 0, dll_linkage = None, pyrex = 0):
484 base = public_decl(self.sign_and_name(), dll_linkage)
485 if for_display and self.is_longlong:
486 base = base.replace('PY_LONG_LONG', 'long long')
487 return self.base_declaration_code(base, entity_code)
490 int_conversion_list = {}
491 type_conversion_functions = ""
492 type_conversion_predeclarations = ""
494 class CIntType(CNumericType):
496 is_int = 1
497 typedef_flag = 0
498 to_py_function = "PyInt_FromLong"
499 from_py_function = "__pyx_PyInt_AsLong"
500 exception_value = -1
502 def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
503 CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
504 self.is_returncode = is_returncode
505 if self.from_py_function == '__pyx_PyInt_AsLong':
506 self.from_py_function = self.get_type_conversion()
508 def get_type_conversion(self):
509 # error on overflow
510 c_type = self.sign_and_name()
511 c_name = c_type.replace(' ', '_');
512 func_name = "__pyx_PyInt_%s" % c_name;
513 if func_name not in int_conversion_list:
514 # no env to add utility code to
515 global type_conversion_predeclarations, type_conversion_functions
516 if self.signed:
517 neg_test = ""
518 else:
519 neg_test = " || (long_val < 0)"
520 type_conversion_predeclarations += """
521 static INLINE %(c_type)s %(func_name)s(PyObject* x);""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name }
522 type_conversion_functions += """
523 static INLINE %(c_type)s %(func_name)s(PyObject* x) {
524 if (sizeof(%(c_type)s) < sizeof(long)) {
525 long long_val = __pyx_PyInt_AsLong(x);
526 %(c_type)s val = (%(c_type)s)long_val;
527 if (unlikely((val != long_val) %(neg_test)s)) {
528 PyErr_SetString(PyExc_OverflowError, "value too large to convert to %(c_type)s");
529 return (%(c_type)s)-1;
530 }
531 return val;
532 }
533 else {
534 return __pyx_PyInt_AsLong(x);
535 }
536 }
537 """ % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name, 'neg_test': neg_test }
538 int_conversion_list[func_name] = True
539 return func_name
541 def assignable_from_resolved_type(self, src_type):
542 return src_type.is_int or src_type.is_enum or src_type is error_type
545 class CBIntType(CIntType):
547 to_py_function = "__Pyx_PyBool_FromLong"
548 from_py_function = "__Pyx_PyObject_IsTrue"
549 exception_check = 0
552 class CAnonEnumType(CIntType):
554 is_enum = 1
557 class CUIntType(CIntType):
559 to_py_function = "PyLong_FromUnsignedLong"
560 from_py_function = "PyInt_AsUnsignedLongMask"
561 exception_value = -1
564 class CULongType(CUIntType):
566 to_py_function = "PyLong_FromUnsignedLong"
567 from_py_function = "PyInt_AsUnsignedLongMask"
570 class CLongLongType(CIntType):
572 is_longlong = 1
573 to_py_function = "PyLong_FromLongLong"
574 from_py_function = "__pyx_PyInt_AsLongLong"
577 class CULongLongType(CUIntType):
579 is_longlong = 1
580 to_py_function = "PyLong_FromUnsignedLongLong"
581 from_py_function = "__pyx_PyInt_AsUnsignedLongLong"
584 class CPySSizeTType(CIntType):
586 to_py_function = "PyInt_FromSsize_t"
587 from_py_function = "__pyx_PyIndex_AsSsize_t"
589 def sign_and_name(self):
590 return rank_to_type_name[self.rank]
593 class CSizeTType(CUIntType):
595 to_py_function = "__pyx_PyInt_FromSize_t"
596 from_py_function = "__pyx_PyInt_AsSize_t"
598 def sign_and_name(self):
599 return rank_to_type_name[self.rank]
602 class CFloatType(CNumericType):
604 is_float = 1
605 to_py_function = "PyFloat_FromDouble"
606 from_py_function = "__pyx_PyFloat_AsDouble"
608 def __init__(self, rank, pymemberdef_typecode = None, math_h_modifier = ''):
609 CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
610 self.math_h_modifier = math_h_modifier
612 def assignable_from_resolved_type(self, src_type):
613 return src_type.is_numeric or src_type is error_type
616 class CArrayType(CType):
617 # base_type CType Element type
618 # size integer or None Number of elements
620 is_array = 1
622 def __init__(self, base_type, size):
623 self.base_type = base_type
624 self.size = size
625 if base_type is c_char_type:
626 self.is_string = 1
628 def __repr__(self):
629 return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
631 def same_as_resolved_type(self, other_type):
632 return ((other_type.is_array and
633 self.base_type.same_as(other_type.base_type))
634 or other_type is error_type)
636 def assignable_from_resolved_type(self, src_type):
637 # Can't assign to a variable of an array type
638 return 0
640 def element_ptr_type(self):
641 return c_ptr_type(self.base_type)
643 def declaration_code(self, entity_code,
644 for_display = 0, dll_linkage = None, pyrex = 0):
645 if self.size is not None:
646 dimension_code = self.size
647 else:
648 dimension_code = ""
649 if entity_code.startswith("*"):
650 entity_code = "(%s)" % entity_code
651 return self.base_type.declaration_code(
652 "%s[%s]" % (entity_code, dimension_code),
653 for_display, dll_linkage, pyrex)
655 def as_argument_type(self):
656 return c_ptr_type(self.base_type)
658 def is_complete(self):
659 return self.size is not None
662 class CPtrType(CType):
663 # base_type CType Referenced type
665 is_ptr = 1
666 default_value = "0"
668 def __init__(self, base_type):
669 self.base_type = base_type
671 def __repr__(self):
672 return "<CPtrType %s>" % repr(self.base_type)
674 def same_as_resolved_type(self, other_type):
675 return ((other_type.is_ptr and
676 self.base_type.same_as(other_type.base_type))
677 or other_type is error_type)
679 def declaration_code(self, entity_code,
680 for_display = 0, dll_linkage = None, pyrex = 0):
681 #print "CPtrType.declaration_code: pointer to", self.base_type ###
682 return self.base_type.declaration_code(
683 "*%s" % entity_code,
684 for_display, dll_linkage, pyrex)
686 def assignable_from_resolved_type(self, other_type):
687 if other_type is error_type:
688 return 1
689 if other_type.is_null_ptr:
690 return 1
691 if self.base_type.is_cfunction:
692 if other_type.is_ptr:
693 other_type = other_type.base_type.resolve()
694 if other_type.is_cfunction:
695 return self.base_type.pointer_assignable_from_resolved_type(other_type)
696 else:
697 return 0
698 if other_type.is_array or other_type.is_ptr:
699 return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
700 return 0
703 class CNullPtrType(CPtrType):
705 is_null_ptr = 1
708 class CFuncType(CType):
709 # return_type CType
710 # args [CFuncTypeArg]
711 # has_varargs boolean
712 # exception_value string
713 # exception_check boolean True if PyErr_Occurred check needed
714 # calling_convention string Function calling convention
715 # nogil boolean Can be called without gil
716 # with_gil boolean Acquire gil around function body
718 is_cfunction = 1
719 original_sig = None
721 def __init__(self, return_type, args, has_varargs = 0,
722 exception_value = None, exception_check = 0, calling_convention = "",
723 nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0):
724 self.return_type = return_type
725 self.args = args
726 self.has_varargs = has_varargs
727 self.optional_arg_count = optional_arg_count
728 self.exception_value = exception_value
729 self.exception_check = exception_check
730 self.calling_convention = calling_convention
731 self.nogil = nogil
732 self.with_gil = with_gil
733 self.is_overridable = is_overridable
735 def __repr__(self):
736 arg_reprs = map(repr, self.args)
737 if self.has_varargs:
738 arg_reprs.append("...")
739 return "<CFuncType %s %s[%s]>" % (
740 repr(self.return_type),
741 self.calling_convention_prefix(),
742 ",".join(arg_reprs))
744 def calling_convention_prefix(self):
745 cc = self.calling_convention
746 if cc:
747 return cc + " "
748 else:
749 return ""
751 def same_c_signature_as(self, other_type, as_cmethod = 0):
752 return self.same_c_signature_as_resolved_type(
753 other_type.resolve(), as_cmethod)
755 def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
756 #print "CFuncType.same_c_signature_as_resolved_type:", \
757 # self, other_type, "as_cmethod =", as_cmethod ###
758 if other_type is error_type:
759 return 1
760 if not other_type.is_cfunction:
761 return 0
762 if self.is_overridable != other_type.is_overridable:
763 return 0
764 nargs = len(self.args)
765 if nargs != len(other_type.args):
766 return 0
767 # When comparing C method signatures, the first argument
768 # is exempt from compatibility checking (the proper check
769 # is performed elsewhere).
770 for i in range(as_cmethod, nargs):
771 if not self.args[i].type.same_as(
772 other_type.args[i].type):
773 return 0
774 if self.has_varargs != other_type.has_varargs:
775 return 0
776 if self.optional_arg_count != other_type.optional_arg_count:
777 return 0
778 if not self.return_type.same_as(other_type.return_type):
779 return 0
780 if not self.same_calling_convention_as(other_type):
781 return 0
782 return 1
784 def compatible_signature_with(self, other_type, as_cmethod = 0):
785 return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
787 def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
788 #print "CFuncType.same_c_signature_as_resolved_type:", \
789 # self, other_type, "as_cmethod =", as_cmethod ###
790 if other_type is error_type:
791 return 1
792 if not other_type.is_cfunction:
793 return 0
794 if not self.is_overridable and other_type.is_overridable:
795 return 0
796 nargs = len(self.args)
797 if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
798 return 0
799 if self.optional_arg_count < other_type.optional_arg_count:
800 return 0
801 # When comparing C method signatures, the first argument
802 # is exempt from compatibility checking (the proper check
803 # is performed elsewhere).
804 for i in range(as_cmethod, len(other_type.args)):
805 if not self.args[i].type.same_as(
806 other_type.args[i].type):
807 return 0
808 if self.has_varargs != other_type.has_varargs:
809 return 0
810 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
811 return 0
812 if not self.same_calling_convention_as(other_type):
813 return 0
814 if self.nogil != other_type.nogil:
815 return 0
816 self.original_sig = other_type.original_sig or other_type
817 if as_cmethod:
818 self.args[0] = other_type.args[0]
819 return 1
822 def narrower_c_signature_than(self, other_type, as_cmethod = 0):
823 return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
825 def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
826 if other_type is error_type:
827 return 1
828 if not other_type.is_cfunction:
829 return 0
830 nargs = len(self.args)
831 if nargs != len(other_type.args):
832 return 0
833 for i in range(as_cmethod, nargs):
834 if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
835 return 0
836 else:
837 self.args[i].needs_type_test = other_type.args[i].needs_type_test \
838 or not self.args[i].type.same_as(other_type.args[i].type)
839 if self.has_varargs != other_type.has_varargs:
840 return 0
841 if self.optional_arg_count != other_type.optional_arg_count:
842 return 0
843 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
844 return 0
845 return 1
847 def same_calling_convention_as(self, other):
848 sc1 = self.calling_convention == '__stdcall'
849 sc2 = other.calling_convention == '__stdcall'
850 return sc1 == sc2
852 def same_exception_signature_as(self, other_type):
853 return self.same_exception_signature_as_resolved_type(
854 other_type.resolve())
856 def same_exception_signature_as_resolved_type(self, other_type):
857 return self.exception_value == other_type.exception_value \
858 and self.exception_check == other_type.exception_check
860 def same_as_resolved_type(self, other_type, as_cmethod = 0):
861 return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
862 and self.same_exception_signature_as_resolved_type(other_type) \
863 and self.nogil == other_type.nogil
865 def pointer_assignable_from_resolved_type(self, other_type):
866 return self.same_c_signature_as_resolved_type(other_type) \
867 and self.same_exception_signature_as_resolved_type(other_type) \
868 and not (self.nogil and not other_type.nogil)
870 def declaration_code(self, entity_code,
871 for_display = 0, dll_linkage = None, pyrex = 0,
872 with_calling_convention = 1):
873 arg_decl_list = []
874 for arg in self.args[:len(self.args)-self.optional_arg_count]:
875 arg_decl_list.append(
876 arg.type.declaration_code("", for_display, pyrex = pyrex))
877 if self.is_overridable:
878 arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
879 if self.optional_arg_count:
880 arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
881 if self.has_varargs:
882 arg_decl_list.append("...")
883 arg_decl_code = ", ".join(arg_decl_list)
884 if not arg_decl_code and not pyrex:
885 arg_decl_code = "void"
886 trailer = ""
887 if (pyrex or for_display) and not self.return_type.is_pyobject:
888 if self.exception_value and self.exception_check:
889 trailer = " except? %s" % self.exception_value
890 elif self.exception_value:
891 trailer = " except %s" % self.exception_value
892 elif self.exception_check == '+':
893 trailer = " except +"
894 else:
895 " except *" # ignored
896 if self.nogil:
897 trailer += " nogil"
898 if not with_calling_convention:
899 cc = ''
900 else:
901 cc = self.calling_convention_prefix()
902 if (not entity_code and cc) or entity_code.startswith("*"):
903 entity_code = "(%s%s)" % (cc, entity_code)
904 cc = ""
905 return self.return_type.declaration_code(
906 "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
907 for_display, dll_linkage, pyrex)
909 def function_header_code(self, func_name, arg_code):
910 return "%s%s(%s)" % (self.calling_convention_prefix(),
911 func_name, arg_code)
913 def signature_string(self):
914 s = self.declaration_code("")
915 return s
917 def signature_cast_string(self):
918 s = self.declaration_code("(*)", with_calling_convention=False)
919 return '(%s)' % s
922 class CFuncTypeArg(object):
923 # name string
924 # cname string
925 # type PyrexType
926 # pos source file position
928 def __init__(self, name, type, pos, cname=None):
929 self.name = name
930 if cname is not None:
931 self.cname = cname
932 else:
933 self.cname = Naming.var_prefix + name
934 self.type = type
935 self.pos = pos
936 self.not_none = False
937 self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
939 def __repr__(self):
940 return "%s:%s" % (self.name, repr(self.type))
942 def declaration_code(self, for_display = 0):
943 return self.type.declaration_code(self.cname, for_display)
946 class CStructOrUnionType(CType):
947 # name string
948 # cname string
949 # kind string "struct" or "union"
950 # scope StructOrUnionScope, or None if incomplete
951 # typedef_flag boolean
953 is_struct_or_union = 1
954 has_attributes = 1
956 def __init__(self, name, kind, scope, typedef_flag, cname):
957 self.name = name
958 self.cname = cname
959 self.kind = kind
960 self.scope = scope
961 self.typedef_flag = typedef_flag
962 self.is_struct = kind == 'struct'
963 if self.is_struct:
964 self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
965 self.exception_check = True
966 self._convert_code = None
968 def create_convert_utility_code(self, env):
969 if env.outer_scope is None:
970 return False
971 if self._convert_code is None:
972 import Code
973 code = Code.CCodeWriter()
974 header = "static PyObject* %s(%s)" % (self.to_py_function, self.declaration_code('s'))
975 code.putln("%s {" % header)
976 code.putln("PyObject* res;")
977 code.putln("PyObject* member;")
978 code.putln("res = PyDict_New(); if (res == NULL) return NULL;")
979 for member in self.scope.var_entries:
980 if member.type.to_py_function and member.type.create_convert_utility_code(env):
981 interned_name = env.get_string_const(member.name, identifier=True)
982 env.add_py_string(interned_name)
983 code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % (
984 member.type.to_py_function, member.cname))
985 code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % interned_name.pystring_cname)
986 code.putln("Py_DECREF(member);")
987 else:
988 self.to_py_function = None
989 return False
990 code.putln("return res;")
991 code.putln("bad:")
992 code.putln("Py_XDECREF(member);")
993 code.putln("Py_DECREF(res);")
994 code.putln("return NULL;")
995 code.putln("}")
996 proto = header + ";"
997 # This is a bit of a hack, we need a forward declaration
998 # due to the way things are ordered in the module...
999 entry = env.lookup(self.name)
1000 if entry.visibility != 'extern':
1001 proto = self.declaration_code('') + ';\n' + proto
1002 self._convert_code = UtilityCode(proto=proto, impl=code.buffer.getvalue())
1004 env.use_utility_code(self._convert_code)
1005 return True
1007 def __repr__(self):
1008 return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
1009 ("", " typedef")[self.typedef_flag])
1011 def declaration_code(self, entity_code,
1012 for_display = 0, dll_linkage = None, pyrex = 0):
1013 if pyrex:
1014 return self.base_declaration_code(self.name, entity_code)
1015 else:
1016 if for_display:
1017 base = self.name
1018 elif self.typedef_flag:
1019 base = self.cname
1020 else:
1021 base = "%s %s" % (self.kind, self.cname)
1022 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1024 def __cmp__(self, other):
1025 try:
1026 if self.name == other.name:
1027 return 0
1028 else:
1029 return 1
1030 except AttributeError:
1031 return 1
1033 def is_complete(self):
1034 return self.scope is not None
1036 def attributes_known(self):
1037 return self.is_complete()
1039 def can_be_complex(self):
1040 # Does the struct consist of exactly two floats?
1041 fields = self.scope.var_entries
1042 return len(fields) == 2 and fields[0].type.is_float and fields[1].type.is_float
1045 class CEnumType(CType):
1046 # name string
1047 # cname string or None
1048 # typedef_flag boolean
1050 is_enum = 1
1051 signed = 1
1052 rank = -1 # Ranks below any integer type
1053 to_py_function = "PyInt_FromLong"
1054 from_py_function = "PyInt_AsLong"
1056 def __init__(self, name, cname, typedef_flag):
1057 self.name = name
1058 self.cname = cname
1059 self.values = []
1060 self.typedef_flag = typedef_flag
1062 def __str__(self):
1063 return self.name
1065 def __repr__(self):
1066 return "<CEnumType %s %s%s>" % (self.name, self.cname,
1067 ("", " typedef")[self.typedef_flag])
1069 def declaration_code(self, entity_code,
1070 for_display = 0, dll_linkage = None, pyrex = 0):
1071 if pyrex:
1072 return self.base_declaration_code(self.cname, entity_code)
1073 else:
1074 if self.typedef_flag:
1075 base = self.cname
1076 else:
1077 base = "enum %s" % self.cname
1078 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1081 class CStringType(object):
1082 # Mixin class for C string types.
1084 is_string = 1
1085 is_unicode = 0
1087 to_py_function = "__Pyx_PyBytes_FromString"
1088 from_py_function = "__Pyx_PyBytes_AsString"
1089 exception_value = "NULL"
1091 def literal_code(self, value):
1092 assert isinstance(value, str)
1093 return '"%s"' % StringEncoding.escape_byte_string(value)
1096 class CUTF8CharArrayType(CStringType, CArrayType):
1097 # C 'char []' type.
1099 pymemberdef_typecode = "T_STRING_INPLACE"
1100 is_unicode = 1
1102 to_py_function = "PyUnicode_DecodeUTF8"
1103 exception_value = "NULL"
1105 def __init__(self, size):
1106 CArrayType.__init__(self, c_char_type, size)
1108 class CCharArrayType(CStringType, CArrayType):
1109 # C 'char []' type.
1111 pymemberdef_typecode = "T_STRING_INPLACE"
1113 def __init__(self, size):
1114 CArrayType.__init__(self, c_char_type, size)
1117 class CCharPtrType(CStringType, CPtrType):
1118 # C 'char *' type.
1120 pymemberdef_typecode = "T_STRING"
1122 def __init__(self):
1123 CPtrType.__init__(self, c_char_type)
1126 class UnspecifiedType(PyrexType):
1127 # Used as a placeholder until the type can be determined.
1129 def declaration_code(self, entity_code,
1130 for_display = 0, dll_linkage = None, pyrex = 0):
1131 return "<unspecified>"
1133 def same_as_resolved_type(self, other_type):
1134 return False
1137 class ErrorType(PyrexType):
1138 # Used to prevent propagation of error messages.
1140 is_error = 1
1141 exception_value = "0"
1142 exception_check = 0
1143 to_py_function = "dummy"
1144 from_py_function = "dummy"
1146 def create_convert_utility_code(self, env):
1147 return True
1149 def declaration_code(self, entity_code,
1150 for_display = 0, dll_linkage = None, pyrex = 0):
1151 return "<error>"
1153 def same_as_resolved_type(self, other_type):
1154 return 1
1156 def error_condition(self, result_code):
1157 return "dummy"
1160 rank_to_type_name = (
1161 "char", # 0
1162 "short", # 1
1163 "int", # 2
1164 "long", # 3
1165 "Py_ssize_t", # 4
1166 "size_t", # 5
1167 "PY_LONG_LONG", # 6
1168 "float", # 7
1169 "double", # 8
1170 "long double", # 9
1171 )
1173 py_object_type = PyObjectType()
1175 c_void_type = CVoidType()
1176 c_void_ptr_type = CPtrType(c_void_type)
1177 c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
1179 c_uchar_type = CIntType(0, 0, "T_UBYTE")
1180 c_ushort_type = CIntType(1, 0, "T_USHORT")
1181 c_uint_type = CUIntType(2, 0, "T_UINT")
1182 c_ulong_type = CULongType(3, 0, "T_ULONG")
1183 c_ulonglong_type = CULongLongType(6, 0, "T_ULONGLONG")
1185 c_char_type = CIntType(0, 1, "T_CHAR")
1186 c_short_type = CIntType(1, 1, "T_SHORT")
1187 c_int_type = CIntType(2, 1, "T_INT")
1188 c_long_type = CIntType(3, 1, "T_LONG")
1189 c_longlong_type = CLongLongType(6, 1, "T_LONGLONG")
1190 c_bint_type = CBIntType(2, 1, "T_INT")
1192 c_schar_type = CIntType(0, 2, "T_CHAR")
1193 c_sshort_type = CIntType(1, 2, "T_SHORT")
1194 c_sint_type = CIntType(2, 2, "T_INT")
1195 c_slong_type = CIntType(3, 2, "T_LONG")
1196 c_slonglong_type = CLongLongType(6, 2, "T_LONGLONG")
1198 c_py_ssize_t_type = CPySSizeTType(4, 2, "T_PYSSIZET")
1199 c_size_t_type = CSizeTType(5, 0, "T_SIZET")
1201 c_float_type = CFloatType(7, "T_FLOAT", math_h_modifier='f')
1202 c_double_type = CFloatType(8, "T_DOUBLE")
1203 c_longdouble_type = CFloatType(9, math_h_modifier='l')
1205 c_null_ptr_type = CNullPtrType(c_void_type)
1206 c_char_array_type = CCharArrayType(None)
1207 c_char_ptr_type = CCharPtrType()
1208 c_utf8_char_array_type = CUTF8CharArrayType(None)
1209 c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
1210 c_int_ptr_type = CPtrType(c_int_type)
1211 c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
1212 c_size_t_ptr_type = CPtrType(c_size_t_type)
1214 c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1)
1216 c_anon_enum_type = CAnonEnumType(-1, 1)
1218 # the Py_buffer type is defined in Builtin.py
1219 c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
1220 c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
1222 error_type = ErrorType()
1223 unspecified_type = UnspecifiedType()
1225 sign_and_rank_to_type = {
1226 #(signed, rank)
1227 (0, 0): c_uchar_type,
1228 (0, 1): c_ushort_type,
1229 (0, 2): c_uint_type,
1230 (0, 3): c_ulong_type,
1231 (0, 6): c_ulonglong_type,
1233 (1, 0): c_char_type,
1234 (1, 1): c_short_type,
1235 (1, 2): c_int_type,
1236 (1, 3): c_long_type,
1237 (1, 6): c_longlong_type,
1239 (2, 0): c_schar_type,
1240 (2, 1): c_sshort_type,
1241 (2, 2): c_sint_type,
1242 (2, 3): c_slong_type,
1243 (2, 6): c_slonglong_type,
1245 (0, 4): c_py_ssize_t_type,
1246 (1, 4): c_py_ssize_t_type,
1247 (2, 4): c_py_ssize_t_type,
1248 (0, 5): c_size_t_type,
1249 (1, 5): c_size_t_type,
1250 (2, 5): c_size_t_type,
1252 (1, 7): c_float_type,
1253 (1, 8): c_double_type,
1254 (1, 9): c_longdouble_type,
1255 # In case we're mixing unsigned ints and floats...
1256 (0, 7): c_float_type,
1257 (0, 8): c_double_type,
1258 (0, 9): c_longdouble_type,
1259 }
1261 modifiers_and_name_to_type = {
1262 #(signed, longness, name)
1263 (0, 0, "char"): c_uchar_type,
1264 (0, -1, "int"): c_ushort_type,
1265 (0, 0, "int"): c_uint_type,
1266 (0, 1, "int"): c_ulong_type,
1267 (0, 2, "int"): c_ulonglong_type,
1268 (1, 0, "void"): c_void_type,
1269 (1, 0, "char"): c_char_type,
1270 (1, -1, "int"): c_short_type,
1271 (1, 0, "int"): c_int_type,
1272 (1, 1, "int"): c_long_type,
1273 (1, 2, "int"): c_longlong_type,
1274 (1, 0, "float"): c_float_type,
1275 (1, 0, "double"): c_double_type,
1276 (1, 1, "double"): c_longdouble_type,
1277 (1, 0, "object"): py_object_type,
1278 (1, 0, "bint"): c_bint_type,
1279 (2, 0, "char"): c_schar_type,
1280 (2, -1, "int"): c_sshort_type,
1281 (2, 0, "int"): c_sint_type,
1282 (2, 1, "int"): c_slong_type,
1283 (2, 2, "int"): c_slonglong_type,
1285 (2, 0, "Py_ssize_t"): c_py_ssize_t_type,
1286 (0, 0, "size_t") : c_size_t_type,
1288 (1, 0, "long"): c_long_type,
1289 (1, 0, "short"): c_short_type,
1290 (1, 0, "longlong"): c_longlong_type,
1291 (1, 0, "bint"): c_bint_type,
1292 }
1294 def widest_numeric_type(type1, type2):
1295 # Given two numeric types, return the narrowest type
1296 # encompassing both of them.
1297 if type1.is_enum and type2.is_enum:
1298 return c_int_type
1299 elif type1 is type2:
1300 return type1
1301 elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
1302 if type2.rank > type1.rank:
1303 return type2
1304 else:
1305 return type1
1306 else:
1307 return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
1308 return widest_type
1310 def simple_c_type(signed, longness, name):
1311 # Find type descriptor for simple type given name and modifiers.
1312 # Returns None if arguments don't make sense.
1313 return modifiers_and_name_to_type.get((signed, longness, name))
1315 def parse_basic_type(name):
1316 base = None
1317 if name.startswith('p_'):
1318 base = parse_basic_type(name[2:])
1319 elif name.startswith('p'):
1320 base = parse_basic_type(name[1:])
1321 elif name.endswith('*'):
1322 base = parse_basic_type(name[:-1])
1323 if base:
1324 return CPtrType(base)
1325 elif name.startswith('u'):
1326 return simple_c_type(0, 0, name[1:])
1327 else:
1328 return simple_c_type(1, 0, name)
1330 def c_array_type(base_type, size):
1331 # Construct a C array type.
1332 if base_type is c_char_type:
1333 return CCharArrayType(size)
1334 elif base_type is error_type:
1335 return error_type
1336 else:
1337 return CArrayType(base_type, size)
1339 def c_ptr_type(base_type):
1340 # Construct a C pointer type.
1341 if base_type is c_char_type:
1342 return c_char_ptr_type
1343 elif base_type is error_type:
1344 return error_type
1345 else:
1346 return CPtrType(base_type)
1348 def Node_to_type(node, env):
1349 from ExprNodes import NameNode, AttributeNode, StringNode, error
1350 if isinstance(node, StringNode):
1351 node = NameNode(node.pos, name=node.value)
1352 if isinstance(node, NameNode) and node.name in rank_to_type_name:
1353 return simple_c_type(1, 0, node.name)
1354 elif isinstance(node, (AttributeNode, NameNode)):
1355 node.analyze_types(env)
1356 if not node.entry.is_type:
1357 pass
1358 else:
1359 error(node.pos, "Bad type")
1361 def public_decl(base, dll_linkage):
1362 if dll_linkage:
1363 return "%s(%s)" % (dll_linkage, base)
1364 else:
1365 return base
1367 def same_type(type1, type2):
1368 return type1.same_as(type2)
1370 def assignable_from(type1, type2):
1371 return type1.assignable_from(type2)
1373 def typecast(to_type, from_type, expr_code):
1374 # Return expr_code cast to a C type which can be
1375 # assigned to to_type, assuming its existing C type
1376 # is from_type.
1377 if to_type is from_type or \
1378 (not to_type.is_pyobject and assignable_from(to_type, from_type)):
1379 return expr_code
1380 else:
1381 #print "typecast: to", to_type, "from", from_type ###
1382 return to_type.cast_code(expr_code)
1385 type_conversion_predeclarations = """
1386 /* Type Conversion Predeclarations */
1388 #if PY_MAJOR_VERSION < 3
1389 #define __Pyx_PyBytes_FromString PyString_FromString
1390 #define __Pyx_PyBytes_FromStringAndSize PyString_FromStringAndSize
1391 #define __Pyx_PyBytes_AsString PyString_AsString
1392 #else
1393 #define __Pyx_PyBytes_FromString PyBytes_FromString
1394 #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
1395 #define __Pyx_PyBytes_AsString PyBytes_AsString
1396 #endif
1398 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
1399 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x);
1400 static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x);
1401 static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x);
1403 #if !defined(T_PYSSIZET)
1404 #if PY_VERSION_HEX < 0x02050000
1405 #define T_PYSSIZET T_INT
1406 #elif !defined(T_LONGLONG)
1407 #define T_PYSSIZET \\
1408 ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
1409 ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : -1))
1410 #else
1411 #define T_PYSSIZET \\
1412 ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
1413 ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : \\
1414 ((sizeof(Py_ssize_t) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))
1415 #endif
1416 #endif
1418 #if !defined(T_SIZET)
1419 #if !defined(T_ULONGLONG)
1420 #define T_SIZET \\
1421 ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
1422 ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : -1))
1423 #else
1424 #define T_SIZET \\
1425 ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
1426 ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : \\
1427 ((sizeof(size_t) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))
1428 #endif
1429 #endif
1431 static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b);
1432 static INLINE PyObject * __pyx_PyInt_FromSize_t(size_t);
1433 static INLINE size_t __pyx_PyInt_AsSize_t(PyObject*);
1435 #define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x))
1436 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
1437 """ + type_conversion_predeclarations
1439 type_conversion_functions = """
1440 /* Type Conversion Functions */
1442 static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) {
1443 Py_ssize_t ival;
1444 PyObject* x = PyNumber_Index(b);
1445 if (!x) return -1;
1446 ival = PyInt_AsSsize_t(x);
1447 Py_DECREF(x);
1448 return ival;
1449 }
1451 static INLINE PyObject * __pyx_PyInt_FromSize_t(size_t ival) {
1452 #if PY_VERSION_HEX < 0x02050000
1453 if (ival <= LONG_MAX)
1454 return PyInt_FromLong((long)ival);
1455 else {
1456 unsigned char *bytes = (unsigned char *) &ival;
1457 int one = 1; int little = (int)*(unsigned char*)&one;
1458 return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
1459 }
1460 #else
1461 return PyInt_FromSize_t(ival);
1462 #endif
1463 }
1465 static INLINE size_t __pyx_PyInt_AsSize_t(PyObject* b) {
1466 unsigned PY_LONG_LONG val = __pyx_PyInt_AsUnsignedLongLong(b);
1467 if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
1468 return (size_t)-1;
1469 } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
1470 PyErr_SetString(PyExc_OverflowError, "value too large to convert to size_t");
1471 return (size_t)-1;
1472 }
1473 return val;
1474 }
1476 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
1477 if (x == Py_True) return 1;
1478 else if ((x == Py_False) | (x == Py_None)) return 0;
1479 else return PyObject_IsTrue(x);
1480 }
1482 static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) {
1483 #if PY_VERSION_HEX < 0x03000000
1484 if (PyInt_CheckExact(x)) {
1485 return PyInt_AS_LONG(x);
1486 }
1487 else
1488 #endif
1489 if (PyLong_CheckExact(x)) {
1490 return PyLong_AsLongLong(x);
1491 }
1492 else {
1493 PY_LONG_LONG val;
1494 #if PY_VERSION_HEX < 0x03000000
1495 PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
1496 val = __pyx_PyInt_AsLongLong(tmp);
1497 #else
1498 PyObject* tmp = PyNumber_Long(x); if (!tmp) return (PY_LONG_LONG)-1;
1499 val = PyLong_AsLongLong(tmp);
1500 #endif
1501 Py_DECREF(tmp);
1502 return val;
1503 }
1504 }
1506 static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
1507 #if PY_VERSION_HEX < 0x03000000
1508 if (PyInt_CheckExact(x)) {
1509 long val = PyInt_AS_LONG(x);
1510 if (unlikely(val < 0)) {
1511 PyErr_SetString(PyExc_OverflowError, "can't convert negative value to unsigned long long");
1512 return (unsigned PY_LONG_LONG)-1;
1513 }
1514 return val;
1515 }
1516 else
1517 #endif
1518 if (PyLong_CheckExact(x)) {
1519 return PyLong_AsUnsignedLongLong(x);
1520 }
1521 else {
1522 unsigned PY_LONG_LONG val;
1523 #if PY_VERSION_HEX < 0x03000000
1524 PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
1525 val = __pyx_PyInt_AsUnsignedLongLong(tmp);
1526 #else
1527 PyObject* tmp = PyNumber_Long(x); if (!tmp) return (PY_LONG_LONG)-1;
1528 val = PyLong_AsUnsignedLongLong(tmp);
1529 #endif
1530 Py_DECREF(tmp);
1531 return val;
1532 }
1533 }
1535 """ + type_conversion_functions
