Cython has moved to github.
cython-devel
view Cython/Compiler/PyrexTypes.py @ 3091:1a2e04bc1395
remove dependency on structmember.h
| author | Lisandro Dalcin <dalcinl@gmail.com> |
|---|---|
| date | Thu Mar 11 17:21:13 2010 -0300 (2 years ago) |
| parents | 982665cb1a01 |
| children | 667c147a8dc2 |
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 #
60 # declaration_code(entity_code,
61 # for_display = 0, dll_linkage = None, pyrex = 0)
62 # Returns a code fragment for the declaration of an entity
63 # of this type, given a code fragment for the entity.
64 # * If for_display, this is for reading by a human in an error
65 # message; otherwise it must be valid C code.
66 # * If dll_linkage is not None, it must be 'DL_EXPORT' or
67 # 'DL_IMPORT', and will be added to the base type part of
68 # the declaration.
69 # * If pyrex = 1, this is for use in a 'cdef extern'
70 # statement of a Pyrex include file.
71 #
72 # assignable_from(src_type)
73 # Tests whether a variable of this type can be
74 # assigned a value of type src_type.
75 #
76 # same_as(other_type)
77 # Tests whether this type represents the same type
78 # as other_type.
79 #
80 # as_argument_type():
81 # Coerces array type into pointer type for use as
82 # a formal argument type.
83 #
85 is_pyobject = 0
86 is_unspecified = 0
87 is_extension_type = 0
88 is_builtin_type = 0
89 is_numeric = 0
90 is_int = 0
91 is_float = 0
92 is_complex = 0
93 is_void = 0
94 is_array = 0
95 is_ptr = 0
96 is_null_ptr = 0
97 is_reference = 0
98 is_cfunction = 0
99 is_struct_or_union = 0
100 is_cpp_class = 0
101 is_struct = 0
102 is_enum = 0
103 is_typedef = 0
104 is_string = 0
105 is_unicode = 0
106 is_returncode = 0
107 is_error = 0
108 is_buffer = 0
109 has_attributes = 0
110 default_value = ""
112 def resolve(self):
113 # If a typedef, returns the base type.
114 return self
116 def specialize(self, values):
117 # TODO(danilo): Override wherever it makes sense.
118 return self
120 def literal_code(self, value):
121 # Returns a C code fragment representing a literal
122 # value of this type.
123 return str(value)
125 def __str__(self):
126 return self.declaration_code("", for_display = 1).strip()
128 def same_as(self, other_type, **kwds):
129 return self.same_as_resolved_type(other_type.resolve(), **kwds)
131 def same_as_resolved_type(self, other_type):
132 return self == other_type or other_type is error_type
134 def subtype_of(self, other_type):
135 return self.subtype_of_resolved_type(other_type.resolve())
137 def subtype_of_resolved_type(self, other_type):
138 return self.same_as(other_type)
140 def assignable_from(self, src_type):
141 return self.assignable_from_resolved_type(src_type.resolve())
143 def assignable_from_resolved_type(self, src_type):
144 return self.same_as(src_type)
146 def as_argument_type(self):
147 return self
149 def is_complete(self):
150 # A type is incomplete if it is an unsized array,
151 # a struct whose attributes are not defined, etc.
152 return 1
154 def is_simple_buffer_dtype(self):
155 return (self.is_int or self.is_float or self.is_complex or self.is_pyobject or
156 self.is_extension_type or self.is_ptr)
158 def struct_nesting_depth(self):
159 # Returns the number levels of nested structs. This is
160 # used for constructing a stack for walking the run-time
161 # type information of the struct.
162 return 1
165 def create_typedef_type(name, base_type, cname, is_external=0):
166 if base_type.is_complex:
167 if is_external:
168 raise ValueError("Complex external typedefs not supported")
169 return base_type
170 else:
171 return CTypedefType(name, base_type, cname, is_external)
173 class CTypedefType(BaseType):
174 #
175 # Pseudo-type defined with a ctypedef statement in a
176 # 'cdef extern from' block. Delegates most attribute
177 # lookups to the base type. ANYTHING NOT DEFINED
178 # HERE IS DELEGATED!
179 #
180 # qualified_name string
181 # typedef_name string
182 # typedef_cname string
183 # typedef_base_type PyrexType
184 # typedef_is_external bool
186 is_typedef = 1
187 typedef_is_external = 0
189 to_py_utility_code = None
190 from_py_utility_code = None
193 def __init__(self, name, base_type, cname, is_external=0):
194 assert not base_type.is_complex
195 self.typedef_name = name
196 self.typedef_cname = cname
197 self.typedef_base_type = base_type
198 self.typedef_is_external = is_external
200 def resolve(self):
201 return self.typedef_base_type.resolve()
203 def declaration_code(self, entity_code,
204 for_display = 0, dll_linkage = None, pyrex = 0):
205 if pyrex or for_display:
206 base_code = self.typedef_name
207 else:
208 base_code = public_decl(self.typedef_cname, dll_linkage)
209 return self.base_declaration_code(base_code, entity_code)
211 def as_argument_type(self):
212 return self
214 def cast_code(self, expr_code):
215 # If self is really an array (rather than pointer), we can't cast.
216 # For example, the gmp mpz_t.
217 if self.typedef_base_type.is_array:
218 base_type = self.typedef_base_type.base_type
219 return CPtrType(base_type).cast_code(expr_code)
220 else:
221 return BaseType.cast_code(self, expr_code)
223 def __repr__(self):
224 return "<CTypedefType %s>" % self.typedef_cname
226 def __str__(self):
227 return self.typedef_name
229 def _create_utility_code(self, template_utility_code,
230 template_function_name):
231 type_name = self.typedef_cname.replace(" ","_")
232 utility_code = template_utility_code.specialize(
233 type = self.typedef_cname,
234 TypeName = type_name)
235 function_name = template_function_name % type_name
236 return utility_code, function_name
238 def create_to_py_utility_code(self, env):
239 if self.typedef_is_external:
240 if not self.to_py_utility_code:
241 base_type = self.typedef_base_type
242 if base_type.is_int:
243 self.to_py_utility_code, self.to_py_function = \
244 self._create_utility_code(c_typedef_int_to_py_function,
245 '__Pyx_PyInt_to_py_%s')
246 elif base_type.is_float:
247 pass # XXX implement!
248 elif base_type.is_complex:
249 pass # XXX implement!
250 pass
251 if self.to_py_utility_code:
252 env.use_utility_code(self.to_py_utility_code)
253 return True
254 # delegation
255 return self.typedef_base_type.create_to_py_utility_code(env)
257 def create_from_py_utility_code(self, env):
258 if self.typedef_is_external:
259 if not self.from_py_utility_code:
260 base_type = self.typedef_base_type
261 if base_type.is_int:
262 self.from_py_utility_code, self.from_py_function = \
263 self._create_utility_code(c_typedef_int_from_py_function,
264 '__Pyx_PyInt_from_py_%s')
265 elif base_type.is_float:
266 pass # XXX implement!
267 elif base_type.is_complex:
268 pass # XXX implement!
269 if self.from_py_utility_code:
270 env.use_utility_code(self.from_py_utility_code)
271 return True
272 # delegation
273 return self.typedef_base_type.create_from_py_utility_code(env)
275 def error_condition(self, result_code):
276 if self.typedef_is_external:
277 if self.exception_value:
278 condition = "(%s == (%s)%s)" % (
279 result_code, self.typedef_cname, self.exception_value)
280 if self.exception_check:
281 condition += " && PyErr_Occurred()"
282 return condition
283 # delegation
284 return self.typedef_base_type.error_condition(result_code)
286 def __getattr__(self, name):
287 return getattr(self.typedef_base_type, name)
289 class BufferType(BaseType):
290 #
291 # Delegates most attribute
292 # lookups to the base type. ANYTHING NOT DEFINED
293 # HERE IS DELEGATED!
295 # dtype PyrexType
296 # ndim int
297 # mode str
298 # negative_indices bool
299 # cast bool
300 # is_buffer bool
301 # writable bool
303 is_buffer = 1
304 writable = True
305 def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
306 self.base = base
307 self.dtype = dtype
308 self.ndim = ndim
309 self.buffer_ptr_type = CPtrType(dtype)
310 self.mode = mode
311 self.negative_indices = negative_indices
312 self.cast = cast
314 def as_argument_type(self):
315 return self
317 def __getattr__(self, name):
318 return getattr(self.base, name)
320 def __repr__(self):
321 return "<BufferType %r>" % self.base
323 def public_decl(base, dll_linkage):
324 if dll_linkage:
325 return "%s(%s)" % (dll_linkage, base)
326 else:
327 return base
329 class PyObjectType(PyrexType):
330 #
331 # Base class for all Python object types (reference-counted).
332 #
333 # buffer_defaults dict or None Default options for bu
335 name = "object"
336 is_pyobject = 1
337 default_value = "0"
338 buffer_defaults = None
339 is_extern = False
340 is_subclassed = False
342 def __str__(self):
343 return "Python object"
345 def __repr__(self):
346 return "<PyObjectType>"
348 def can_coerce_to_pyobject(self, env):
349 return True
351 def assignable_from(self, src_type):
352 # except for pointers, conversion will be attempted
353 return not src_type.is_ptr or src_type.is_string
355 def declaration_code(self, entity_code,
356 for_display = 0, dll_linkage = None, pyrex = 0):
357 if pyrex or for_display:
358 return self.base_declaration_code("object", entity_code)
359 else:
360 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
362 def as_pyobject(self, cname):
363 if (not self.is_complete()) or self.is_extension_type:
364 return "(PyObject *)" + cname
365 else:
366 return cname
368 class BuiltinObjectType(PyObjectType):
370 is_builtin_type = 1
371 has_attributes = 1
372 base_type = None
373 module_name = '__builtin__'
375 alternative_name = None # used for str/bytes duality
377 def __init__(self, name, cname):
378 self.name = name
379 if name == 'str':
380 self.alternative_name = 'bytes'
381 elif name == 'bytes':
382 self.alternative_name = 'str'
383 self.cname = cname
384 self.typeptr_cname = "&" + cname
386 def set_scope(self, scope):
387 self.scope = scope
388 if scope:
389 scope.parent_type = self
391 def __str__(self):
392 return "%s object" % self.name
394 def __repr__(self):
395 return "<%s>"% self.cname
397 def assignable_from(self, src_type):
398 if isinstance(src_type, BuiltinObjectType):
399 return src_type.name == self.name or (
400 src_type.name == self.alternative_name and
401 src_type.name is not None)
402 elif src_type.is_extension_type:
403 return (src_type.module_name == '__builtin__' and
404 src_type.name == self.name)
405 else:
406 return True
408 def typeobj_is_available(self):
409 return True
411 def attributes_known(self):
412 return True
414 def subtype_of(self, type):
415 return type.is_pyobject and self.assignable_from(type)
417 def type_test_code(self, arg, notnone=False):
418 type_name = self.name
419 if type_name == 'str':
420 type_check = 'PyString_CheckExact'
421 elif type_name == 'set':
422 type_check = 'PyAnySet_CheckExact'
423 elif type_name == 'frozenset':
424 type_check = 'PyFrozenSet_CheckExact'
425 elif type_name == 'bool':
426 type_check = 'PyBool_Check'
427 else:
428 type_check = 'Py%s_CheckExact' % type_name.capitalize()
430 check = 'likely(%s(%s))' % (type_check, arg)
431 if not notnone:
432 check = check + ('||((%s) == Py_None)' % arg)
433 error = '(PyErr_Format(PyExc_TypeError, "Expected %s, got %%.200s", Py_TYPE(%s)->tp_name), 0)' % (self.name, arg)
434 return check + '||' + error
436 def declaration_code(self, entity_code,
437 for_display = 0, dll_linkage = None, pyrex = 0):
438 if pyrex or for_display:
439 return self.base_declaration_code(self.name, entity_code)
440 else:
441 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
444 class PyExtensionType(PyObjectType):
445 #
446 # A Python extension type.
447 #
448 # name string
449 # scope CClassScope Attribute namespace
450 # visibility string
451 # typedef_flag boolean
452 # base_type PyExtensionType or None
453 # module_name string or None Qualified name of defining module
454 # objstruct_cname string Name of PyObject struct
455 # objtypedef_cname string Name of PyObject struct typedef
456 # typeobj_cname string or None C code fragment referring to type object
457 # typeptr_cname string or None Name of pointer to external type object
458 # vtabslot_cname string Name of C method table member
459 # vtabstruct_cname string Name of C method table struct
460 # vtabptr_cname string Name of pointer to C method table
461 # vtable_cname string Name of C method table definition
463 is_extension_type = 1
464 has_attributes = 1
466 objtypedef_cname = None
468 def __init__(self, name, typedef_flag, base_type, is_external=0):
469 self.name = name
470 self.scope = None
471 self.typedef_flag = typedef_flag
472 if base_type is not None:
473 base_type.is_subclassed = True
474 self.base_type = base_type
475 self.module_name = None
476 self.objstruct_cname = None
477 self.typeobj_cname = None
478 self.typeptr_cname = None
479 self.vtabslot_cname = None
480 self.vtabstruct_cname = None
481 self.vtabptr_cname = None
482 self.vtable_cname = None
483 self.is_external = is_external
485 def set_scope(self, scope):
486 self.scope = scope
487 if scope:
488 scope.parent_type = self
490 def subtype_of_resolved_type(self, other_type):
491 if other_type.is_extension_type:
492 return self is other_type or (
493 self.base_type and self.base_type.subtype_of(other_type))
494 else:
495 return other_type is py_object_type
497 def typeobj_is_available(self):
498 # Do we have a pointer to the type object?
499 return self.typeptr_cname
501 def typeobj_is_imported(self):
502 # If we don't know the C name of the type object but we do
503 # know which module it's defined in, it will be imported.
504 return self.typeobj_cname is None and self.module_name is not None
506 def declaration_code(self, entity_code,
507 for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
508 if pyrex or for_display:
509 return self.base_declaration_code(self.name, entity_code)
510 else:
511 if self.typedef_flag:
512 base_format = "%s"
513 else:
514 base_format = "struct %s"
515 base = public_decl(base_format % self.objstruct_cname, dll_linkage)
516 if deref:
517 return "%s %s" % (base, entity_code)
518 else:
519 return "%s *%s" % (base, entity_code)
521 def type_test_code(self, py_arg, notnone=False):
523 none_check = "((%s) == Py_None)" % py_arg
524 type_check = "likely(__Pyx_TypeTest(%s, %s))" % (
525 py_arg, self.typeptr_cname)
526 if notnone:
527 return type_check
528 else:
529 return "likely(%s || %s)" % (none_check, type_check)
531 def attributes_known(self):
532 return self.scope is not None
534 def __str__(self):
535 return self.name
537 def __repr__(self):
538 return "<PyExtensionType %s%s>" % (self.scope.class_name,
539 ("", " typedef")[self.typedef_flag])
542 class CType(PyrexType):
543 #
544 # Base class for all C types (non-reference-counted).
545 #
546 # to_py_function string C function for converting to Python object
547 # from_py_function string C function for constructing from Python object
548 #
550 to_py_function = None
551 from_py_function = None
552 exception_value = None
553 exception_check = 1
555 def create_to_py_utility_code(self, env):
556 return self.to_py_function is not None
558 def create_from_py_utility_code(self, env):
559 return self.from_py_function is not None
561 def can_coerce_to_pyobject(self, env):
562 return self.create_to_py_utility_code(env)
564 def error_condition(self, result_code):
565 conds = []
566 if self.is_string:
567 conds.append("(!%s)" % result_code)
568 elif self.exception_value is not None:
569 conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
570 if self.exception_check:
571 conds.append("PyErr_Occurred()")
572 if len(conds) > 0:
573 return " && ".join(conds)
574 else:
575 return 0
578 class CVoidType(CType):
579 is_void = 1
581 def __repr__(self):
582 return "<CVoidType>"
584 def declaration_code(self, entity_code,
585 for_display = 0, dll_linkage = None, pyrex = 0):
586 base = public_decl("void", dll_linkage)
587 return self.base_declaration_code(base, entity_code)
589 def is_complete(self):
590 return 0
593 class CNumericType(CType):
594 #
595 # Base class for all C numeric types.
596 #
597 # rank integer Relative size
598 # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
599 #
601 is_numeric = 1
602 default_value = "0"
604 sign_words = ("unsigned ", "", "signed ")
606 def __init__(self, rank, signed = 1):
607 self.rank = rank
608 self.signed = signed
610 def sign_and_name(self):
611 s = self.sign_words[self.signed]
612 n = rank_to_type_name[self.rank]
613 return s + n
615 def __repr__(self):
616 return "<CNumericType %s>" % self.sign_and_name()
618 def declaration_code(self, entity_code,
619 for_display = 0, dll_linkage = None, pyrex = 0):
620 base = public_decl(self.sign_and_name(), dll_linkage)
621 if for_display:
622 base = base.replace('PY_LONG_LONG', 'long long')
623 return self.base_declaration_code(base, entity_code)
626 type_conversion_predeclarations = ""
627 type_conversion_functions = ""
629 c_int_from_py_function = UtilityCode(
630 proto="""
631 static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
632 """,
633 impl="""
634 static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
635 const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
636 const int is_unsigned = neg_one > const_zero;
637 if (sizeof(%(type)s) < sizeof(long)) {
638 long val = __Pyx_PyInt_AsLong(x);
639 if (unlikely(val != (long)(%(type)s)val)) {
640 if (!unlikely(val == -1 && PyErr_Occurred())) {
641 PyErr_SetString(PyExc_OverflowError,
642 (is_unsigned && unlikely(val < 0)) ?
643 "can't convert negative value to %(type)s" :
644 "value too large to convert to %(type)s");
645 }
646 return (%(type)s)-1;
647 }
648 return (%(type)s)val;
649 }
650 return (%(type)s)__Pyx_PyInt_As%(SignWord)sLong(x);
651 }
652 """) #fool emacs: '
654 c_long_from_py_function = UtilityCode(
655 proto="""
656 static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
657 """,
658 impl="""
659 static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
660 const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
661 const int is_unsigned = neg_one > const_zero;
662 #if PY_VERSION_HEX < 0x03000000
663 if (likely(PyInt_Check(x))) {
664 long val = PyInt_AS_LONG(x);
665 if (is_unsigned && unlikely(val < 0)) {
666 PyErr_SetString(PyExc_OverflowError,
667 "can't convert negative value to %(type)s");
668 return (%(type)s)-1;
669 }
670 return (%(type)s)val;
671 } else
672 #endif
673 if (likely(PyLong_Check(x))) {
674 if (is_unsigned) {
675 if (unlikely(Py_SIZE(x) < 0)) {
676 PyErr_SetString(PyExc_OverflowError,
677 "can't convert negative value to %(type)s");
678 return (%(type)s)-1;
679 }
680 return PyLong_AsUnsigned%(TypeName)s(x);
681 } else {
682 return PyLong_As%(TypeName)s(x);
683 }
684 } else {
685 %(type)s val;
686 PyObject *tmp = __Pyx_PyNumber_Int(x);
687 if (!tmp) return (%(type)s)-1;
688 val = __Pyx_PyInt_As%(SignWord)s%(TypeName)s(tmp);
689 Py_DECREF(tmp);
690 return val;
691 }
692 }
693 """)
695 c_typedef_int_from_py_function = UtilityCode(
696 proto="""
697 static CYTHON_INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject *);
698 """,
699 impl="""
700 static CYTHON_INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject* x) {
701 const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
702 const int is_unsigned = neg_one > const_zero;
703 if (sizeof(%(type)s) == sizeof(char)) {
704 if (is_unsigned)
705 return (%(type)s)__Pyx_PyInt_AsUnsignedChar(x);
706 else
707 return (%(type)s)__Pyx_PyInt_AsSignedChar(x);
708 } else if (sizeof(%(type)s) == sizeof(short)) {
709 if (is_unsigned)
710 return (%(type)s)__Pyx_PyInt_AsUnsignedShort(x);
711 else
712 return (%(type)s)__Pyx_PyInt_AsSignedShort(x);
713 } else if (sizeof(%(type)s) == sizeof(int)) {
714 if (is_unsigned)
715 return (%(type)s)__Pyx_PyInt_AsUnsignedInt(x);
716 else
717 return (%(type)s)__Pyx_PyInt_AsSignedInt(x);
718 } else if (sizeof(%(type)s) == sizeof(long)) {
719 if (is_unsigned)
720 return (%(type)s)__Pyx_PyInt_AsUnsignedLong(x);
721 else
722 return (%(type)s)__Pyx_PyInt_AsSignedLong(x);
723 } else if (sizeof(%(type)s) == sizeof(PY_LONG_LONG)) {
724 if (is_unsigned)
725 return (%(type)s)__Pyx_PyInt_AsUnsignedLongLong(x);
726 else
727 return (%(type)s)__Pyx_PyInt_AsSignedLongLong(x);
728 #if 0
729 } else if (sizeof(%(type)s) > sizeof(short) &&
730 sizeof(%(type)s) < sizeof(int)) { /* __int32 ILP64 ? */
731 if (is_unsigned)
732 return (%(type)s)__Pyx_PyInt_AsUnsignedInt(x);
733 else
734 return (%(type)s)__Pyx_PyInt_AsSignedInt(x);
735 #endif
736 }
737 PyErr_SetString(PyExc_TypeError, "%(TypeName)s");
738 return (%(type)s)-1;
739 }
740 """)
742 c_typedef_int_to_py_function = UtilityCode(
743 proto="""
744 static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s);
745 """,
746 impl="""
747 static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s val) {
748 const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
749 const int is_unsigned = neg_one > const_zero;
750 if (sizeof(%(type)s) < sizeof(long)) {
751 return PyInt_FromLong((long)val);
752 } else if (sizeof(%(type)s) == sizeof(long)) {
753 if (is_unsigned)
754 return PyLong_FromUnsignedLong((unsigned long)val);
755 else
756 return PyInt_FromLong((long)val);
757 } else { /* (sizeof(%(type)s) > sizeof(long)) */
758 if (is_unsigned)
759 return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)val);
760 else
761 return PyLong_FromLongLong((PY_LONG_LONG)val);
762 }
763 }
764 """)
766 class CIntType(CNumericType):
768 is_int = 1
769 typedef_flag = 0
770 to_py_function = "PyInt_FromLong"
771 from_py_function = "__Pyx_PyInt_AsInt"
772 exception_value = -1
774 def __init__(self, rank, signed, is_returncode = 0):
775 CNumericType.__init__(self, rank, signed)
776 self.is_returncode = is_returncode
777 if self.from_py_function == "__Pyx_PyInt_AsInt":
778 self.from_py_function = self.get_type_conversion()
780 def get_type_conversion(self):
781 ctype = self.declaration_code('')
782 bits = ctype.split(" ", 1)
783 if len(bits) == 1:
784 sign_word, type_name = "", bits[0]
785 else:
786 sign_word, type_name = bits
787 type_name = type_name.replace("PY_LONG_LONG","long long")
788 SignWord = sign_word.title()
789 TypeName = type_name.title().replace(" ", "")
790 if "Long" in TypeName:
791 utility_code = c_long_from_py_function
792 else:
793 utility_code = c_int_from_py_function
794 utility_code.specialize(self,
795 SignWord=SignWord,
796 TypeName=TypeName)
797 func_name = "__Pyx_PyInt_As%s%s" % (SignWord, TypeName)
798 return func_name
800 def assignable_from_resolved_type(self, src_type):
801 return src_type.is_int or src_type.is_enum or src_type is error_type
804 class CBIntType(CIntType):
806 to_py_function = "__Pyx_PyBool_FromLong"
807 from_py_function = "__Pyx_PyObject_IsTrue"
808 exception_check = 0
810 def __repr__(self):
811 return "<CNumericType bint>"
814 class CAnonEnumType(CIntType):
816 is_enum = 1
818 def sign_and_name(self):
819 return 'int'
822 class CUIntType(CIntType):
824 to_py_function = "PyLong_FromUnsignedLong"
825 exception_value = -1
828 class CLongType(CIntType):
830 to_py_function = "PyInt_FromLong"
833 class CULongType(CUIntType):
835 to_py_function = "PyLong_FromUnsignedLong"
838 class CLongLongType(CIntType):
840 to_py_function = "PyLong_FromLongLong"
843 class CULongLongType(CUIntType):
845 to_py_function = "PyLong_FromUnsignedLongLong"
848 class CPySSizeTType(CIntType):
850 to_py_function = "PyInt_FromSsize_t"
851 from_py_function = "__Pyx_PyIndex_AsSsize_t"
853 def sign_and_name(self):
854 return rank_to_type_name[self.rank]
857 class CSizeTType(CUIntType):
859 to_py_function = "__Pyx_PyInt_FromSize_t"
860 from_py_function = "__Pyx_PyInt_AsSize_t"
862 def sign_and_name(self):
863 return rank_to_type_name[self.rank]
866 class CFloatType(CNumericType):
868 is_float = 1
869 to_py_function = "PyFloat_FromDouble"
870 from_py_function = "__pyx_PyFloat_AsDouble"
872 exception_value = -1
874 def __init__(self, rank, math_h_modifier = ''):
875 CNumericType.__init__(self, rank, 1)
876 self.math_h_modifier = math_h_modifier
878 def assignable_from_resolved_type(self, src_type):
879 return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type
882 class CComplexType(CNumericType):
884 is_complex = 1
885 to_py_function = "__pyx_PyComplex_FromComplex"
886 has_attributes = 1
887 scope = None
889 def __init__(self, real_type):
890 while real_type.is_typedef and not real_type.typedef_is_external:
891 real_type = real_type.typedef_base_type
892 if real_type.is_typedef and real_type.typedef_is_external:
893 # The below is not actually used: Coercions are currently disabled
894 # so that complex types of external types can not be created
895 self.funcsuffix = "_%s" % real_type.specalization_name()
896 elif hasattr(real_type, 'math_h_modifier'):
897 self.funcsuffix = real_type.math_h_modifier
898 else:
899 self.funcsuffix = "_%s" % real_type.specalization_name()
901 self.real_type = real_type
902 CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
903 self.binops = {}
904 self.from_parts = "%s_from_parts" % self.specalization_name()
905 self.default_value = "%s(0, 0)" % self.from_parts
907 def __eq__(self, other):
908 if isinstance(self, CComplexType) and isinstance(other, CComplexType):
909 return self.real_type == other.real_type
910 else:
911 return False
913 def __ne__(self, other):
914 if isinstance(self, CComplexType) and isinstance(other, CComplexType):
915 return self.real_type != other.real_type
916 else:
917 return True
919 def __lt__(self, other):
920 if isinstance(self, CComplexType) and isinstance(other, CComplexType):
921 return self.real_type < other.real_type
922 else:
923 # this is arbitrary, but it makes sure we always have
924 # *some* kind of order
925 return False
927 def __hash__(self):
928 return ~hash(self.real_type)
930 def declaration_code(self, entity_code,
931 for_display = 0, dll_linkage = None, pyrex = 0):
932 if for_display:
933 base = public_decl(self.real_type.sign_and_name() + " complex", dll_linkage)
934 else:
935 base = public_decl(self.sign_and_name(), dll_linkage)
936 return self.base_declaration_code(base, entity_code)
938 def sign_and_name(self):
939 real_type_name = self.real_type.specalization_name()
940 real_type_name = real_type_name.replace('long__double','long_double')
941 return Naming.type_prefix + real_type_name + "_complex"
943 def assignable_from(self, src_type):
944 # Temporary hack/feature disabling, see #441
945 if (not src_type.is_complex and src_type.is_numeric and src_type.is_typedef
946 and src_type.typedef_is_external):
947 return False
948 else:
949 return super(CComplexType, self).assignable_from(src_type)
951 def assignable_from_resolved_type(self, src_type):
952 return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type)
953 or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type)
954 or src_type is error_type)
956 def attributes_known(self):
957 if self.scope is None:
958 import Symtab
959 self.scope = scope = Symtab.CClassScope(
960 '',
961 None,
962 visibility="extern")
963 scope.parent_type = self
964 scope.declare_var("real", self.real_type, None, "real", is_cdef=True)
965 scope.declare_var("imag", self.real_type, None, "imag", is_cdef=True)
966 entry = scope.declare_cfunction(
967 "conjugate",
968 CFuncType(self, [CFuncTypeArg("self", self, None)]),
969 pos=None,
970 defining=1,
971 cname="__Pyx_c_conj%s" % self.funcsuffix)
973 return True
975 def create_declaration_utility_code(self, env):
976 # This must always be run, because a single CComplexType instance can be shared
977 # across multiple compilations (the one created in the module scope)
978 env.use_utility_code(complex_header_utility_code)
979 env.use_utility_code(complex_real_imag_utility_code)
980 for utility_code in (complex_type_utility_code,
981 complex_from_parts_utility_code,
982 complex_arithmetic_utility_code):
983 env.use_utility_code(
984 utility_code.specialize(
985 self,
986 real_type = self.real_type.declaration_code(''),
987 m = self.funcsuffix))
988 return True
990 def create_to_py_utility_code(self, env):
991 env.use_utility_code(complex_real_imag_utility_code)
992 env.use_utility_code(complex_to_py_utility_code)
993 return True
995 def create_from_py_utility_code(self, env):
996 self.real_type.create_from_py_utility_code(env)
998 for utility_code in (complex_from_parts_utility_code,
999 complex_from_py_utility_code):
1000 env.use_utility_code(
1001 utility_code.specialize(
1002 self,
1003 real_type = self.real_type.declaration_code(''),
1004 m = self.funcsuffix))
1005 self.from_py_function = "__Pyx_PyComplex_As_" + self.specalization_name()
1006 return True
1008 def lookup_op(self, nargs, op):
1009 try:
1010 return self.binops[nargs, op]
1011 except KeyError:
1012 pass
1013 try:
1014 op_name = complex_ops[nargs, op]
1015 self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, self.funcsuffix)
1016 return func_name
1017 except KeyError:
1018 return None
1020 def unary_op(self, op):
1021 return self.lookup_op(1, op)
1023 def binary_op(self, op):
1024 return self.lookup_op(2, op)
1026 complex_ops = {
1027 (1, '-'): 'neg',
1028 (1, 'zero'): 'is_zero',
1029 (2, '+'): 'sum',
1030 (2, '-'): 'diff',
1031 (2, '*'): 'prod',
1032 (2, '/'): 'quot',
1033 (2, '=='): 'eq',
1034 }
1036 complex_header_utility_code = UtilityCode(
1037 proto_block='h_code',
1038 proto="""
1039 #if !defined(CYTHON_CCOMPLEX)
1040 #if defined(__cplusplus)
1041 #define CYTHON_CCOMPLEX 1
1042 #elif defined(_Complex_I)
1043 #define CYTHON_CCOMPLEX 1
1044 #else
1045 #define CYTHON_CCOMPLEX 0
1046 #endif
1047 #endif
1049 #if CYTHON_CCOMPLEX
1050 #ifdef __cplusplus
1051 #include <complex>
1052 #else
1053 #include <complex.h>
1054 #endif
1055 #endif
1057 #if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
1058 #undef _Complex_I
1059 #define _Complex_I 1.0fj
1060 #endif
1061 """)
1063 complex_real_imag_utility_code = UtilityCode(
1064 proto="""
1065 #if CYTHON_CCOMPLEX
1066 #ifdef __cplusplus
1067 #define __Pyx_CREAL(z) ((z).real())
1068 #define __Pyx_CIMAG(z) ((z).imag())
1069 #else
1070 #define __Pyx_CREAL(z) (__real__(z))
1071 #define __Pyx_CIMAG(z) (__imag__(z))
1072 #endif
1073 #else
1074 #define __Pyx_CREAL(z) ((z).real)
1075 #define __Pyx_CIMAG(z) ((z).imag)
1076 #endif
1078 #if defined(_WIN32) && defined(__cplusplus) && CYTHON_CCOMPLEX
1079 #define __Pyx_SET_CREAL(z,x) ((z).real(x))
1080 #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
1081 #else
1082 #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
1083 #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
1084 #endif
1085 """)
1087 complex_type_utility_code = UtilityCode(
1088 proto_block='complex_type_declarations',
1089 proto="""
1090 #if CYTHON_CCOMPLEX
1091 #ifdef __cplusplus
1092 typedef ::std::complex< %(real_type)s > %(type_name)s;
1093 #else
1094 typedef %(real_type)s _Complex %(type_name)s;
1095 #endif
1096 #else
1097 typedef struct { %(real_type)s real, imag; } %(type_name)s;
1098 #endif
1099 """)
1101 complex_from_parts_utility_code = UtilityCode(
1102 proto_block='utility_code_proto',
1103 proto="""
1104 static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
1105 """,
1106 impl="""
1107 #if CYTHON_CCOMPLEX
1108 #ifdef __cplusplus
1109 static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1110 return ::std::complex< %(real_type)s >(x, y);
1111 }
1112 #else
1113 static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1114 return x + y*(%(type)s)_Complex_I;
1115 }
1116 #endif
1117 #else
1118 static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1119 %(type)s z;
1120 z.real = x;
1121 z.imag = y;
1122 return z;
1123 }
1124 #endif
1125 """)
1127 complex_to_py_utility_code = UtilityCode(
1128 proto="""
1129 #define __pyx_PyComplex_FromComplex(z) \\
1130 PyComplex_FromDoubles((double)__Pyx_CREAL(z), \\
1131 (double)__Pyx_CIMAG(z))
1132 """)
1134 complex_from_py_utility_code = UtilityCode(
1135 proto="""
1136 static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject*);
1137 """,
1138 impl="""
1139 static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject* o) {
1140 Py_complex cval;
1141 if (PyComplex_CheckExact(o))
1142 cval = ((PyComplexObject *)o)->cval;
1143 else
1144 cval = PyComplex_AsCComplex(o);
1145 return %(type_name)s_from_parts(
1146 (%(real_type)s)cval.real,
1147 (%(real_type)s)cval.imag);
1148 }
1149 """)
1151 complex_arithmetic_utility_code = UtilityCode(
1152 proto="""
1153 #if CYTHON_CCOMPLEX
1154 #define __Pyx_c_eq%(m)s(a, b) ((a)==(b))
1155 #define __Pyx_c_sum%(m)s(a, b) ((a)+(b))
1156 #define __Pyx_c_diff%(m)s(a, b) ((a)-(b))
1157 #define __Pyx_c_prod%(m)s(a, b) ((a)*(b))
1158 #define __Pyx_c_quot%(m)s(a, b) ((a)/(b))
1159 #define __Pyx_c_neg%(m)s(a) (-(a))
1160 #ifdef __cplusplus
1161 #define __Pyx_c_is_zero%(m)s(z) ((z)==(%(real_type)s)0)
1162 #define __Pyx_c_conj%(m)s(z) (::std::conj(z))
1163 /*#define __Pyx_c_abs%(m)s(z) (::std::abs(z))*/
1164 #else
1165 #define __Pyx_c_is_zero%(m)s(z) ((z)==0)
1166 #define __Pyx_c_conj%(m)s(z) (conj%(m)s(z))
1167 /*#define __Pyx_c_abs%(m)s(z) (cabs%(m)s(z))*/
1168 #endif
1169 #else
1170 static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s, %(type)s);
1171 static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s, %(type)s);
1172 static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s, %(type)s);
1173 static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s, %(type)s);
1174 static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s, %(type)s);
1175 static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s);
1176 static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s);
1177 static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s);
1178 /*static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s);*/
1179 #endif
1180 """,
1181 impl="""
1182 #if CYTHON_CCOMPLEX
1183 #else
1184 static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s a, %(type)s b) {
1185 return (a.real == b.real) && (a.imag == b.imag);
1186 }
1187 static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s a, %(type)s b) {
1188 %(type)s z;
1189 z.real = a.real + b.real;
1190 z.imag = a.imag + b.imag;
1191 return z;
1192 }
1193 static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s a, %(type)s b) {
1194 %(type)s z;
1195 z.real = a.real - b.real;
1196 z.imag = a.imag - b.imag;
1197 return z;
1198 }
1199 static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s a, %(type)s b) {
1200 %(type)s z;
1201 z.real = a.real * b.real - a.imag * b.imag;
1202 z.imag = a.real * b.imag + a.imag * b.real;
1203 return z;
1204 }
1205 static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s a, %(type)s b) {
1206 %(type)s z;
1207 %(real_type)s denom = b.real * b.real + b.imag * b.imag;
1208 z.real = (a.real * b.real + a.imag * b.imag) / denom;
1209 z.imag = (a.imag * b.real - a.real * b.imag) / denom;
1210 return z;
1211 }
1212 static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s a) {
1213 %(type)s z;
1214 z.real = -a.real;
1215 z.imag = -a.imag;
1216 return z;
1217 }
1218 static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s a) {
1219 return (a.real == 0) && (a.imag == 0);
1220 }
1221 static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s a) {
1222 %(type)s z;
1223 z.real = a.real;
1224 z.imag = -a.imag;
1225 return z;
1226 }
1227 /*
1228 static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) {
1229 #if HAVE_HYPOT
1230 return hypot%(m)s(z.real, z.imag);
1231 #else
1232 return sqrt%(m)s(z.real*z.real + z.imag*z.imag);
1233 #endif
1234 }
1235 */
1236 #endif
1237 """)
1239 class CArrayType(CType):
1240 # base_type CType Element type
1241 # size integer or None Number of elements
1243 is_array = 1
1245 def __init__(self, base_type, size):
1246 self.base_type = base_type
1247 self.size = size
1248 if base_type is c_char_type:
1249 self.is_string = 1
1251 def __repr__(self):
1252 return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
1254 def same_as_resolved_type(self, other_type):
1255 return ((other_type.is_array and
1256 self.base_type.same_as(other_type.base_type))
1257 or other_type is error_type)
1259 def assignable_from_resolved_type(self, src_type):
1260 # Can't assign to a variable of an array type
1261 return 0
1263 def element_ptr_type(self):
1264 return c_ptr_type(self.base_type)
1266 def declaration_code(self, entity_code,
1267 for_display = 0, dll_linkage = None, pyrex = 0):
1268 if self.size is not None:
1269 dimension_code = self.size
1270 else:
1271 dimension_code = ""
1272 if entity_code.startswith("*"):
1273 entity_code = "(%s)" % entity_code
1274 return self.base_type.declaration_code(
1275 "%s[%s]" % (entity_code, dimension_code),
1276 for_display, dll_linkage, pyrex)
1278 def as_argument_type(self):
1279 return c_ptr_type(self.base_type)
1281 def is_complete(self):
1282 return self.size is not None
1285 class CPtrType(CType):
1286 # base_type CType Referenced type
1288 is_ptr = 1
1289 default_value = "0"
1291 def __init__(self, base_type):
1292 self.base_type = base_type
1294 def __repr__(self):
1295 return "<CPtrType %s>" % repr(self.base_type)
1297 def same_as_resolved_type(self, other_type):
1298 return ((other_type.is_ptr and
1299 self.base_type.same_as(other_type.base_type))
1300 or other_type is error_type)
1302 def declaration_code(self, entity_code,
1303 for_display = 0, dll_linkage = None, pyrex = 0):
1304 #print "CPtrType.declaration_code: pointer to", self.base_type ###
1305 return self.base_type.declaration_code(
1306 "*%s" % entity_code,
1307 for_display, dll_linkage, pyrex)
1309 def assignable_from_resolved_type(self, other_type):
1310 if other_type is error_type:
1311 return 1
1312 if other_type.is_null_ptr:
1313 return 1
1314 if self.base_type.is_cfunction:
1315 if other_type.is_ptr:
1316 other_type = other_type.base_type.resolve()
1317 if other_type.is_cfunction:
1318 return self.base_type.pointer_assignable_from_resolved_type(other_type)
1319 else:
1320 return 0
1321 if (self.base_type.is_cpp_class and other_type.is_ptr
1322 and other_type.base_type.is_cpp_class and other_type.base_type.is_subclass(self.base_type)):
1323 return 1
1324 if other_type.is_array or other_type.is_ptr:
1325 return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
1326 return 0
1328 def specialize(self, values):
1329 base_type = self.base_type.specialize(values)
1330 if base_type == self.base_type:
1331 return self
1332 else:
1333 return CPtrType(base_type)
1336 class CNullPtrType(CPtrType):
1338 is_null_ptr = 1
1341 class CReferenceType(BaseType):
1343 is_reference = 1
1345 def __init__(self, base_type):
1346 self.ref_base_type = base_type
1348 def __repr__(self):
1349 return "<CReferenceType %s>" % repr(self.ref_base_type)
1351 def __str__(self):
1352 return "%s &" % self.ref_base_type
1354 def as_argument_type(self):
1355 return self
1357 def declaration_code(self, entity_code,
1358 for_display = 0, dll_linkage = None, pyrex = 0):
1359 #print "CReferenceType.declaration_code: pointer to", self.base_type ###
1360 return self.ref_base_type.declaration_code(
1361 "&%s" % entity_code,
1362 for_display, dll_linkage, pyrex)
1364 def specialize(self, values):
1365 base_type = self.ref_base_type.specialize(values)
1366 if base_type == self.ref_base_type:
1367 return self
1368 else:
1369 return CReferenceType(base_type)
1371 def __getattr__(self, name):
1372 return getattr(self.ref_base_type, name)
1375 class CFuncType(CType):
1376 # return_type CType
1377 # args [CFuncTypeArg]
1378 # has_varargs boolean
1379 # exception_value string
1380 # exception_check boolean True if PyErr_Occurred check needed
1381 # calling_convention string Function calling convention
1382 # nogil boolean Can be called without gil
1383 # with_gil boolean Acquire gil around function body
1384 # templates [string] or None
1386 is_cfunction = 1
1387 original_sig = None
1389 def __init__(self, return_type, args, has_varargs = 0,
1390 exception_value = None, exception_check = 0, calling_convention = "",
1391 nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0,
1392 templates = None):
1393 self.return_type = return_type
1394 self.args = args
1395 self.has_varargs = has_varargs
1396 self.optional_arg_count = optional_arg_count
1397 self.exception_value = exception_value
1398 self.exception_check = exception_check
1399 self.calling_convention = calling_convention
1400 self.nogil = nogil
1401 self.with_gil = with_gil
1402 self.is_overridable = is_overridable
1403 self.templates = templates
1405 def __repr__(self):
1406 arg_reprs = map(repr, self.args)
1407 if self.has_varargs:
1408 arg_reprs.append("...")
1409 if self.exception_value:
1410 except_clause = " %r" % self.exception_value
1411 else:
1412 except_clause = ""
1413 if self.exception_check:
1414 except_clause += "?"
1415 return "<CFuncType %s %s[%s]%s>" % (
1416 repr(self.return_type),
1417 self.calling_convention_prefix(),
1418 ",".join(arg_reprs),
1419 except_clause)
1421 def calling_convention_prefix(self):
1422 cc = self.calling_convention
1423 if cc:
1424 return cc + " "
1425 else:
1426 return ""
1428 def same_c_signature_as(self, other_type, as_cmethod = 0):
1429 return self.same_c_signature_as_resolved_type(
1430 other_type.resolve(), as_cmethod)
1432 def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
1433 #print "CFuncType.same_c_signature_as_resolved_type:", \
1434 # self, other_type, "as_cmethod =", as_cmethod ###
1435 if other_type is error_type:
1436 return 1
1437 if not other_type.is_cfunction:
1438 return 0
1439 if self.is_overridable != other_type.is_overridable:
1440 return 0
1441 nargs = len(self.args)
1442 if nargs != len(other_type.args):
1443 return 0
1444 # When comparing C method signatures, the first argument
1445 # is exempt from compatibility checking (the proper check
1446 # is performed elsewhere).
1447 for i in range(as_cmethod, nargs):
1448 if not self.args[i].type.same_as(
1449 other_type.args[i].type):
1450 return 0
1451 if self.has_varargs != other_type.has_varargs:
1452 return 0
1453 if self.optional_arg_count != other_type.optional_arg_count:
1454 return 0
1455 if not self.return_type.same_as(other_type.return_type):
1456 return 0
1457 if not self.same_calling_convention_as(other_type):
1458 return 0
1459 return 1
1461 def compatible_signature_with(self, other_type, as_cmethod = 0):
1462 return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
1464 def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
1465 #print "CFuncType.same_c_signature_as_resolved_type:", \
1466 # self, other_type, "as_cmethod =", as_cmethod ###
1467 if other_type is error_type:
1468 return 1
1469 if not other_type.is_cfunction:
1470 return 0
1471 if not self.is_overridable and other_type.is_overridable:
1472 return 0
1473 nargs = len(self.args)
1474 if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
1475 return 0
1476 if self.optional_arg_count < other_type.optional_arg_count:
1477 return 0
1478 # When comparing C method signatures, the first argument
1479 # is exempt from compatibility checking (the proper check
1480 # is performed elsewhere).
1481 for i in range(as_cmethod, len(other_type.args)):
1482 if not self.args[i].type.same_as(
1483 other_type.args[i].type):
1484 return 0
1485 if self.has_varargs != other_type.has_varargs:
1486 return 0
1487 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1488 return 0
1489 if not self.same_calling_convention_as(other_type):
1490 return 0
1491 if self.nogil != other_type.nogil:
1492 return 0
1493 self.original_sig = other_type.original_sig or other_type
1494 if as_cmethod:
1495 self.args[0] = other_type.args[0]
1496 return 1
1499 def narrower_c_signature_than(self, other_type, as_cmethod = 0):
1500 return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
1502 def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
1503 if other_type is error_type:
1504 return 1
1505 if not other_type.is_cfunction:
1506 return 0
1507 nargs = len(self.args)
1508 if nargs != len(other_type.args):
1509 return 0
1510 for i in range(as_cmethod, nargs):
1511 if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
1512 return 0
1513 else:
1514 self.args[i].needs_type_test = other_type.args[i].needs_type_test \
1515 or not self.args[i].type.same_as(other_type.args[i].type)
1516 if self.has_varargs != other_type.has_varargs:
1517 return 0
1518 if self.optional_arg_count != other_type.optional_arg_count:
1519 return 0
1520 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1521 return 0
1522 return 1
1524 def same_calling_convention_as(self, other):
1525 ## XXX Under discussion ...
1526 ## callspec_words = ("__stdcall", "__cdecl", "__fastcall")
1527 ## cs1 = self.calling_convention
1528 ## cs2 = other.calling_convention
1529 ## if (cs1 in callspec_words or
1530 ## cs2 in callspec_words):
1531 ## return cs1 == cs2
1532 ## else:
1533 ## return True
1534 sc1 = self.calling_convention == '__stdcall'
1535 sc2 = other.calling_convention == '__stdcall'
1536 return sc1 == sc2
1538 def same_exception_signature_as(self, other_type):
1539 return self.same_exception_signature_as_resolved_type(
1540 other_type.resolve())
1542 def same_exception_signature_as_resolved_type(self, other_type):
1543 return self.exception_value == other_type.exception_value \
1544 and self.exception_check == other_type.exception_check
1546 def same_as_resolved_type(self, other_type, as_cmethod = 0):
1547 return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
1548 and self.same_exception_signature_as_resolved_type(other_type) \
1549 and self.nogil == other_type.nogil
1551 def pointer_assignable_from_resolved_type(self, other_type):
1552 return self.same_c_signature_as_resolved_type(other_type) \
1553 and self.same_exception_signature_as_resolved_type(other_type) \
1554 and not (self.nogil and not other_type.nogil)
1556 def declaration_code(self, entity_code,
1557 for_display = 0, dll_linkage = None, pyrex = 0,
1558 with_calling_convention = 1):
1559 arg_decl_list = []
1560 for arg in self.args[:len(self.args)-self.optional_arg_count]:
1561 arg_decl_list.append(
1562 arg.type.declaration_code("", for_display, pyrex = pyrex))
1563 if self.is_overridable:
1564 arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
1565 if self.optional_arg_count:
1566 arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
1567 if self.has_varargs:
1568 arg_decl_list.append("...")
1569 arg_decl_code = ", ".join(arg_decl_list)
1570 if not arg_decl_code and not pyrex:
1571 arg_decl_code = "void"
1572 trailer = ""
1573 if (pyrex or for_display) and not self.return_type.is_pyobject:
1574 if self.exception_value and self.exception_check:
1575 trailer = " except? %s" % self.exception_value
1576 elif self.exception_value:
1577 trailer = " except %s" % self.exception_value
1578 elif self.exception_check == '+':
1579 trailer = " except +"
1580 else:
1581 " except *" # ignored
1582 if self.nogil:
1583 trailer += " nogil"
1584 if not with_calling_convention:
1585 cc = ''
1586 else:
1587 cc = self.calling_convention_prefix()
1588 if (not entity_code and cc) or entity_code.startswith("*"):
1589 entity_code = "(%s%s)" % (cc, entity_code)
1590 cc = ""
1591 return self.return_type.declaration_code(
1592 "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
1593 for_display, dll_linkage, pyrex)
1595 def function_header_code(self, func_name, arg_code):
1596 return "%s%s(%s)" % (self.calling_convention_prefix(),
1597 func_name, arg_code)
1599 def signature_string(self):
1600 s = self.declaration_code("")
1601 return s
1603 def signature_cast_string(self):
1604 s = self.declaration_code("(*)", with_calling_convention=False)
1605 return '(%s)' % s
1607 def specialize(self, values):
1608 if self.templates is None:
1609 new_templates = None
1610 else:
1611 new_templates = [v.specialize(values) for v in self.templates]
1612 return CFuncType(self.return_type.specialize(values),
1613 [arg.specialize(values) for arg in self.args],
1614 has_varargs = 0,
1615 exception_value = self.exception_value,
1616 exception_check = self.exception_check,
1617 calling_convention = self.calling_convention,
1618 nogil = self.nogil,
1619 with_gil = self.with_gil,
1620 is_overridable = self.is_overridable,
1621 optional_arg_count = self.optional_arg_count,
1622 templates = new_templates)
1624 def opt_arg_cname(self, arg_name):
1625 return self.op_arg_struct.base_type.scope.lookup(arg_name).cname
1628 class CFuncTypeArg(object):
1629 # name string
1630 # cname string
1631 # type PyrexType
1632 # pos source file position
1634 def __init__(self, name, type, pos, cname=None):
1635 self.name = name
1636 if cname is not None:
1637 self.cname = cname
1638 else:
1639 self.cname = Naming.var_prefix + name
1640 self.type = type
1641 self.pos = pos
1642 self.not_none = False
1643 self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
1645 def __repr__(self):
1646 return "%s:%s" % (self.name, repr(self.type))
1648 def declaration_code(self, for_display = 0):
1649 return self.type.declaration_code(self.cname, for_display)
1651 def specialize(self, values):
1652 return CFuncTypeArg(self.name, self.type.specialize(values), self.pos, self.cname)
1654 class StructUtilityCode(object):
1655 def __init__(self, type, forward_decl):
1656 self.type = type
1657 self.header = "static PyObject* %s(%s)" % (type.to_py_function, type.declaration_code('s'))
1658 self.forward_decl = forward_decl
1660 def __eq__(self, other):
1661 return isinstance(other, StructUtilityCode) and self.header == other.header
1662 def __hash__(self):
1663 return hash(self.header)
1665 def put_code(self, output):
1666 code = output['utility_code_def']
1667 proto = output['utility_code_proto']
1669 code.putln("%s {" % self.header)
1670 code.putln("PyObject* res;")
1671 code.putln("PyObject* member;")
1672 code.putln("res = PyDict_New(); if (res == NULL) return NULL;")
1673 for member in self.type.scope.var_entries:
1674 nameconst_cname = code.get_py_string_const(member.name, identifier=True)
1675 code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % (
1676 member.type.to_py_function, member.cname))
1677 code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % nameconst_cname)
1678 code.putln("Py_DECREF(member);")
1679 code.putln("return res;")
1680 code.putln("bad:")
1681 code.putln("Py_XDECREF(member);")
1682 code.putln("Py_DECREF(res);")
1683 code.putln("return NULL;")
1684 code.putln("}")
1686 # This is a bit of a hack, we need a forward declaration
1687 # due to the way things are ordered in the module...
1688 if self.forward_decl:
1689 proto.putln(self.type.declaration_code('') + ';')
1690 proto.putln(self.header + ";")
1693 class CStructOrUnionType(CType):
1694 # name string
1695 # cname string
1696 # kind string "struct" or "union"
1697 # scope StructOrUnionScope, or None if incomplete
1698 # typedef_flag boolean
1699 # packed boolean
1701 # entry Entry
1703 is_struct_or_union = 1
1704 has_attributes = 1
1706 def __init__(self, name, kind, scope, typedef_flag, cname, packed=False):
1707 self.name = name
1708 self.cname = cname
1709 self.kind = kind
1710 self.scope = scope
1711 self.typedef_flag = typedef_flag
1712 self.is_struct = kind == 'struct'
1713 if self.is_struct:
1714 self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
1715 self.exception_check = True
1716 self._convert_code = None
1717 self.packed = packed
1719 def create_to_py_utility_code(self, env):
1720 if env.outer_scope is None:
1721 return False
1723 if self._convert_code is False: return # tri-state-ish
1725 if self._convert_code is None:
1726 for member in self.scope.var_entries:
1727 if not member.type.to_py_function or not member.type.create_to_py_utility_code(env):
1728 self.to_py_function = None
1729 self._convert_code = False
1730 return False
1731 forward_decl = (self.entry.visibility != 'extern')
1732 self._convert_code = StructUtilityCode(self, forward_decl)
1734 env.use_utility_code(self._convert_code)
1735 return True
1737 def __repr__(self):
1738 return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
1739 ("", " typedef")[self.typedef_flag])
1741 def declaration_code(self, entity_code,
1742 for_display = 0, dll_linkage = None, pyrex = 0):
1743 if pyrex:
1744 return self.base_declaration_code(self.name, entity_code)
1745 else:
1746 if for_display:
1747 base = self.name
1748 elif self.typedef_flag:
1749 base = self.cname
1750 else:
1751 base = "%s %s" % (self.kind, self.cname)
1752 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1754 def __eq__(self, other):
1755 try:
1756 return (isinstance(other, CStructOrUnionType) and
1757 self.name == other.name)
1758 except AttributeError:
1759 return False
1761 def __lt__(self, other):
1762 try:
1763 return self.name < other.name
1764 except AttributeError:
1765 # this is arbitrary, but it makes sure we always have
1766 # *some* kind of order
1767 return False
1769 def __hash__(self):
1770 return hash(self.cname) ^ hash(self.kind)
1772 def is_complete(self):
1773 return self.scope is not None
1775 def attributes_known(self):
1776 return self.is_complete()
1778 def can_be_complex(self):
1779 # Does the struct consist of exactly two identical floats?
1780 fields = self.scope.var_entries
1781 if len(fields) != 2: return False
1782 a, b = fields
1783 return (a.type.is_float and b.type.is_float and
1784 a.type.declaration_code("") ==
1785 b.type.declaration_code(""))
1787 def struct_nesting_depth(self):
1788 child_depths = [x.type.struct_nesting_depth()
1789 for x in self.scope.var_entries]
1790 return max(child_depths) + 1
1792 class CppClassType(CType):
1793 # name string
1794 # cname string
1795 # scope CppClassScope
1796 # templates [string] or None
1798 is_cpp_class = 1
1799 has_attributes = 1
1800 exception_check = True
1801 namespace = None
1803 def __init__(self, name, scope, cname, base_classes, templates = None, template_type = None):
1804 self.name = name
1805 self.cname = cname
1806 self.scope = scope
1807 self.base_classes = base_classes
1808 self.operators = []
1809 self.templates = templates
1810 self.template_type = template_type
1811 self.specializations = {}
1813 def specialize_here(self, pos, template_values = None):
1814 if self.templates is None:
1815 error(pos, "'%s' type is not a template" % self);
1816 return PyrexTypes.error_type
1817 if len(self.templates) != len(template_values):
1818 error(pos, "%s templated type receives %d arguments, got %d" %
1819 (self.name, len(self.templates), len(template_values)))
1820 return error_type
1821 return self.specialize(dict(zip(self.templates, template_values)))
1823 def specialize(self, values):
1824 if not self.templates and not self.namespace:
1825 return self
1826 if self.templates is None:
1827 self.templates = []
1828 key = tuple(values.items())
1829 if key in self.specializations:
1830 return self.specializations[key]
1831 template_values = [t.specialize(values) for t in self.templates]
1832 specialized = self.specializations[key] = \
1833 CppClassType(self.name, None, self.cname, [], template_values, template_type=self)
1834 # Need to do these *after* self.specializations[key] is set
1835 # to avoid infinite recursion on circular references.
1836 specialized.base_classes = [b.specialize(values) for b in self.base_classes]
1837 specialized.scope = self.scope.specialize(values)
1838 if self.namespace is not None:
1839 specialized.namespace = self.namespace.specialize(values)
1840 return specialized
1842 def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0):
1843 if self.templates:
1844 template_strings = [param.declaration_code('', for_display, pyrex) for param in self.templates]
1845 templates = "<" + ",".join(template_strings) + ">"
1846 else:
1847 templates = ""
1848 if for_display or pyrex:
1849 name = self.name
1850 else:
1851 if self.namespace is not None:
1852 name = "%s::%s" % (self.namespace.declaration_code(''), self.cname)
1853 else:
1854 name = self.cname
1855 return "%s%s %s" % (name, templates, entity_code)
1857 def is_subclass(self, other_type):
1858 # TODO(danilo): Handle templates.
1859 if self.same_as_resolved_type(other_type):
1860 return 1
1861 for base_class in self.base_classes:
1862 if base_class.is_subclass(other_type):
1863 return 1
1864 return 0
1866 def same_as_resolved_type(self, other_type):
1867 if other_type.is_cpp_class:
1868 if self == other_type:
1869 return 1
1870 elif self.template_type and self.template_type == other_type.template_type:
1871 if self.templates == other_type.templates:
1872 return 1
1873 for t1, t2 in zip(self.templates, other_type.templates):
1874 if not t1.same_as_resolved_type(t2):
1875 return 0
1876 return 1
1877 return 0
1879 def assignable_from_resolved_type(self, other_type):
1880 # TODO: handle operator=(...) here?
1881 if other_type is error_type:
1882 return True
1883 return other_type.is_cpp_class and other_type.is_subclass(self)
1885 def attributes_known(self):
1886 return self.scope is not None
1889 class TemplatePlaceholderType(CType):
1891 def __init__(self, name):
1892 self.name = name
1894 def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0):
1895 if entity_code:
1896 return self.name + " " + entity_code
1897 else:
1898 return self.name
1900 def specialize(self, values):
1901 if self in values:
1902 return values[self]
1903 else:
1904 return self
1906 def same_as_resolved_type(self, other_type):
1907 if isinstance(other_type, TemplatePlaceholderType):
1908 return self.name == other_type.name
1909 else:
1910 return 0
1912 def __hash__(self):
1913 return hash(self.name)
1915 def __cmp__(self, other):
1916 if isinstance(other, TemplatePlaceholderType):
1917 return cmp(self.name, other.name)
1918 else:
1919 return cmp(type(self), type(other))
1921 class CEnumType(CType):
1922 # name string
1923 # cname string or None
1924 # typedef_flag boolean
1926 is_enum = 1
1927 signed = 1
1928 rank = -1 # Ranks below any integer type
1929 to_py_function = "PyInt_FromLong"
1930 from_py_function = "PyInt_AsLong"
1932 def __init__(self, name, cname, typedef_flag):
1933 self.name = name
1934 self.cname = cname
1935 self.values = []
1936 self.typedef_flag = typedef_flag
1938 def __str__(self):
1939 return self.name
1941 def __repr__(self):
1942 return "<CEnumType %s %s%s>" % (self.name, self.cname,
1943 ("", " typedef")[self.typedef_flag])
1945 def declaration_code(self, entity_code,
1946 for_display = 0, dll_linkage = None, pyrex = 0):
1947 if pyrex:
1948 return self.base_declaration_code(self.cname, entity_code)
1949 else:
1950 if self.typedef_flag:
1951 base = self.cname
1952 else:
1953 base = "enum %s" % self.cname
1954 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1957 class CStringType(object):
1958 # Mixin class for C string types.
1960 is_string = 1
1961 is_unicode = 0
1963 to_py_function = "__Pyx_PyBytes_FromString"
1964 from_py_function = "__Pyx_PyBytes_AsString"
1965 exception_value = "NULL"
1967 def literal_code(self, value):
1968 assert isinstance(value, str)
1969 return '"%s"' % StringEncoding.escape_byte_string(value)
1972 class CUTF8CharArrayType(CStringType, CArrayType):
1973 # C 'char []' type.
1975 is_unicode = 1
1977 to_py_function = "PyUnicode_DecodeUTF8"
1978 exception_value = "NULL"
1980 def __init__(self, size):
1981 CArrayType.__init__(self, c_char_type, size)
1983 class CCharArrayType(CStringType, CArrayType):
1984 # C 'char []' type.
1986 def __init__(self, size):
1987 CArrayType.__init__(self, c_char_type, size)
1990 class CCharPtrType(CStringType, CPtrType):
1991 # C 'char *' type.
1993 def __init__(self):
1994 CPtrType.__init__(self, c_char_type)
1997 class CUCharPtrType(CStringType, CPtrType):
1998 # C 'unsigned char *' type.
2000 to_py_function = "__Pyx_PyBytes_FromUString"
2001 from_py_function = "__Pyx_PyBytes_AsUString"
2003 def __init__(self):
2004 CPtrType.__init__(self, c_uchar_type)
2007 class UnspecifiedType(PyrexType):
2008 # Used as a placeholder until the type can be determined.
2010 is_unspecified = 1
2012 def declaration_code(self, entity_code,
2013 for_display = 0, dll_linkage = None, pyrex = 0):
2014 return "<unspecified>"
2016 def same_as_resolved_type(self, other_type):
2017 return False
2020 class ErrorType(PyrexType):
2021 # Used to prevent propagation of error messages.
2023 is_error = 1
2024 exception_value = "0"
2025 exception_check = 0
2026 to_py_function = "dummy"
2027 from_py_function = "dummy"
2029 def create_to_py_utility_code(self, env):
2030 return True
2032 def create_from_py_utility_code(self, env):
2033 return True
2035 def declaration_code(self, entity_code,
2036 for_display = 0, dll_linkage = None, pyrex = 0):
2037 return "<error>"
2039 def same_as_resolved_type(self, other_type):
2040 return 1
2042 def error_condition(self, result_code):
2043 return "dummy"
2046 rank_to_type_name = (
2047 "char", # 0
2048 "short", # 1
2049 "int", # 2
2050 "long", # 3
2051 "Py_ssize_t", # 4
2052 "size_t", # 5
2053 "PY_LONG_LONG", # 6
2054 "float", # 7
2055 "double", # 8
2056 "long double", # 9
2057 )
2059 py_object_type = PyObjectType()
2061 c_void_type = CVoidType()
2062 c_void_ptr_type = CPtrType(c_void_type)
2063 c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
2065 c_uchar_type = CIntType(0, 0)
2066 c_ushort_type = CIntType(1, 0)
2067 c_uint_type = CUIntType(2, 0)
2068 c_ulong_type = CULongType(3, 0)
2069 c_ulonglong_type = CULongLongType(6, 0)
2071 c_char_type = CIntType(0, 1)
2072 c_short_type = CIntType(1, 1)
2073 c_int_type = CIntType(2, 1)
2074 c_long_type = CLongType(3, 1)
2075 c_longlong_type = CLongLongType(6, 1)
2076 c_bint_type = CBIntType(2, 1)
2078 c_schar_type = CIntType(0, 2)
2079 c_sshort_type = CIntType(1, 2)
2080 c_sint_type = CIntType(2, 2)
2081 c_slong_type = CLongType(3, 2)
2082 c_slonglong_type = CLongLongType(6, 2)
2084 c_py_ssize_t_type = CPySSizeTType(4, 2)
2085 c_size_t_type = CSizeTType(5, 0)
2087 c_float_type = CFloatType(7, math_h_modifier='f')
2088 c_double_type = CFloatType(8)
2089 c_longdouble_type = CFloatType(9, math_h_modifier='l')
2091 c_double_complex_type = CComplexType(c_double_type)
2093 c_null_ptr_type = CNullPtrType(c_void_type)
2094 c_char_array_type = CCharArrayType(None)
2095 c_char_ptr_type = CCharPtrType()
2096 c_uchar_ptr_type = CUCharPtrType()
2097 c_utf8_char_array_type = CUTF8CharArrayType(None)
2098 c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
2099 c_int_ptr_type = CPtrType(c_int_type)
2100 c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
2101 c_size_t_ptr_type = CPtrType(c_size_t_type)
2103 c_returncode_type = CIntType(2, 1, is_returncode = 1)
2105 c_anon_enum_type = CAnonEnumType(-1, 1)
2107 # the Py_buffer type is defined in Builtin.py
2108 c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
2109 c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
2111 error_type = ErrorType()
2112 unspecified_type = UnspecifiedType()
2114 sign_and_rank_to_type = {
2115 #(signed, rank)
2116 (0, 0): c_uchar_type,
2117 (0, 1): c_ushort_type,
2118 (0, 2): c_uint_type,
2119 (0, 3): c_ulong_type,
2120 (0, 6): c_ulonglong_type,
2122 (1, 0): c_char_type,
2123 (1, 1): c_short_type,
2124 (1, 2): c_int_type,
2125 (1, 3): c_long_type,
2126 (1, 6): c_longlong_type,
2128 (2, 0): c_schar_type,
2129 (2, 1): c_sshort_type,
2130 (2, 2): c_sint_type,
2131 (2, 3): c_slong_type,
2132 (2, 6): c_slonglong_type,
2134 (0, 4): c_py_ssize_t_type,
2135 (1, 4): c_py_ssize_t_type,
2136 (2, 4): c_py_ssize_t_type,
2137 (0, 5): c_size_t_type,
2138 (1, 5): c_size_t_type,
2139 (2, 5): c_size_t_type,
2141 (1, 7): c_float_type,
2142 (1, 8): c_double_type,
2143 (1, 9): c_longdouble_type,
2144 # In case we're mixing unsigned ints and floats...
2145 (0, 7): c_float_type,
2146 (0, 8): c_double_type,
2147 (0, 9): c_longdouble_type,
2148 }
2150 modifiers_and_name_to_type = {
2151 #(signed, longness, name)
2152 (0, 0, "char"): c_uchar_type,
2153 (0, -1, "int"): c_ushort_type,
2154 (0, 0, "int"): c_uint_type,
2155 (0, 1, "int"): c_ulong_type,
2156 (0, 2, "int"): c_ulonglong_type,
2157 (1, 0, "void"): c_void_type,
2158 (1, 0, "char"): c_char_type,
2159 (1, -1, "int"): c_short_type,
2160 (1, 0, "int"): c_int_type,
2161 (1, 1, "int"): c_long_type,
2162 (1, 2, "int"): c_longlong_type,
2163 (1, 0, "float"): c_float_type,
2164 (1, 0, "double"): c_double_type,
2165 (1, 1, "double"): c_longdouble_type,
2166 (1, 0, "object"): py_object_type,
2167 (1, 0, "bint"): c_bint_type,
2168 (2, 0, "char"): c_schar_type,
2169 (2, -1, "int"): c_sshort_type,
2170 (2, 0, "int"): c_sint_type,
2171 (2, 1, "int"): c_slong_type,
2172 (2, 2, "int"): c_slonglong_type,
2174 (2, 0, "Py_ssize_t"): c_py_ssize_t_type,
2175 (0, 0, "size_t") : c_size_t_type,
2177 (1, 0, "long"): c_long_type,
2178 (1, 0, "short"): c_short_type,
2179 (1, 0, "longlong"): c_longlong_type,
2180 (1, 0, "bint"): c_bint_type,
2181 }
2183 def is_promotion0(src_type, dst_type):
2184 if src_type.is_numeric and dst_type.is_numeric:
2185 if src_type.is_int and dst_type.is_int:
2186 if src_type.is_enum:
2187 return True
2188 elif src_type.signed:
2189 return dst_type.signed and src_type.rank <= dst_type.rank
2190 elif dst_type.signed: # and not src_type.signed
2191 src_type.rank < dst_type.rank
2192 else:
2193 return src_type.rank <= dst_type.rank
2194 elif src_type.is_float and dst_type.is_float:
2195 return src_type.rank <= dst_type.rank
2196 else:
2197 return False
2198 else:
2199 return False
2201 def is_promotion(src_type, dst_type):
2202 # It's hard to find a hard definition of promotion, but empirical
2203 # evidence suggests that the below is all that's allowed.
2204 if src_type.is_numeric:
2205 if dst_type.same_as(c_int_type):
2206 return src_type.is_enum or (src_type.is_int and (not src_type.signed) + src_type.rank < dst_type.rank)
2207 elif dst_type.same_as(c_double_type):
2208 return src_type.is_float and src_type.rank <= dst_type.rank
2209 return False
2211 def best_match(args, functions, pos=None):
2212 """
2213 Given a list args of arguments and a list of functions, choose one
2214 to call which seems to be the "best" fit for this list of arguments.
2215 This function is used, e.g., when deciding which overloaded method
2216 to dispatch for C++ classes.
2218 We first eliminate functions based on arity, and if only one
2219 function has the correct arity, we return it. Otherwise, we weight
2220 functions based on how much work must be done to convert the
2221 arguments, with the following priorities:
2222 * identical types or pointers to identical types
2223 * promotions
2224 * non-Python types
2225 That is, we prefer functions where no arguments need converted,
2226 and failing that, functions where only promotions are required, and
2227 so on.
2229 If no function is deemed a good fit, or if two or more functions have
2230 the same weight, we return None (as there is no best match). If pos
2231 is not None, we also generate an error.
2232 """
2233 # TODO: args should be a list of types, not a list of Nodes.
2234 actual_nargs = len(args)
2236 candidates = []
2237 errors = []
2238 for func in functions:
2239 error_mesg = ""
2240 func_type = func.type
2241 if func_type.is_ptr:
2242 func_type = func_type.base_type
2243 # Check function type
2244 if not func_type.is_cfunction:
2245 if not func_type.is_error and pos is not None:
2246 error_mesg = "Calling non-function type '%s'" % func_type
2247 errors.append((func, error_mesg))
2248 continue
2249 # Check no. of args
2250 max_nargs = len(func_type.args)
2251 min_nargs = max_nargs - func_type.optional_arg_count
2252 if actual_nargs < min_nargs or \
2253 (not func_type.has_varargs and actual_nargs > max_nargs):
2254 if max_nargs == min_nargs and not func_type.has_varargs:
2255 expectation = max_nargs
2256 elif actual_nargs < min_nargs:
2257 expectation = "at least %s" % min_nargs
2258 else:
2259 expectation = "at most %s" % max_nargs
2260 error_mesg = "Call with wrong number of arguments (expected %s, got %s)" \
2261 % (expectation, actual_nargs)
2262 errors.append((func, error_mesg))
2263 continue
2264 candidates.append((func, func_type))
2266 # Optimize the most common case of no overloading...
2267 if len(candidates) == 1:
2268 return candidates[0][0]
2269 elif len(candidates) == 0:
2270 if len(errors) == 1 and pos is not None:
2271 error(pos, errors[0][1])
2272 return None
2274 possibilities = []
2275 bad_types = []
2276 for func, func_type in candidates:
2277 score = [0,0,0]
2278 for i in range(min(len(args), len(func_type.args))):
2279 src_type = args[i].type
2280 dst_type = func_type.args[i].type
2281 if dst_type.assignable_from(src_type):
2282 if src_type == dst_type or dst_type.same_as(src_type):
2283 pass # score 0
2284 elif is_promotion(src_type, dst_type):
2285 score[2] += 1
2286 elif not src_type.is_pyobject:
2287 score[1] += 1
2288 else:
2289 score[0] += 1
2290 else:
2291 error_mesg = "Invalid conversion from '%s' to '%s'"%(src_type,
2292 dst_type)
2293 bad_types.append((func, error_mesg))
2294 break
2295 else:
2296 possibilities.append((score, func)) # so we can sort it
2297 if possibilities:
2298 possibilities.sort()
2299 if len(possibilities) > 1 and possibilities[0][0] == possibilities[1][0]:
2300 if pos is not None:
2301 error(pos, "ambiguous overloaded method")
2302 return None
2303 return possibilities[0][1]
2304 if pos is not None:
2305 if len(bad_types) == 1:
2306 error(pos, bad_types[0][1])
2307 else:
2308 error(pos, "no suitable method found")
2309 return None
2312 def widest_numeric_type(type1, type2):
2313 # Given two numeric types, return the narrowest type
2314 # encompassing both of them.
2315 if type1 == type2:
2316 return type1
2317 if type1.is_complex:
2318 if type2.is_complex:
2319 return CComplexType(widest_numeric_type(type1.real_type, type2.real_type))
2320 else:
2321 return CComplexType(widest_numeric_type(type1.real_type, type2))
2322 elif type2.is_complex:
2323 return CComplexType(widest_numeric_type(type1, type2.real_type))
2324 if type1.is_enum and type2.is_enum:
2325 return c_int_type
2326 elif type1 is type2:
2327 return type1
2328 elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
2329 if type2.rank > type1.rank:
2330 return type2
2331 else:
2332 return type1
2333 else:
2334 return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
2336 def spanning_type(type1, type2):
2337 # Return a type assignable from both type1 and type2.
2338 if type1 is py_object_type or type2 is py_object_type:
2339 return py_object_type
2340 elif type1 == type2:
2341 return type1
2342 elif type1.is_numeric and type2.is_numeric:
2343 return widest_numeric_type(type1, type2)
2344 elif type1.is_builtin_type and type1.name == 'float' and type2.is_numeric:
2345 return widest_numeric_type(c_double_type, type2)
2346 elif type2.is_builtin_type and type2.name == 'float' and type1.is_numeric:
2347 return widest_numeric_type(type1, c_double_type)
2348 elif type1.is_pyobject ^ type2.is_pyobject:
2349 return py_object_type
2350 elif type1.is_extension_type and type2.is_extension_type:
2351 if type1.typeobj_is_imported() or type2.typeobj_is_imported():
2352 return py_object_type
2353 while True:
2354 if type1.subtype_of(type2):
2355 return type2
2356 elif type2.subtype_of(type1):
2357 return type1
2358 type1, type2 = type1.base_type, type2.base_type
2359 if type1 is None or type2 is None:
2360 return py_object_type
2361 elif type1.assignable_from(type2):
2362 if type1.is_extension_type and type1.typeobj_is_imported():
2363 # external types are unsafe, so we use PyObject instead
2364 return py_object_type
2365 return type1
2366 elif type2.assignable_from(type1):
2367 if type2.is_extension_type and type2.typeobj_is_imported():
2368 # external types are unsafe, so we use PyObject instead
2369 return py_object_type
2370 return type2
2371 else:
2372 return py_object_type
2374 def simple_c_type(signed, longness, name):
2375 # Find type descriptor for simple type given name and modifiers.
2376 # Returns None if arguments don't make sense.
2377 return modifiers_and_name_to_type.get((signed, longness, name))
2379 def parse_basic_type(name):
2380 base = None
2381 if name.startswith('p_'):
2382 base = parse_basic_type(name[2:])
2383 elif name.startswith('p'):
2384 base = parse_basic_type(name[1:])
2385 elif name.endswith('*'):
2386 base = parse_basic_type(name[:-1])
2387 if base:
2388 return CPtrType(base)
2389 elif name.startswith('u'):
2390 return simple_c_type(0, 0, name[1:])
2391 else:
2392 return simple_c_type(1, 0, name)
2394 def c_array_type(base_type, size):
2395 # Construct a C array type.
2396 if base_type is c_char_type:
2397 return CCharArrayType(size)
2398 elif base_type is error_type:
2399 return error_type
2400 else:
2401 return CArrayType(base_type, size)
2403 def c_ptr_type(base_type):
2404 # Construct a C pointer type.
2405 if base_type is c_char_type:
2406 return c_char_ptr_type
2407 elif base_type is c_uchar_type:
2408 return c_uchar_ptr_type
2409 elif base_type is error_type:
2410 return error_type
2411 else:
2412 return CPtrType(base_type)
2414 def c_ref_type(base_type):
2415 # Construct a C reference type
2416 if base_type is error_type:
2417 return error_type
2418 else:
2419 return CReferenceType(base_type)
2421 def Node_to_type(node, env):
2422 from ExprNodes import NameNode, AttributeNode, StringNode, error
2423 if isinstance(node, StringNode):
2424 node = NameNode(node.pos, name=node.value)
2425 if isinstance(node, NameNode) and node.name in rank_to_type_name:
2426 return simple_c_type(1, 0, node.name)
2427 elif isinstance(node, (AttributeNode, NameNode)):
2428 node.analyze_types(env)
2429 if not node.entry.is_type:
2430 pass
2431 else:
2432 error(node.pos, "Bad type")
2434 def same_type(type1, type2):
2435 return type1.same_as(type2)
2437 def assignable_from(type1, type2):
2438 return type1.assignable_from(type2)
2440 def typecast(to_type, from_type, expr_code):
2441 # Return expr_code cast to a C type which can be
2442 # assigned to to_type, assuming its existing C type
2443 # is from_type.
2444 if to_type is from_type or \
2445 (not to_type.is_pyobject and assignable_from(to_type, from_type)):
2446 return expr_code
2447 else:
2448 #print "typecast: to", to_type, "from", from_type ###
2449 return to_type.cast_code(expr_code)
2452 type_conversion_predeclarations = """
2453 /* Type Conversion Predeclarations */
2455 #if PY_MAJOR_VERSION < 3
2456 #define __Pyx_PyBytes_FromString PyString_FromString
2457 #define __Pyx_PyBytes_FromStringAndSize PyString_FromStringAndSize
2458 #define __Pyx_PyBytes_AsString PyString_AsString
2459 #else
2460 #define __Pyx_PyBytes_FromString PyBytes_FromString
2461 #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
2462 #define __Pyx_PyBytes_AsString PyBytes_AsString
2463 #endif
2465 #define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((char*)s)
2466 #define __Pyx_PyBytes_AsUString(s) ((unsigned char*) __Pyx_PyBytes_AsString(s))
2468 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
2469 static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
2470 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
2472 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
2473 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
2474 static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
2476 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
2478 """ + type_conversion_predeclarations
2480 type_conversion_functions = """
2481 /* Type Conversion Functions */
2483 static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
2484 if (x == Py_True) return 1;
2485 else if ((x == Py_False) | (x == Py_None)) return 0;
2486 else return PyObject_IsTrue(x);
2487 }
2489 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
2490 PyNumberMethods *m;
2491 const char *name = NULL;
2492 PyObject *res = NULL;
2493 #if PY_VERSION_HEX < 0x03000000
2494 if (PyInt_Check(x) || PyLong_Check(x))
2495 #else
2496 if (PyLong_Check(x))
2497 #endif
2498 return Py_INCREF(x), x;
2499 m = Py_TYPE(x)->tp_as_number;
2500 #if PY_VERSION_HEX < 0x03000000
2501 if (m && m->nb_int) {
2502 name = "int";
2503 res = PyNumber_Int(x);
2504 }
2505 else if (m && m->nb_long) {
2506 name = "long";
2507 res = PyNumber_Long(x);
2508 }
2509 #else
2510 if (m && m->nb_int) {
2511 name = "int";
2512 res = PyNumber_Long(x);
2513 }
2514 #endif
2515 if (res) {
2516 #if PY_VERSION_HEX < 0x03000000
2517 if (!PyInt_Check(res) && !PyLong_Check(res)) {
2518 #else
2519 if (!PyLong_Check(res)) {
2520 #endif
2521 PyErr_Format(PyExc_TypeError,
2522 "__%s__ returned non-%s (type %.200s)",
2523 name, name, Py_TYPE(res)->tp_name);
2524 Py_DECREF(res);
2525 return NULL;
2526 }
2527 }
2528 else if (!PyErr_Occurred()) {
2529 PyErr_SetString(PyExc_TypeError,
2530 "an integer is required");
2531 }
2532 return res;
2533 }
2535 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
2536 Py_ssize_t ival;
2537 PyObject* x = PyNumber_Index(b);
2538 if (!x) return -1;
2539 ival = PyInt_AsSsize_t(x);
2540 Py_DECREF(x);
2541 return ival;
2542 }
2544 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
2545 #if PY_VERSION_HEX < 0x02050000
2546 if (ival <= LONG_MAX)
2547 return PyInt_FromLong((long)ival);
2548 else {
2549 unsigned char *bytes = (unsigned char *) &ival;
2550 int one = 1; int little = (int)*(unsigned char*)&one;
2551 return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
2552 }
2553 #else
2554 return PyInt_FromSize_t(ival);
2555 #endif
2556 }
2558 static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
2559 unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
2560 if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
2561 return (size_t)-1;
2562 } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
2563 PyErr_SetString(PyExc_OverflowError,
2564 "value too large to convert to size_t");
2565 return (size_t)-1;
2566 }
2567 return (size_t)val;
2568 }
2570 """ + type_conversion_functions
