Cython has moved to github.
cython-devel
view Cython/Compiler/PyrexTypes.py @ 1213:302abc2245aa
lists as literal structs
| author | Robert Bradshaw <robertwb@math.washington.edu> |
|---|---|
| date | Tue Oct 07 15:02:54 2008 -0700 (3 years ago) |
| parents | c086038b5c07 |
| children | c53d543d00da |
line source
1 #
2 # Pyrex - Types
3 #
5 import StringEncoding
6 import Naming
7 import copy
10 class BaseType:
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 base_declaration_code(self, base_code, entity_code):
18 if entity_code:
19 return "%s %s" % (base_code, entity_code)
20 else:
21 return base_code
24 class PyrexType(BaseType):
25 #
26 # Base class for all Pyrex types.
27 #
28 # is_pyobject boolean Is a Python object type
29 # is_extension_type boolean Is a Python extension type
30 # is_numeric boolean Is a C numeric type
31 # is_int boolean Is a C integer type
32 # is_longlong boolean Is a long long or unsigned long long.
33 # is_float boolean Is a C floating point type
34 # is_void boolean Is the C void type
35 # is_array boolean Is a C array type
36 # is_ptr boolean Is a C pointer type
37 # is_null_ptr boolean Is the type of NULL
38 # is_cfunction boolean Is a C function type
39 # is_struct_or_union boolean Is a C struct or union type
40 # is_struct boolean Is a C struct type
41 # is_enum boolean Is a C enum type
42 # is_typedef boolean Is a typedef type
43 # is_string boolean Is a C char * type
44 # is_unicode boolean Is a UTF-8 encoded C char * type
45 # is_returncode boolean Is used only to signal exceptions
46 # is_error boolean Is the dummy error type
47 # is_buffer boolean Is buffer access type
48 # has_attributes boolean Has C dot-selectable attributes
49 # default_value string Initial value
50 # parsetuple_format string Format char for PyArg_ParseTuple
51 # pymemberdef_typecode string Type code for PyMemberDef struct
52 # typestring string String char defining the type (see Python struct module)
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 parsetuple_format = ""
103 pymemberdef_typecode = None
105 def resolve(self):
106 # If a typedef, returns the base type.
107 return self
109 def literal_code(self, value):
110 # Returns a C code fragment representing a literal
111 # value of this type.
112 return str(value)
114 def __str__(self):
115 return self.declaration_code("", for_display = 1).strip()
117 def same_as(self, other_type, **kwds):
118 return self.same_as_resolved_type(other_type.resolve(), **kwds)
120 def same_as_resolved_type(self, other_type):
121 return self == other_type or other_type is error_type
123 def subtype_of(self, other_type):
124 return self.subtype_of_resolved_type(other_type.resolve())
126 def subtype_of_resolved_type(self, other_type):
127 return self.same_as(other_type)
129 def assignable_from(self, src_type):
130 return self.assignable_from_resolved_type(src_type.resolve())
132 def assignable_from_resolved_type(self, src_type):
133 return self.same_as(src_type)
135 def as_argument_type(self):
136 return self
138 def is_complete(self):
139 # A type is incomplete if it is an unsized array,
140 # a struct whose attributes are not defined, etc.
141 return 1
144 class CTypedefType(BaseType):
145 #
146 # Pseudo-type defined with a ctypedef statement in a
147 # 'cdef extern from' block. Delegates most attribute
148 # lookups to the base type. ANYTHING NOT DEFINED
149 # HERE IS DELEGATED!
150 #
151 # qualified_name string
152 # typedef_cname string
153 # typedef_base_type PyrexType
155 is_typedef = 1
156 typestring = None # Because typedefs are not known exactly
158 def __init__(self, cname, base_type):
159 self.typedef_cname = cname
160 self.typedef_base_type = base_type
162 def resolve(self):
163 return self.typedef_base_type.resolve()
165 def declaration_code(self, entity_code,
166 for_display = 0, dll_linkage = None, pyrex = 0):
167 name = self.declaration_name(for_display, pyrex)
168 return self.base_declaration_code(name, entity_code)
170 def declaration_name(self, for_display = 0, pyrex = 0):
171 if pyrex or for_display:
172 return self.qualified_name
173 else:
174 return self.typedef_cname
176 def as_argument_type(self):
177 return self
179 def cast_code(self, expr_code):
180 # If self is really an array (rather than pointer), we can't cast.
181 # For example, the gmp mpz_t.
182 if self.typedef_base_type.is_ptr:
183 return self.typedef_base_type.cast_code(expr_code)
184 else:
185 return BaseType.cast_code(self, expr_code)
187 def __repr__(self):
188 return "<CTypedefType %s>" % self.typedef_cname
190 def __str__(self):
191 return self.declaration_name(for_display = 1)
193 def __getattr__(self, name):
194 return getattr(self.typedef_base_type, name)
196 class BufferType(BaseType):
197 #
198 # Delegates most attribute
199 # lookups to the base type. ANYTHING NOT DEFINED
200 # HERE IS DELEGATED!
202 # dtype PyrexType
203 # ndim int
204 # mode str
205 # negative_indices bool
206 # cast bool
207 # is_buffer bool
208 # writable bool
210 is_buffer = 1
211 writable = True
212 def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
213 self.base = base
214 self.dtype = dtype
215 self.ndim = ndim
216 self.buffer_ptr_type = CPtrType(dtype)
217 self.mode = mode
218 self.negative_indices = negative_indices
219 self.cast = cast
221 def as_argument_type(self):
222 return self
224 def __getattr__(self, name):
225 return getattr(self.base, name)
227 def __repr__(self):
228 return "<BufferType %r>" % self.base
231 class PyObjectType(PyrexType):
232 #
233 # Base class for all Python object types (reference-counted).
234 #
235 # buffer_defaults dict or None Default options for bu
237 is_pyobject = 1
238 default_value = "0"
239 parsetuple_format = "O"
240 pymemberdef_typecode = "T_OBJECT"
241 buffer_defaults = None
242 typestring = "O"
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)
261 class BuiltinObjectType(PyObjectType):
263 is_builtin_type = 1
264 has_attributes = 1
265 base_type = None
266 module_name = '__builtin__'
268 def __init__(self, name, cname):
269 self.name = name
270 self.cname = cname
271 self.typeptr_cname = "&" + cname
273 def set_scope(self, scope):
274 self.scope = scope
275 if scope:
276 scope.parent_type = self
278 def __str__(self):
279 return "%s object" % self.name
281 def __repr__(self):
282 return "<%s>"% self.cname
284 def assignable_from(self, src_type):
285 if isinstance(src_type, BuiltinObjectType):
286 return src_type.name == self.name
287 else:
288 return not src_type.is_extension_type
290 def typeobj_is_available(self):
291 return True
293 def attributes_known(self):
294 return True
296 def subtype_of(self, type):
297 return type.is_pyobject and self.assignable_from(type)
299 def type_test_code(self, arg):
300 return 'likely(Py%s_CheckExact(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", Py_TYPE(%s)->tp_name), 0)' % (self.name[0].upper() + self.name[1:], arg, arg, self.name, arg)
302 def declaration_code(self, entity_code,
303 for_display = 0, dll_linkage = None, pyrex = 0):
304 if pyrex or for_display:
305 return self.base_declaration_code(self.name, entity_code)
306 else:
307 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
310 class PyExtensionType(PyObjectType):
311 #
312 # A Python extension type.
313 #
314 # name string
315 # scope CClassScope Attribute namespace
316 # visibility string
317 # typedef_flag boolean
318 # base_type PyExtensionType or None
319 # module_name string or None Qualified name of defining module
320 # objstruct_cname string Name of PyObject struct
321 # typeobj_cname string or None C code fragment referring to type object
322 # typeptr_cname string or None Name of pointer to external type object
323 # vtabslot_cname string Name of C method table member
324 # vtabstruct_cname string Name of C method table struct
325 # vtabptr_cname string Name of pointer to C method table
326 # vtable_cname string Name of C method table definition
328 is_extension_type = 1
329 has_attributes = 1
331 def __init__(self, name, typedef_flag, base_type):
332 self.name = name
333 self.scope = None
334 self.typedef_flag = typedef_flag
335 self.base_type = base_type
336 self.module_name = None
337 self.objstruct_cname = None
338 self.typeobj_cname = None
339 self.typeptr_cname = None
340 self.vtabslot_cname = None
341 self.vtabstruct_cname = None
342 self.vtabptr_cname = None
343 self.vtable_cname = None
345 def set_scope(self, scope):
346 self.scope = scope
347 if scope:
348 scope.parent_type = self
350 def subtype_of_resolved_type(self, other_type):
351 if other_type.is_extension_type:
352 return self is other_type or (
353 self.base_type and self.base_type.subtype_of(other_type))
354 else:
355 return other_type is py_object_type
357 def typeobj_is_available(self):
358 # Do we have a pointer to the type object?
359 return self.typeptr_cname
361 def typeobj_is_imported(self):
362 # If we don't know the C name of the type object but we do
363 # know which module it's defined in, it will be imported.
364 return self.typeobj_cname is None and self.module_name is not None
366 def declaration_code(self, entity_code,
367 for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
368 if pyrex or for_display:
369 return self.base_declaration_code(self.name, entity_code)
370 else:
371 if self.typedef_flag:
372 base_format = "%s"
373 else:
374 base_format = "struct %s"
375 base = public_decl(base_format % self.objstruct_cname, dll_linkage)
376 if deref:
377 return "%s %s" % (base, entity_code)
378 else:
379 return "%s *%s" % (base, entity_code)
381 def type_test_code(self, py_arg):
382 return "__Pyx_TypeTest(%s, %s)" % (py_arg, self.typeptr_cname)
384 def attributes_known(self):
385 return self.scope is not None
387 def __str__(self):
388 return self.name
390 def __repr__(self):
391 return "<PyExtensionType %s%s>" % (self.scope.class_name,
392 ("", " typedef")[self.typedef_flag])
395 class CType(PyrexType):
396 #
397 # Base class for all C types (non-reference-counted).
398 #
399 # to_py_function string C function for converting to Python object
400 # from_py_function string C function for constructing from Python object
401 #
403 to_py_function = None
404 from_py_function = None
405 exception_value = None
406 exception_check = 1
408 def error_condition(self, result_code):
409 conds = []
410 if self.is_string:
411 conds.append("(!%s)" % result_code)
412 elif self.exception_value is not None:
413 conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
414 if self.exception_check:
415 conds.append("PyErr_Occurred()")
416 if len(conds) > 0:
417 return " && ".join(conds)
418 else:
419 return 0
422 class CVoidType(CType):
423 is_void = 1
425 def __repr__(self):
426 return "<CVoidType>"
428 def declaration_code(self, entity_code,
429 for_display = 0, dll_linkage = None, pyrex = 0):
430 base = public_decl("void", dll_linkage)
431 return self.base_declaration_code(base, entity_code)
433 def is_complete(self):
434 return 0
437 class CNumericType(CType):
438 #
439 # Base class for all C numeric types.
440 #
441 # rank integer Relative size
442 # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
443 #
445 is_numeric = 1
446 default_value = "0"
448 parsetuple_formats = ( # rank -> format
449 "BHIkK????", # unsigned
450 "bhilL?fd?", # assumed signed
451 "bhilL?fd?", # explicitly signed
452 )
454 sign_words = ("unsigned ", "", "signed ")
456 def __init__(self, rank, signed = 1, pymemberdef_typecode = None, typestring = None):
457 self.rank = rank
458 self.signed = signed
459 self.typestring = typestring
460 ptf = self.parsetuple_formats[signed][rank]
461 if ptf == '?':
462 ptf = None
463 self.parsetuple_format = ptf
464 self.pymemberdef_typecode = pymemberdef_typecode
466 def sign_and_name(self):
467 s = self.sign_words[self.signed]
468 n = rank_to_type_name[self.rank]
469 return s + n
471 def __repr__(self):
472 return "<CNumericType %s>" % self.sign_and_name()
474 def declaration_code(self, entity_code,
475 for_display = 0, dll_linkage = None, pyrex = 0):
476 base = public_decl(self.sign_and_name(), dll_linkage)
477 if for_display and self.is_longlong:
478 base = base.replace('PY_LONG_LONG', 'long long')
479 return self.base_declaration_code(base, entity_code)
482 int_conversion_list = {}
483 type_conversion_functions = ""
484 type_conversion_predeclarations = ""
486 class CIntType(CNumericType):
488 is_int = 1
489 typedef_flag = 0
490 to_py_function = "PyInt_FromLong"
491 from_py_function = "__pyx_PyInt_AsLong"
492 exception_value = -1
494 def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0,
495 typestring=None):
496 CNumericType.__init__(self, rank, signed, pymemberdef_typecode, typestring=typestring)
497 self.is_returncode = is_returncode
498 if self.from_py_function == '__pyx_PyInt_AsLong':
499 self.from_py_function = self.get_type_conversion()
501 def get_type_conversion(self):
502 # error on overflow
503 c_type = self.sign_and_name()
504 c_name = c_type.replace(' ', '_');
505 func_name = "__pyx_PyInt_%s" % c_name;
506 if not int_conversion_list.has_key(func_name):
507 # no env to add utility code to
508 global type_conversion_predeclarations, type_conversion_functions
509 if self.signed:
510 neg_test = ""
511 else:
512 neg_test = " || (long_val < 0)"
513 type_conversion_predeclarations += """
514 static INLINE %(c_type)s %(func_name)s(PyObject* x);""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name }
515 type_conversion_functions += """
516 static INLINE %(c_type)s %(func_name)s(PyObject* x) {
517 if (sizeof(%(c_type)s) < sizeof(long)) {
518 long long_val = __pyx_PyInt_AsLong(x);
519 %(c_type)s val = (%(c_type)s)long_val;
520 if (unlikely((val != long_val) %(neg_test)s)) {
521 PyErr_SetString(PyExc_OverflowError, "value too large to convert to %(c_type)s");
522 return (%(c_type)s)-1;
523 }
524 return val;
525 }
526 else {
527 return __pyx_PyInt_AsLong(x);
528 }
529 }
530 """ % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name, 'neg_test': neg_test }
531 int_conversion_list[func_name] = True
532 return func_name
534 def assignable_from_resolved_type(self, src_type):
535 return src_type.is_int or src_type.is_enum or src_type is error_type
538 class CBIntType(CIntType):
540 to_py_function = "__Pyx_PyBool_FromLong"
541 from_py_function = "__Pyx_PyObject_IsTrue"
542 exception_check = 0
545 class CAnonEnumType(CIntType):
547 is_enum = 1
550 class CUIntType(CIntType):
552 to_py_function = "PyLong_FromUnsignedLong"
553 from_py_function = "PyInt_AsUnsignedLongMask"
554 exception_value = -1
557 class CULongType(CUIntType):
559 to_py_function = "PyLong_FromUnsignedLong"
560 from_py_function = "PyInt_AsUnsignedLongMask"
563 class CLongLongType(CIntType):
565 is_longlong = 1
566 to_py_function = "PyLong_FromLongLong"
567 from_py_function = "__pyx_PyInt_AsLongLong"
570 class CULongLongType(CUIntType):
572 is_longlong = 1
573 to_py_function = "PyLong_FromUnsignedLongLong"
574 from_py_function = "__pyx_PyInt_AsUnsignedLongLong"
577 class CPySSizeTType(CIntType):
579 to_py_function = "PyInt_FromSsize_t"
580 from_py_function = "__pyx_PyIndex_AsSsize_t"
583 class CFloatType(CNumericType):
585 is_float = 1
586 to_py_function = "PyFloat_FromDouble"
587 from_py_function = "__pyx_PyFloat_AsDouble"
589 def __init__(self, rank, pymemberdef_typecode = None, typestring=None):
590 CNumericType.__init__(self, rank, 1, pymemberdef_typecode, typestring = typestring)
592 def assignable_from_resolved_type(self, src_type):
593 return src_type.is_numeric or src_type is error_type
596 class CArrayType(CType):
597 # base_type CType Element type
598 # size integer or None Number of elements
600 is_array = 1
602 def __init__(self, base_type, size):
603 self.base_type = base_type
604 self.size = size
605 if base_type is c_char_type:
606 self.is_string = 1
608 def __repr__(self):
609 return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
611 def same_as_resolved_type(self, other_type):
612 return ((other_type.is_array and
613 self.base_type.same_as(other_type.base_type))
614 or other_type is error_type)
616 def assignable_from_resolved_type(self, src_type):
617 # Can't assign to a variable of an array type
618 return 0
620 def element_ptr_type(self):
621 return c_ptr_type(self.base_type)
623 def declaration_code(self, entity_code,
624 for_display = 0, dll_linkage = None, pyrex = 0):
625 if self.size is not None:
626 dimension_code = self.size
627 else:
628 dimension_code = ""
629 if entity_code.startswith("*"):
630 entity_code = "(%s)" % entity_code
631 return self.base_type.declaration_code(
632 "%s[%s]" % (entity_code, dimension_code),
633 for_display, dll_linkage, pyrex)
635 def as_argument_type(self):
636 return c_ptr_type(self.base_type)
638 def is_complete(self):
639 return self.size is not None
642 class CPtrType(CType):
643 # base_type CType Referenced type
645 is_ptr = 1
646 default_value = "0"
648 def __init__(self, base_type):
649 self.base_type = base_type
651 def __repr__(self):
652 return "<CPtrType %s>" % repr(self.base_type)
654 def same_as_resolved_type(self, other_type):
655 return ((other_type.is_ptr and
656 self.base_type.same_as(other_type.base_type))
657 or other_type is error_type)
659 def declaration_code(self, entity_code,
660 for_display = 0, dll_linkage = None, pyrex = 0):
661 #print "CPtrType.declaration_code: pointer to", self.base_type ###
662 return self.base_type.declaration_code(
663 "*%s" % entity_code,
664 for_display, dll_linkage, pyrex)
666 def assignable_from_resolved_type(self, other_type):
667 if other_type is error_type:
668 return 1
669 if other_type.is_null_ptr:
670 return 1
671 if self.base_type.is_cfunction:
672 if other_type.is_ptr:
673 other_type = other_type.base_type.resolve()
674 if other_type.is_cfunction:
675 return self.base_type.pointer_assignable_from_resolved_type(other_type)
676 else:
677 return 0
678 if other_type.is_array or other_type.is_ptr:
679 return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
680 return 0
683 class CNullPtrType(CPtrType):
685 is_null_ptr = 1
688 class CFuncType(CType):
689 # return_type CType
690 # args [CFuncTypeArg]
691 # has_varargs boolean
692 # exception_value string
693 # exception_check boolean True if PyErr_Occurred check needed
694 # calling_convention string Function calling convention
695 # nogil boolean Can be called without gil
696 # with_gil boolean Acquire gil around function body
698 is_cfunction = 1
699 original_sig = None
701 def __init__(self, return_type, args, has_varargs = 0,
702 exception_value = None, exception_check = 0, calling_convention = "",
703 nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0):
704 self.return_type = return_type
705 self.args = args
706 self.has_varargs = has_varargs
707 self.optional_arg_count = optional_arg_count
708 self.exception_value = exception_value
709 self.exception_check = exception_check
710 self.calling_convention = calling_convention
711 self.nogil = nogil
712 self.with_gil = with_gil
713 self.is_overridable = is_overridable
715 def __repr__(self):
716 arg_reprs = map(repr, self.args)
717 if self.has_varargs:
718 arg_reprs.append("...")
719 return "<CFuncType %s %s[%s]>" % (
720 repr(self.return_type),
721 self.calling_convention_prefix(),
722 ",".join(arg_reprs))
724 def calling_convention_prefix(self):
725 cc = self.calling_convention
726 if cc:
727 return cc + " "
728 else:
729 return ""
731 def same_c_signature_as(self, other_type, as_cmethod = 0):
732 return self.same_c_signature_as_resolved_type(
733 other_type.resolve(), as_cmethod)
735 def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
736 #print "CFuncType.same_c_signature_as_resolved_type:", \
737 # self, other_type, "as_cmethod =", as_cmethod ###
738 if other_type is error_type:
739 return 1
740 if not other_type.is_cfunction:
741 return 0
742 if self.is_overridable != other_type.is_overridable:
743 return 0
744 nargs = len(self.args)
745 if nargs != len(other_type.args):
746 return 0
747 # When comparing C method signatures, the first argument
748 # is exempt from compatibility checking (the proper check
749 # is performed elsewhere).
750 for i in range(as_cmethod, nargs):
751 if not self.args[i].type.same_as(
752 other_type.args[i].type):
753 return 0
754 if self.has_varargs != other_type.has_varargs:
755 return 0
756 if self.optional_arg_count != other_type.optional_arg_count:
757 return 0
758 if not self.return_type.same_as(other_type.return_type):
759 return 0
760 if not self.same_calling_convention_as(other_type):
761 return 0
762 return 1
764 def compatible_signature_with(self, other_type, as_cmethod = 0):
765 return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
767 def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
768 #print "CFuncType.same_c_signature_as_resolved_type:", \
769 # self, other_type, "as_cmethod =", as_cmethod ###
770 if other_type is error_type:
771 return 1
772 if not other_type.is_cfunction:
773 return 0
774 if not self.is_overridable and other_type.is_overridable:
775 return 0
776 nargs = len(self.args)
777 if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
778 return 0
779 if self.optional_arg_count < other_type.optional_arg_count:
780 return 0
781 # When comparing C method signatures, the first argument
782 # is exempt from compatibility checking (the proper check
783 # is performed elsewhere).
784 for i in range(as_cmethod, len(other_type.args)):
785 if not self.args[i].type.same_as(
786 other_type.args[i].type):
787 return 0
788 if self.has_varargs != other_type.has_varargs:
789 return 0
790 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
791 return 0
792 if not self.same_calling_convention_as(other_type):
793 return 0
794 if self.nogil != other_type.nogil:
795 return 0
796 self.original_sig = other_type.original_sig or other_type
797 if as_cmethod:
798 self.args[0] = other_type.args[0]
799 return 1
802 def narrower_c_signature_than(self, other_type, as_cmethod = 0):
803 return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
805 def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
806 if other_type is error_type:
807 return 1
808 if not other_type.is_cfunction:
809 return 0
810 nargs = len(self.args)
811 if nargs != len(other_type.args):
812 return 0
813 for i in range(as_cmethod, nargs):
814 if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
815 return 0
816 else:
817 self.args[i].needs_type_test = other_type.args[i].needs_type_test \
818 or not self.args[i].type.same_as(other_type.args[i].type)
819 if self.has_varargs != other_type.has_varargs:
820 return 0
821 if self.optional_arg_count != other_type.optional_arg_count:
822 return 0
823 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
824 return 0
825 return 1
827 def same_calling_convention_as(self, other):
828 sc1 = self.calling_convention == '__stdcall'
829 sc2 = other.calling_convention == '__stdcall'
830 return sc1 == sc2
832 def same_exception_signature_as(self, other_type):
833 return self.same_exception_signature_as_resolved_type(
834 other_type.resolve())
836 def same_exception_signature_as_resolved_type(self, other_type):
837 return self.exception_value == other_type.exception_value \
838 and self.exception_check == other_type.exception_check
840 def same_as_resolved_type(self, other_type, as_cmethod = 0):
841 return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
842 and self.same_exception_signature_as_resolved_type(other_type) \
843 and self.nogil == other_type.nogil
845 def pointer_assignable_from_resolved_type(self, other_type):
846 return self.same_c_signature_as_resolved_type(other_type) \
847 and self.same_exception_signature_as_resolved_type(other_type) \
848 and not (self.nogil and not other_type.nogil)
850 def declaration_code(self, entity_code,
851 for_display = 0, dll_linkage = None, pyrex = 0):
852 arg_decl_list = []
853 for arg in self.args[:len(self.args)-self.optional_arg_count]:
854 arg_decl_list.append(
855 arg.type.declaration_code("", for_display, pyrex = pyrex))
856 if self.is_overridable:
857 arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
858 if self.optional_arg_count:
859 arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
860 if self.has_varargs:
861 arg_decl_list.append("...")
862 arg_decl_code = ", ".join(arg_decl_list)
863 if not arg_decl_code and not pyrex:
864 arg_decl_code = "void"
865 trailer = ""
866 if (pyrex or for_display) and not self.return_type.is_pyobject:
867 if self.exception_value and self.exception_check:
868 trailer = " except? %s" % self.exception_value
869 elif self.exception_value:
870 trailer = " except %s" % self.exception_value
871 elif self.exception_check == '+':
872 trailer = " except +"
873 else:
874 " except *" # ignored
875 if self.nogil:
876 trailer += " nogil"
877 cc = self.calling_convention_prefix()
878 if (not entity_code and cc) or entity_code.startswith("*"):
879 entity_code = "(%s%s)" % (cc, entity_code)
880 cc = ""
881 return self.return_type.declaration_code(
882 "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
883 for_display, dll_linkage, pyrex)
885 def function_header_code(self, func_name, arg_code):
886 return "%s%s(%s)" % (self.calling_convention_prefix(),
887 func_name, arg_code)
889 def signature_string(self):
890 s = self.declaration_code("")
891 return s
894 class CFuncTypeArg:
895 # name string
896 # cname string
897 # type PyrexType
898 # pos source file position
900 def __init__(self, name, type, pos, cname=None):
901 self.name = name
902 if cname is not None:
903 self.cname = cname
904 else:
905 self.cname = Naming.var_prefix + name
906 self.type = type
907 self.pos = pos
908 self.not_none = False
909 self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
911 def __repr__(self):
912 return "%s:%s" % (self.name, repr(self.type))
914 def declaration_code(self, for_display = 0):
915 return self.type.declaration_code(self.cname, for_display)
918 class CStructOrUnionType(CType):
919 # name string
920 # cname string
921 # kind string "struct" or "union"
922 # scope StructOrUnionScope, or None if incomplete
923 # typedef_flag boolean
925 is_struct_or_union = 1
926 has_attributes = 1
928 def __init__(self, name, kind, scope, typedef_flag, cname):
929 self.name = name
930 self.cname = cname
931 self.kind = kind
932 self.scope = scope
933 self.typedef_flag = typedef_flag
934 self.is_struct = kind == 'struct'
936 def __repr__(self):
937 return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
938 ("", " typedef")[self.typedef_flag])
940 def declaration_code(self, entity_code,
941 for_display = 0, dll_linkage = None, pyrex = 0):
942 if pyrex:
943 return self.base_declaration_code(self.name, entity_code)
944 else:
945 if for_display:
946 base = self.name
947 elif self.typedef_flag:
948 base = self.cname
949 else:
950 base = "%s %s" % (self.kind, self.cname)
951 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
953 def __cmp__(self, other):
954 try:
955 if self.name == other.name:
956 return 0
957 else:
958 return 1
959 except AttributeError:
960 return 1
962 def is_complete(self):
963 return self.scope is not None
965 def attributes_known(self):
966 return self.is_complete()
969 class CEnumType(CType):
970 # name string
971 # cname string or None
972 # typedef_flag boolean
974 is_enum = 1
975 signed = 1
976 rank = -1 # Ranks below any integer type
977 to_py_function = "PyInt_FromLong"
978 from_py_function = "PyInt_AsLong"
980 def __init__(self, name, cname, typedef_flag):
981 self.name = name
982 self.cname = cname
983 self.values = []
984 self.typedef_flag = typedef_flag
986 def __str__(self):
987 return self.name
989 def __repr__(self):
990 return "<CEnumType %s %s%s>" % (self.name, self.cname,
991 ("", " typedef")[self.typedef_flag])
993 def declaration_code(self, entity_code,
994 for_display = 0, dll_linkage = None, pyrex = 0):
995 if pyrex:
996 return self.base_declaration_code(self.cname, entity_code)
997 else:
998 if self.typedef_flag:
999 base = self.cname
1000 else:
1001 base = "enum %s" % self.cname
1002 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1005 class CStringType:
1006 # Mixin class for C string types.
1008 is_string = 1
1009 is_unicode = 0
1011 to_py_function = "__Pyx_PyBytes_FromString"
1012 from_py_function = "__Pyx_PyBytes_AsString"
1013 exception_value = "NULL"
1015 def literal_code(self, value):
1016 assert isinstance(value, str)
1017 return '"%s"' % StringEncoding.escape_byte_string(value)
1020 class CUTF8CharArrayType(CStringType, CArrayType):
1021 # C 'char []' type.
1023 parsetuple_format = "s"
1024 pymemberdef_typecode = "T_STRING_INPLACE"
1025 is_unicode = 1
1027 to_py_function = "PyUnicode_DecodeUTF8"
1028 exception_value = "NULL"
1030 def __init__(self, size):
1031 CArrayType.__init__(self, c_char_type, size)
1033 class CCharArrayType(CStringType, CArrayType):
1034 # C 'char []' type.
1036 parsetuple_format = "s"
1037 pymemberdef_typecode = "T_STRING_INPLACE"
1039 def __init__(self, size):
1040 CArrayType.__init__(self, c_char_type, size)
1043 class CCharPtrType(CStringType, CPtrType):
1044 # C 'char *' type.
1046 parsetuple_format = "s"
1047 pymemberdef_typecode = "T_STRING"
1049 def __init__(self):
1050 CPtrType.__init__(self, c_char_type)
1053 class UnspecifiedType(PyrexType):
1054 # Used as a placeholder until the type can be determined.
1056 def declaration_code(self, entity_code,
1057 for_display = 0, dll_linkage = None, pyrex = 0):
1058 return "<unspecified>"
1060 def same_as_resolved_type(self, other_type):
1061 return False
1064 class ErrorType(PyrexType):
1065 # Used to prevent propagation of error messages.
1067 is_error = 1
1068 exception_value = "0"
1069 exception_check = 0
1070 to_py_function = "dummy"
1071 from_py_function = "dummy"
1072 typestring = None
1074 def declaration_code(self, entity_code,
1075 for_display = 0, dll_linkage = None, pyrex = 0):
1076 return "<error>"
1078 def same_as_resolved_type(self, other_type):
1079 return 1
1081 def error_condition(self, result_code):
1082 return "dummy"
1085 rank_to_type_name = (
1086 "char", # 0
1087 "short", # 1
1088 "int", # 2
1089 "long", # 3
1090 "PY_LONG_LONG", # 4
1091 "Py_ssize_t", # 5
1092 "float", # 6
1093 "double", # 7
1094 "long double", # 8
1095 )
1097 py_object_type = PyObjectType()
1099 c_void_type = CVoidType()
1100 c_void_ptr_type = CPtrType(c_void_type)
1101 c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
1103 c_uchar_type = CIntType(0, 0, "T_UBYTE", typestring="B")
1104 c_ushort_type = CIntType(1, 0, "T_USHORT", typestring="H")
1105 c_uint_type = CUIntType(2, 0, "T_UINT", typestring="I")
1106 c_ulong_type = CULongType(3, 0, "T_ULONG", typestring="L")
1107 c_ulonglong_type = CULongLongType(4, 0, "T_ULONGLONG", typestring="Q")
1109 c_char_type = CIntType(0, 1, "T_CHAR", typestring="b")
1110 c_short_type = CIntType(1, 1, "T_SHORT", typestring="h")
1111 c_int_type = CIntType(2, 1, "T_INT", typestring="i")
1112 c_long_type = CIntType(3, 1, "T_LONG", typestring="l")
1113 c_longlong_type = CLongLongType(4, 1, "T_LONGLONG", typestring="q")
1114 c_py_ssize_t_type = CPySSizeTType(5, 1)
1115 c_bint_type = CBIntType(2, 1, "T_INT", typestring="i")
1117 c_schar_type = CIntType(0, 2, "T_CHAR", typestring="b")
1118 c_sshort_type = CIntType(1, 2, "T_SHORT", typestring="h")
1119 c_sint_type = CIntType(2, 2, "T_INT", typestring="i")
1120 c_slong_type = CIntType(3, 2, "T_LONG", typestring="l")
1121 c_slonglong_type = CLongLongType(4, 2, "T_LONGLONG", typestring="q")
1123 c_float_type = CFloatType(6, "T_FLOAT", typestring="f")
1124 c_double_type = CFloatType(7, "T_DOUBLE", typestring="d")
1125 c_longdouble_type = CFloatType(8, typestring="g")
1127 c_null_ptr_type = CNullPtrType(c_void_type)
1128 c_char_array_type = CCharArrayType(None)
1129 c_char_ptr_type = CCharPtrType()
1130 c_utf8_char_array_type = CUTF8CharArrayType(None)
1131 c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
1132 c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
1133 c_int_ptr_type = CPtrType(c_int_type)
1135 c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1)
1137 c_anon_enum_type = CAnonEnumType(-1, 1)
1139 # the Py_buffer type is defined in Builtin.py
1140 c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
1141 c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
1143 error_type = ErrorType()
1144 unspecified_type = UnspecifiedType()
1146 lowest_float_rank = 6
1148 sign_and_rank_to_type = {
1149 #(signed, rank)
1150 (0, 0, ): c_uchar_type,
1151 (0, 1): c_ushort_type,
1152 (0, 2): c_uint_type,
1153 (0, 3): c_ulong_type,
1154 (0, 4): c_ulonglong_type,
1155 (0, 5): c_ulonglong_type, # I'm not sure about this. this should be for size_t Py_ssize_t
1156 (1, 0): c_char_type,
1157 (1, 1): c_short_type,
1158 (1, 2): c_int_type,
1159 (1, 3): c_long_type,
1160 (1, 4): c_longlong_type,
1161 (1, 5): c_py_ssize_t_type,
1162 (2, 0): c_schar_type,
1163 (2, 1): c_sshort_type,
1164 (2, 2): c_sint_type,
1165 (2, 3): c_slong_type,
1166 (2, 4): c_slonglong_type,
1167 (2, 5): c_py_ssize_t_type,
1168 (1, 6): c_float_type,
1169 (1, 7): c_double_type,
1170 (1, 8): c_longdouble_type,
1171 }
1173 modifiers_and_name_to_type = {
1174 #(signed, longness, name)
1175 (0, 0, "char"): c_uchar_type,
1176 (0, -1, "int"): c_ushort_type,
1177 (0, 0, "int"): c_uint_type,
1178 (0, 1, "int"): c_ulong_type,
1179 (0, 2, "int"): c_ulonglong_type,
1180 (1, 0, "void"): c_void_type,
1181 (1, 0, "char"): c_char_type,
1182 (1, -1, "int"): c_short_type,
1183 (1, 0, "int"): c_int_type,
1184 (1, 1, "int"): c_long_type,
1185 (1, 2, "int"): c_longlong_type,
1186 (1, 0, "Py_ssize_t"): c_py_ssize_t_type,
1187 (1, 0, "float"): c_float_type,
1188 (1, 0, "double"): c_double_type,
1189 (1, 1, "double"): c_longdouble_type,
1190 (1, 0, "object"): py_object_type,
1191 (1, 0, "bint"): c_bint_type,
1192 (2, 0, "char"): c_schar_type,
1193 (2, -1, "int"): c_sshort_type,
1194 (2, 0, "int"): c_sint_type,
1195 (2, 1, "int"): c_slong_type,
1196 (2, 2, "int"): c_slonglong_type,
1197 (2, 0, "Py_ssize_t"): c_py_ssize_t_type,
1199 (1, 0, "long"): c_long_type,
1200 (1, 0, "longlong"): c_longlong_type,
1201 (1, 0, "bint"): c_bint_type,
1202 }
1204 def widest_numeric_type(type1, type2):
1205 # Given two numeric types, return the narrowest type
1206 # encompassing both of them.
1207 if type1.is_enum and type2.is_enum:
1208 return c_int_type
1209 elif type1 is type2:
1210 return type1
1211 elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
1212 if type2.rank > type1.rank:
1213 return type2
1214 else:
1215 return type1
1216 else:
1217 return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
1218 return widest_type
1220 def simple_c_type(signed, longness, name):
1221 # Find type descriptor for simple type given name and modifiers.
1222 # Returns None if arguments don't make sense.
1223 return modifiers_and_name_to_type.get((signed, longness, name))
1225 def parse_basic_type(name):
1226 base = None
1227 if name.startswith('p_'):
1228 base = parse_basic_type(name[2:])
1229 elif name.startswith('p'):
1230 base = parse_basic_type(name[1:])
1231 elif name.endswith('*'):
1232 base = parse_basic_type(name[:-1])
1233 if base:
1234 return CPtrType(base)
1235 elif name.startswith('u'):
1236 return simple_c_type(0, 0, name[1:])
1237 else:
1238 return simple_c_type(1, 0, name)
1240 def c_array_type(base_type, size):
1241 # Construct a C array type.
1242 if base_type is c_char_type:
1243 return CCharArrayType(size)
1244 else:
1245 return CArrayType(base_type, size)
1247 def c_ptr_type(base_type):
1248 # Construct a C pointer type.
1249 if base_type is c_char_type:
1250 return c_char_ptr_type
1251 else:
1252 return CPtrType(base_type)
1254 def Node_to_type(node, env):
1255 from ExprNodes import NameNode, AttributeNode, StringNode, error
1256 if isinstance(node, StringNode):
1257 node = NameNode(node.pos, name=node.value)
1258 if isinstance(node, NameNode) and node.name in rank_to_type_name:
1259 return simple_c_type(1, 0, node.name)
1260 elif isinstance(node, (AttributeNode, NameNode)):
1261 node.analyze_types(env)
1262 if not node.entry.is_type:
1263 pass
1264 else:
1265 error(node.pos, "Bad type")
1267 def public_decl(base, dll_linkage):
1268 if dll_linkage:
1269 return "%s(%s)" % (dll_linkage, base)
1270 else:
1271 return base
1273 def same_type(type1, type2):
1274 return type1.same_as(type2)
1276 def assignable_from(type1, type2):
1277 return type1.assignable_from(type2)
1279 def typecast(to_type, from_type, expr_code):
1280 # Return expr_code cast to a C type which can be
1281 # assigned to to_type, assuming its existing C type
1282 # is from_type.
1283 if to_type is from_type or \
1284 (not to_type.is_pyobject and assignable_from(to_type, from_type)):
1285 return expr_code
1286 else:
1287 #print "typecast: to", to_type, "from", from_type ###
1288 return to_type.cast_code(expr_code)
1291 type_conversion_predeclarations = """
1292 /* Type Conversion Predeclarations */
1294 #if PY_MAJOR_VERSION < 3
1295 #define __Pyx_PyBytes_FromString PyString_FromString
1296 #define __Pyx_PyBytes_AsString PyString_AsString
1297 #else
1298 #define __Pyx_PyBytes_FromString PyBytes_FromString
1299 #define __Pyx_PyBytes_AsString PyBytes_AsString
1300 #endif
1302 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
1303 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x);
1304 static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x);
1305 static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x);
1306 static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b);
1308 #define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x))
1309 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
1310 """ + type_conversion_predeclarations
1312 type_conversion_functions = """
1313 /* Type Conversion Functions */
1315 static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) {
1316 Py_ssize_t ival;
1317 PyObject* x = PyNumber_Index(b);
1318 if (!x) return -1;
1319 ival = PyInt_AsSsize_t(x);
1320 Py_DECREF(x);
1321 return ival;
1322 }
1324 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
1325 if (x == Py_True) return 1;
1326 else if (x == Py_False) return 0;
1327 else return PyObject_IsTrue(x);
1328 }
1330 static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) {
1331 if (PyInt_CheckExact(x)) {
1332 return PyInt_AS_LONG(x);
1333 }
1334 else if (PyLong_CheckExact(x)) {
1335 return PyLong_AsLongLong(x);
1336 }
1337 else {
1338 PY_LONG_LONG val;
1339 PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
1340 val = __pyx_PyInt_AsLongLong(tmp);
1341 Py_DECREF(tmp);
1342 return val;
1343 }
1344 }
1346 static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
1347 if (PyInt_CheckExact(x)) {
1348 long val = PyInt_AS_LONG(x);
1349 if (unlikely(val < 0)) {
1350 PyErr_SetString(PyExc_TypeError, "Negative assignment to unsigned type.");
1351 return (unsigned PY_LONG_LONG)-1;
1352 }
1353 return val;
1354 }
1355 else if (PyLong_CheckExact(x)) {
1356 return PyLong_AsUnsignedLongLong(x);
1357 }
1358 else {
1359 PY_LONG_LONG val;
1360 PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
1361 val = __pyx_PyInt_AsUnsignedLongLong(tmp);
1362 Py_DECREF(tmp);
1363 return val;
1364 }
1365 }
1367 """ + type_conversion_functions
