Cython has moved to github.

cython

view Cython/Compiler/PyrexTypes.py @ 1586:4a96e1aff2d4

Fix error in buffer typestring checking
author Dag Sverre Seljebotn <dagss@student.matnat.uio.no>
date Tue Dec 16 10:02:51 2008 +0100 (3 years ago)
parents d6b77994c455
children 136bd9fa09a7
line source
1 #
2 # Pyrex - Types
3 #
5 from Cython.Utils import UtilityCode
6 import StringEncoding
7 import Naming
8 import copy
10 class BaseType:
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 #
53 # declaration_code(entity_code,
54 # for_display = 0, dll_linkage = None, pyrex = 0)
55 # Returns a code fragment for the declaration of an entity
56 # of this type, given a code fragment for the entity.
57 # * If for_display, this is for reading by a human in an error
58 # message; otherwise it must be valid C code.
59 # * If dll_linkage is not None, it must be 'DL_EXPORT' or
60 # 'DL_IMPORT', and will be added to the base type part of
61 # the declaration.
62 # * If pyrex = 1, this is for use in a 'cdef extern'
63 # statement of a Pyrex include file.
64 #
65 # assignable_from(src_type)
66 # Tests whether a variable of this type can be
67 # assigned a value of type src_type.
68 #
69 # same_as(other_type)
70 # Tests whether this type represents the same type
71 # as other_type.
72 #
73 # as_argument_type():
74 # Coerces array type into pointer type for use as
75 # a formal argument type.
76 #
78 is_pyobject = 0
79 is_extension_type = 0
80 is_builtin_type = 0
81 is_numeric = 0
82 is_int = 0
83 is_longlong = 0
84 is_float = 0
85 is_void = 0
86 is_array = 0
87 is_ptr = 0
88 is_null_ptr = 0
89 is_cfunction = 0
90 is_struct_or_union = 0
91 is_struct = 0
92 is_enum = 0
93 is_typedef = 0
94 is_string = 0
95 is_unicode = 0
96 is_returncode = 0
97 is_error = 0
98 is_buffer = 0
99 has_attributes = 0
100 default_value = ""
101 parsetuple_format = ""
102 pymemberdef_typecode = None
104 def resolve(self):
105 # If a typedef, returns the base type.
106 return self
108 def literal_code(self, value):
109 # Returns a C code fragment representing a literal
110 # value of this type.
111 return str(value)
113 def __str__(self):
114 return self.declaration_code("", for_display = 1).strip()
116 def same_as(self, other_type, **kwds):
117 return self.same_as_resolved_type(other_type.resolve(), **kwds)
119 def same_as_resolved_type(self, other_type):
120 return self == other_type or other_type is error_type
122 def subtype_of(self, other_type):
123 return self.subtype_of_resolved_type(other_type.resolve())
125 def subtype_of_resolved_type(self, other_type):
126 return self.same_as(other_type)
128 def assignable_from(self, src_type):
129 return self.assignable_from_resolved_type(src_type.resolve())
131 def assignable_from_resolved_type(self, src_type):
132 return self.same_as(src_type)
134 def as_argument_type(self):
135 return self
137 def is_complete(self):
138 # A type is incomplete if it is an unsized array,
139 # a struct whose attributes are not defined, etc.
140 return 1
142 def is_simple_buffer_dtype(self):
143 return (self.is_int or self.is_float or self.is_pyobject or
144 self.is_extension_type or self.is_ptr)
146 class CTypedefType(BaseType):
147 #
148 # Pseudo-type defined with a ctypedef statement in a
149 # 'cdef extern from' block. Delegates most attribute
150 # lookups to the base type. ANYTHING NOT DEFINED
151 # HERE IS DELEGATED!
152 #
153 # qualified_name string
154 # typedef_cname string
155 # typedef_base_type PyrexType
157 is_typedef = 1
159 def __init__(self, cname, base_type):
160 self.typedef_cname = cname
161 self.typedef_base_type = base_type
163 def resolve(self):
164 return self.typedef_base_type.resolve()
166 def declaration_code(self, entity_code,
167 for_display = 0, dll_linkage = None, pyrex = 0):
168 name = self.declaration_name(for_display, pyrex)
169 return self.base_declaration_code(name, entity_code)
171 def declaration_name(self, for_display = 0, pyrex = 0):
172 if pyrex or for_display:
173 return self.qualified_name
174 else:
175 return self.typedef_cname
177 def as_argument_type(self):
178 return self
180 def cast_code(self, expr_code):
181 # If self is really an array (rather than pointer), we can't cast.
182 # For example, the gmp mpz_t.
183 if self.typedef_base_type.is_ptr:
184 return self.typedef_base_type.cast_code(expr_code)
185 else:
186 return BaseType.cast_code(self, expr_code)
188 def __repr__(self):
189 return "<CTypedefType %s>" % self.typedef_cname
191 def __str__(self):
192 return self.declaration_name(for_display = 1)
194 def __getattr__(self, name):
195 return getattr(self.typedef_base_type, name)
197 class BufferType(BaseType):
198 #
199 # Delegates most attribute
200 # lookups to the base type. ANYTHING NOT DEFINED
201 # HERE IS DELEGATED!
203 # dtype PyrexType
204 # ndim int
205 # mode str
206 # negative_indices bool
207 # cast bool
208 # is_buffer bool
209 # writable bool
211 is_buffer = 1
212 writable = True
213 def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
214 self.base = base
215 self.dtype = dtype
216 self.ndim = ndim
217 self.buffer_ptr_type = CPtrType(dtype)
218 self.mode = mode
219 self.negative_indices = negative_indices
220 self.cast = cast
222 def as_argument_type(self):
223 return self
225 def __getattr__(self, name):
226 return getattr(self.base, name)
228 def __repr__(self):
229 return "<BufferType %r>" % self.base
232 class PyObjectType(PyrexType):
233 #
234 # Base class for all Python object types (reference-counted).
235 #
236 # buffer_defaults dict or None Default options for bu
238 is_pyobject = 1
239 default_value = "0"
240 parsetuple_format = "O"
241 pymemberdef_typecode = "T_OBJECT"
242 buffer_defaults = None
244 def __str__(self):
245 return "Python object"
247 def __repr__(self):
248 return "<PyObjectType>"
250 def assignable_from(self, src_type):
251 return 1 # Conversion will be attempted
253 def declaration_code(self, entity_code,
254 for_display = 0, dll_linkage = None, pyrex = 0):
255 if pyrex or for_display:
256 return self.base_declaration_code("object", entity_code)
257 else:
258 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
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 type_name = self.name
301 if type_name == 'str':
302 type_name = 'String'
303 elif type_name == 'set':
304 type_name = 'AnySet'
305 elif type_name == 'frozenset':
306 type_name = 'FrozenSet'
307 else:
308 type_name = type_name.capitalize()
309 return 'likely(Py%s_CheckExact(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", Py_TYPE(%s)->tp_name), 0)' % (type_name, arg, arg, self.name, arg)
311 def declaration_code(self, entity_code,
312 for_display = 0, dll_linkage = None, pyrex = 0):
313 if pyrex or for_display:
314 return self.base_declaration_code(self.name, entity_code)
315 else:
316 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
319 class PyExtensionType(PyObjectType):
320 #
321 # A Python extension type.
322 #
323 # name string
324 # scope CClassScope Attribute namespace
325 # visibility string
326 # typedef_flag boolean
327 # base_type PyExtensionType or None
328 # module_name string or None Qualified name of defining module
329 # objstruct_cname string Name of PyObject struct
330 # typeobj_cname string or None C code fragment referring to type object
331 # typeptr_cname string or None Name of pointer to external type object
332 # vtabslot_cname string Name of C method table member
333 # vtabstruct_cname string Name of C method table struct
334 # vtabptr_cname string Name of pointer to C method table
335 # vtable_cname string Name of C method table definition
337 is_extension_type = 1
338 has_attributes = 1
340 def __init__(self, name, typedef_flag, base_type):
341 self.name = name
342 self.scope = None
343 self.typedef_flag = typedef_flag
344 self.base_type = base_type
345 self.module_name = None
346 self.objstruct_cname = None
347 self.typeobj_cname = None
348 self.typeptr_cname = None
349 self.vtabslot_cname = None
350 self.vtabstruct_cname = None
351 self.vtabptr_cname = None
352 self.vtable_cname = None
354 def set_scope(self, scope):
355 self.scope = scope
356 if scope:
357 scope.parent_type = self
359 def subtype_of_resolved_type(self, other_type):
360 if other_type.is_extension_type:
361 return self is other_type or (
362 self.base_type and self.base_type.subtype_of(other_type))
363 else:
364 return other_type is py_object_type
366 def typeobj_is_available(self):
367 # Do we have a pointer to the type object?
368 return self.typeptr_cname
370 def typeobj_is_imported(self):
371 # If we don't know the C name of the type object but we do
372 # know which module it's defined in, it will be imported.
373 return self.typeobj_cname is None and self.module_name is not None
375 def declaration_code(self, entity_code,
376 for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
377 if pyrex or for_display:
378 return self.base_declaration_code(self.name, entity_code)
379 else:
380 if self.typedef_flag:
381 base_format = "%s"
382 else:
383 base_format = "struct %s"
384 base = public_decl(base_format % self.objstruct_cname, dll_linkage)
385 if deref:
386 return "%s %s" % (base, entity_code)
387 else:
388 return "%s *%s" % (base, entity_code)
390 def type_test_code(self, py_arg):
391 return "__Pyx_TypeTest(%s, %s)" % (py_arg, self.typeptr_cname)
393 def attributes_known(self):
394 return self.scope is not None
396 def __str__(self):
397 return self.name
399 def __repr__(self):
400 return "<PyExtensionType %s%s>" % (self.scope.class_name,
401 ("", " typedef")[self.typedef_flag])
404 class CType(PyrexType):
405 #
406 # Base class for all C types (non-reference-counted).
407 #
408 # to_py_function string C function for converting to Python object
409 # from_py_function string C function for constructing from Python object
410 #
412 to_py_function = None
413 from_py_function = None
414 exception_value = None
415 exception_check = 1
417 def create_convert_utility_code(self, env):
418 return True
420 def error_condition(self, result_code):
421 conds = []
422 if self.is_string:
423 conds.append("(!%s)" % result_code)
424 elif self.exception_value is not None:
425 conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
426 if self.exception_check:
427 conds.append("PyErr_Occurred()")
428 if len(conds) > 0:
429 return " && ".join(conds)
430 else:
431 return 0
434 class CVoidType(CType):
435 is_void = 1
437 def __repr__(self):
438 return "<CVoidType>"
440 def declaration_code(self, entity_code,
441 for_display = 0, dll_linkage = None, pyrex = 0):
442 base = public_decl("void", dll_linkage)
443 return self.base_declaration_code(base, entity_code)
445 def is_complete(self):
446 return 0
449 class CNumericType(CType):
450 #
451 # Base class for all C numeric types.
452 #
453 # rank integer Relative size
454 # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
455 #
457 is_numeric = 1
458 default_value = "0"
460 parsetuple_formats = ( # rank -> format
461 "BHIkK????", # unsigned
462 "bhilL?fd?", # assumed signed
463 "bhilL?fd?", # explicitly signed
464 )
466 sign_words = ("unsigned ", "", "signed ")
468 def __init__(self, rank, signed = 1, pymemberdef_typecode = None):
469 self.rank = rank
470 self.signed = signed
471 ptf = self.parsetuple_formats[signed][rank]
472 if ptf == '?':
473 ptf = None
474 self.parsetuple_format = ptf
475 self.pymemberdef_typecode = pymemberdef_typecode
477 def sign_and_name(self):
478 s = self.sign_words[self.signed]
479 n = rank_to_type_name[self.rank]
480 return s + n
482 def __repr__(self):
483 return "<CNumericType %s>" % self.sign_and_name()
485 def declaration_code(self, entity_code,
486 for_display = 0, dll_linkage = None, pyrex = 0):
487 base = public_decl(self.sign_and_name(), dll_linkage)
488 if for_display and self.is_longlong:
489 base = base.replace('PY_LONG_LONG', 'long long')
490 return self.base_declaration_code(base, entity_code)
493 int_conversion_list = {}
494 type_conversion_functions = ""
495 type_conversion_predeclarations = ""
497 class CIntType(CNumericType):
499 is_int = 1
500 typedef_flag = 0
501 to_py_function = "PyInt_FromLong"
502 from_py_function = "__pyx_PyInt_AsLong"
503 exception_value = -1
505 def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
506 CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
507 self.is_returncode = is_returncode
508 if self.from_py_function == '__pyx_PyInt_AsLong':
509 self.from_py_function = self.get_type_conversion()
511 def get_type_conversion(self):
512 # error on overflow
513 c_type = self.sign_and_name()
514 c_name = c_type.replace(' ', '_');
515 func_name = "__pyx_PyInt_%s" % c_name;
516 if not int_conversion_list.has_key(func_name):
517 # no env to add utility code to
518 global type_conversion_predeclarations, type_conversion_functions
519 if self.signed:
520 neg_test = ""
521 else:
522 neg_test = " || (long_val < 0)"
523 type_conversion_predeclarations += """
524 static INLINE %(c_type)s %(func_name)s(PyObject* x);""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name }
525 type_conversion_functions += """
526 static INLINE %(c_type)s %(func_name)s(PyObject* x) {
527 if (sizeof(%(c_type)s) < sizeof(long)) {
528 long long_val = __pyx_PyInt_AsLong(x);
529 %(c_type)s val = (%(c_type)s)long_val;
530 if (unlikely((val != long_val) %(neg_test)s)) {
531 PyErr_SetString(PyExc_OverflowError, "value too large to convert to %(c_type)s");
532 return (%(c_type)s)-1;
533 }
534 return val;
535 }
536 else {
537 return __pyx_PyInt_AsLong(x);
538 }
539 }
540 """ % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name, 'neg_test': neg_test }
541 int_conversion_list[func_name] = True
542 return func_name
544 def assignable_from_resolved_type(self, src_type):
545 return src_type.is_int or src_type.is_enum or src_type is error_type
548 class CBIntType(CIntType):
550 to_py_function = "__Pyx_PyBool_FromLong"
551 from_py_function = "__Pyx_PyObject_IsTrue"
552 exception_check = 0
555 class CAnonEnumType(CIntType):
557 is_enum = 1
560 class CUIntType(CIntType):
562 to_py_function = "PyLong_FromUnsignedLong"
563 from_py_function = "PyInt_AsUnsignedLongMask"
564 exception_value = -1
567 class CULongType(CUIntType):
569 to_py_function = "PyLong_FromUnsignedLong"
570 from_py_function = "PyInt_AsUnsignedLongMask"
573 class CLongLongType(CIntType):
575 is_longlong = 1
576 to_py_function = "PyLong_FromLongLong"
577 from_py_function = "__pyx_PyInt_AsLongLong"
580 class CULongLongType(CUIntType):
582 is_longlong = 1
583 to_py_function = "PyLong_FromUnsignedLongLong"
584 from_py_function = "__pyx_PyInt_AsUnsignedLongLong"
587 class CPySSizeTType(CIntType):
589 to_py_function = "PyInt_FromSsize_t"
590 from_py_function = "__pyx_PyIndex_AsSsize_t"
593 class CFloatType(CNumericType):
595 is_float = 1
596 to_py_function = "PyFloat_FromDouble"
597 from_py_function = "__pyx_PyFloat_AsDouble"
599 def __init__(self, rank, pymemberdef_typecode = None):
600 CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
602 def assignable_from_resolved_type(self, src_type):
603 return src_type.is_numeric or src_type is error_type
606 class CArrayType(CType):
607 # base_type CType Element type
608 # size integer or None Number of elements
610 is_array = 1
612 def __init__(self, base_type, size):
613 self.base_type = base_type
614 self.size = size
615 if base_type is c_char_type:
616 self.is_string = 1
618 def __repr__(self):
619 return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
621 def same_as_resolved_type(self, other_type):
622 return ((other_type.is_array and
623 self.base_type.same_as(other_type.base_type))
624 or other_type is error_type)
626 def assignable_from_resolved_type(self, src_type):
627 # Can't assign to a variable of an array type
628 return 0
630 def element_ptr_type(self):
631 return c_ptr_type(self.base_type)
633 def declaration_code(self, entity_code,
634 for_display = 0, dll_linkage = None, pyrex = 0):
635 if self.size is not None:
636 dimension_code = self.size
637 else:
638 dimension_code = ""
639 if entity_code.startswith("*"):
640 entity_code = "(%s)" % entity_code
641 return self.base_type.declaration_code(
642 "%s[%s]" % (entity_code, dimension_code),
643 for_display, dll_linkage, pyrex)
645 def as_argument_type(self):
646 return c_ptr_type(self.base_type)
648 def is_complete(self):
649 return self.size is not None
652 class CPtrType(CType):
653 # base_type CType Referenced type
655 is_ptr = 1
656 default_value = "0"
658 def __init__(self, base_type):
659 self.base_type = base_type
661 def __repr__(self):
662 return "<CPtrType %s>" % repr(self.base_type)
664 def same_as_resolved_type(self, other_type):
665 return ((other_type.is_ptr and
666 self.base_type.same_as(other_type.base_type))
667 or other_type is error_type)
669 def declaration_code(self, entity_code,
670 for_display = 0, dll_linkage = None, pyrex = 0):
671 #print "CPtrType.declaration_code: pointer to", self.base_type ###
672 return self.base_type.declaration_code(
673 "*%s" % entity_code,
674 for_display, dll_linkage, pyrex)
676 def assignable_from_resolved_type(self, other_type):
677 if other_type is error_type:
678 return 1
679 if other_type.is_null_ptr:
680 return 1
681 if self.base_type.is_cfunction:
682 if other_type.is_ptr:
683 other_type = other_type.base_type.resolve()
684 if other_type.is_cfunction:
685 return self.base_type.pointer_assignable_from_resolved_type(other_type)
686 else:
687 return 0
688 if other_type.is_array or other_type.is_ptr:
689 return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
690 return 0
693 class CNullPtrType(CPtrType):
695 is_null_ptr = 1
698 class CFuncType(CType):
699 # return_type CType
700 # args [CFuncTypeArg]
701 # has_varargs boolean
702 # exception_value string
703 # exception_check boolean True if PyErr_Occurred check needed
704 # calling_convention string Function calling convention
705 # nogil boolean Can be called without gil
706 # with_gil boolean Acquire gil around function body
708 is_cfunction = 1
709 original_sig = None
711 def __init__(self, return_type, args, has_varargs = 0,
712 exception_value = None, exception_check = 0, calling_convention = "",
713 nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0):
714 self.return_type = return_type
715 self.args = args
716 self.has_varargs = has_varargs
717 self.optional_arg_count = optional_arg_count
718 self.exception_value = exception_value
719 self.exception_check = exception_check
720 self.calling_convention = calling_convention
721 self.nogil = nogil
722 self.with_gil = with_gil
723 self.is_overridable = is_overridable
725 def __repr__(self):
726 arg_reprs = map(repr, self.args)
727 if self.has_varargs:
728 arg_reprs.append("...")
729 return "<CFuncType %s %s[%s]>" % (
730 repr(self.return_type),
731 self.calling_convention_prefix(),
732 ",".join(arg_reprs))
734 def calling_convention_prefix(self):
735 cc = self.calling_convention
736 if cc:
737 return cc + " "
738 else:
739 return ""
741 def same_c_signature_as(self, other_type, as_cmethod = 0):
742 return self.same_c_signature_as_resolved_type(
743 other_type.resolve(), as_cmethod)
745 def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
746 #print "CFuncType.same_c_signature_as_resolved_type:", \
747 # self, other_type, "as_cmethod =", as_cmethod ###
748 if other_type is error_type:
749 return 1
750 if not other_type.is_cfunction:
751 return 0
752 if self.is_overridable != other_type.is_overridable:
753 return 0
754 nargs = len(self.args)
755 if nargs != len(other_type.args):
756 return 0
757 # When comparing C method signatures, the first argument
758 # is exempt from compatibility checking (the proper check
759 # is performed elsewhere).
760 for i in range(as_cmethod, nargs):
761 if not self.args[i].type.same_as(
762 other_type.args[i].type):
763 return 0
764 if self.has_varargs != other_type.has_varargs:
765 return 0
766 if self.optional_arg_count != other_type.optional_arg_count:
767 return 0
768 if not self.return_type.same_as(other_type.return_type):
769 return 0
770 if not self.same_calling_convention_as(other_type):
771 return 0
772 return 1
774 def compatible_signature_with(self, other_type, as_cmethod = 0):
775 return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
777 def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
778 #print "CFuncType.same_c_signature_as_resolved_type:", \
779 # self, other_type, "as_cmethod =", as_cmethod ###
780 if other_type is error_type:
781 return 1
782 if not other_type.is_cfunction:
783 return 0
784 if not self.is_overridable and other_type.is_overridable:
785 return 0
786 nargs = len(self.args)
787 if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
788 return 0
789 if self.optional_arg_count < other_type.optional_arg_count:
790 return 0
791 # When comparing C method signatures, the first argument
792 # is exempt from compatibility checking (the proper check
793 # is performed elsewhere).
794 for i in range(as_cmethod, len(other_type.args)):
795 if not self.args[i].type.same_as(
796 other_type.args[i].type):
797 return 0
798 if self.has_varargs != other_type.has_varargs:
799 return 0
800 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
801 return 0
802 if not self.same_calling_convention_as(other_type):
803 return 0
804 if self.nogil != other_type.nogil:
805 return 0
806 self.original_sig = other_type.original_sig or other_type
807 if as_cmethod:
808 self.args[0] = other_type.args[0]
809 return 1
812 def narrower_c_signature_than(self, other_type, as_cmethod = 0):
813 return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
815 def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
816 if other_type is error_type:
817 return 1
818 if not other_type.is_cfunction:
819 return 0
820 nargs = len(self.args)
821 if nargs != len(other_type.args):
822 return 0
823 for i in range(as_cmethod, nargs):
824 if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
825 return 0
826 else:
827 self.args[i].needs_type_test = other_type.args[i].needs_type_test \
828 or not self.args[i].type.same_as(other_type.args[i].type)
829 if self.has_varargs != other_type.has_varargs:
830 return 0
831 if self.optional_arg_count != other_type.optional_arg_count:
832 return 0
833 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
834 return 0
835 return 1
837 def same_calling_convention_as(self, other):
838 sc1 = self.calling_convention == '__stdcall'
839 sc2 = other.calling_convention == '__stdcall'
840 return sc1 == sc2
842 def same_exception_signature_as(self, other_type):
843 return self.same_exception_signature_as_resolved_type(
844 other_type.resolve())
846 def same_exception_signature_as_resolved_type(self, other_type):
847 return self.exception_value == other_type.exception_value \
848 and self.exception_check == other_type.exception_check
850 def same_as_resolved_type(self, other_type, as_cmethod = 0):
851 return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
852 and self.same_exception_signature_as_resolved_type(other_type) \
853 and self.nogil == other_type.nogil
855 def pointer_assignable_from_resolved_type(self, other_type):
856 return self.same_c_signature_as_resolved_type(other_type) \
857 and self.same_exception_signature_as_resolved_type(other_type) \
858 and not (self.nogil and not other_type.nogil)
860 def declaration_code(self, entity_code,
861 for_display = 0, dll_linkage = None, pyrex = 0):
862 arg_decl_list = []
863 for arg in self.args[:len(self.args)-self.optional_arg_count]:
864 arg_decl_list.append(
865 arg.type.declaration_code("", for_display, pyrex = pyrex))
866 if self.is_overridable:
867 arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
868 if self.optional_arg_count:
869 arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
870 if self.has_varargs:
871 arg_decl_list.append("...")
872 arg_decl_code = ", ".join(arg_decl_list)
873 if not arg_decl_code and not pyrex:
874 arg_decl_code = "void"
875 trailer = ""
876 if (pyrex or for_display) and not self.return_type.is_pyobject:
877 if self.exception_value and self.exception_check:
878 trailer = " except? %s" % self.exception_value
879 elif self.exception_value:
880 trailer = " except %s" % self.exception_value
881 elif self.exception_check == '+':
882 trailer = " except +"
883 else:
884 " except *" # ignored
885 if self.nogil:
886 trailer += " nogil"
887 cc = self.calling_convention_prefix()
888 if (not entity_code and cc) or entity_code.startswith("*"):
889 entity_code = "(%s%s)" % (cc, entity_code)
890 cc = ""
891 return self.return_type.declaration_code(
892 "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
893 for_display, dll_linkage, pyrex)
895 def function_header_code(self, func_name, arg_code):
896 return "%s%s(%s)" % (self.calling_convention_prefix(),
897 func_name, arg_code)
899 def signature_string(self):
900 s = self.declaration_code("")
901 return s
904 class CFuncTypeArg:
905 # name string
906 # cname string
907 # type PyrexType
908 # pos source file position
910 def __init__(self, name, type, pos, cname=None):
911 self.name = name
912 if cname is not None:
913 self.cname = cname
914 else:
915 self.cname = Naming.var_prefix + name
916 self.type = type
917 self.pos = pos
918 self.not_none = False
919 self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
921 def __repr__(self):
922 return "%s:%s" % (self.name, repr(self.type))
924 def declaration_code(self, for_display = 0):
925 return self.type.declaration_code(self.cname, for_display)
928 class CStructOrUnionType(CType):
929 # name string
930 # cname string
931 # kind string "struct" or "union"
932 # scope StructOrUnionScope, or None if incomplete
933 # typedef_flag boolean
935 is_struct_or_union = 1
936 has_attributes = 1
938 def __init__(self, name, kind, scope, typedef_flag, cname):
939 self.name = name
940 self.cname = cname
941 self.kind = kind
942 self.scope = scope
943 self.typedef_flag = typedef_flag
944 self.is_struct = kind == 'struct'
945 if self.is_struct:
946 self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
947 self.exception_check = True
948 self._convert_code = None
950 def create_convert_utility_code(self, env):
951 if env.outer_scope is None:
952 return False
953 if self._convert_code is None:
954 import Code
955 code = Code.CCodeWriter()
956 header = "static PyObject* %s(%s)" % (self.to_py_function, self.declaration_code('s'))
957 code.putln("%s {" % header)
958 code.putln("PyObject* res;")
959 code.putln("PyObject* member;")
960 code.putln("res = PyDict_New(); if (res == NULL) return NULL;")
961 for member in self.scope.var_entries:
962 if member.type.to_py_function and member.type.create_convert_utility_code(env):
963 interned_name = env.get_string_const(member.name, identifier=True)
964 env.add_py_string(interned_name)
965 code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % (
966 member.type.to_py_function, member.cname))
967 code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % interned_name.pystring_cname)
968 code.putln("Py_DECREF(member);")
969 else:
970 self.to_py_function = None
971 return False
972 code.putln("return res;")
973 code.putln("bad:")
974 code.putln("Py_XDECREF(member);")
975 code.putln("Py_DECREF(res);")
976 code.putln("return NULL;")
977 code.putln("}")
978 proto = header + ";"
979 # This is a bit of a hack, we need a forward declaration
980 # due to the way things are ordered in the module...
981 entry = env.lookup(self.name)
982 if entry.visibility != 'extern':
983 proto = self.declaration_code('') + ';\n' + proto
984 self._convert_code = UtilityCode(proto=proto, impl=code.buffer.getvalue())
986 env.use_utility_code(self._convert_code)
987 return True
989 def __repr__(self):
990 return "<CStructOrUnionType %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.name, entity_code)
997 else:
998 if for_display:
999 base = self.name
1000 elif self.typedef_flag:
1001 base = self.cname
1002 else:
1003 base = "%s %s" % (self.kind, self.cname)
1004 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1006 def __cmp__(self, other):
1007 try:
1008 if self.name == other.name:
1009 return 0
1010 else:
1011 return 1
1012 except AttributeError:
1013 return 1
1015 def is_complete(self):
1016 return self.scope is not None
1018 def attributes_known(self):
1019 return self.is_complete()
1021 def can_be_complex(self):
1022 # Does the struct consist of exactly two floats?
1023 fields = self.scope.var_entries
1024 return len(fields) == 2 and fields[0].type.is_float and fields[1].type.is_float
1027 class CEnumType(CType):
1028 # name string
1029 # cname string or None
1030 # typedef_flag boolean
1032 is_enum = 1
1033 signed = 1
1034 rank = -1 # Ranks below any integer type
1035 to_py_function = "PyInt_FromLong"
1036 from_py_function = "PyInt_AsLong"
1038 def __init__(self, name, cname, typedef_flag):
1039 self.name = name
1040 self.cname = cname
1041 self.values = []
1042 self.typedef_flag = typedef_flag
1044 def __str__(self):
1045 return self.name
1047 def __repr__(self):
1048 return "<CEnumType %s %s%s>" % (self.name, self.cname,
1049 ("", " typedef")[self.typedef_flag])
1051 def declaration_code(self, entity_code,
1052 for_display = 0, dll_linkage = None, pyrex = 0):
1053 if pyrex:
1054 return self.base_declaration_code(self.cname, entity_code)
1055 else:
1056 if self.typedef_flag:
1057 base = self.cname
1058 else:
1059 base = "enum %s" % self.cname
1060 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1063 class CStringType:
1064 # Mixin class for C string types.
1066 is_string = 1
1067 is_unicode = 0
1069 to_py_function = "__Pyx_PyBytes_FromString"
1070 from_py_function = "__Pyx_PyBytes_AsString"
1071 exception_value = "NULL"
1073 def literal_code(self, value):
1074 assert isinstance(value, str)
1075 return '"%s"' % StringEncoding.escape_byte_string(value)
1078 class CUTF8CharArrayType(CStringType, CArrayType):
1079 # C 'char []' type.
1081 parsetuple_format = "s"
1082 pymemberdef_typecode = "T_STRING_INPLACE"
1083 is_unicode = 1
1085 to_py_function = "PyUnicode_DecodeUTF8"
1086 exception_value = "NULL"
1088 def __init__(self, size):
1089 CArrayType.__init__(self, c_char_type, size)
1091 class CCharArrayType(CStringType, CArrayType):
1092 # C 'char []' type.
1094 parsetuple_format = "s"
1095 pymemberdef_typecode = "T_STRING_INPLACE"
1097 def __init__(self, size):
1098 CArrayType.__init__(self, c_char_type, size)
1101 class CCharPtrType(CStringType, CPtrType):
1102 # C 'char *' type.
1104 parsetuple_format = "s"
1105 pymemberdef_typecode = "T_STRING"
1107 def __init__(self):
1108 CPtrType.__init__(self, c_char_type)
1111 class UnspecifiedType(PyrexType):
1112 # Used as a placeholder until the type can be determined.
1114 def declaration_code(self, entity_code,
1115 for_display = 0, dll_linkage = None, pyrex = 0):
1116 return "<unspecified>"
1118 def same_as_resolved_type(self, other_type):
1119 return False
1122 class ErrorType(PyrexType):
1123 # Used to prevent propagation of error messages.
1125 is_error = 1
1126 exception_value = "0"
1127 exception_check = 0
1128 to_py_function = "dummy"
1129 from_py_function = "dummy"
1131 def create_convert_utility_code(self, env):
1132 return True
1134 def declaration_code(self, entity_code,
1135 for_display = 0, dll_linkage = None, pyrex = 0):
1136 return "<error>"
1138 def same_as_resolved_type(self, other_type):
1139 return 1
1141 def error_condition(self, result_code):
1142 return "dummy"
1145 rank_to_type_name = (
1146 "char", # 0
1147 "short", # 1
1148 "int", # 2
1149 "long", # 3
1150 "PY_LONG_LONG", # 4
1151 "Py_ssize_t", # 5
1152 "float", # 6
1153 "double", # 7
1154 "long double", # 8
1157 py_object_type = PyObjectType()
1159 c_void_type = CVoidType()
1160 c_void_ptr_type = CPtrType(c_void_type)
1161 c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
1163 c_uchar_type = CIntType(0, 0, "T_UBYTE")
1164 c_ushort_type = CIntType(1, 0, "T_USHORT")
1165 c_uint_type = CUIntType(2, 0, "T_UINT")
1166 c_ulong_type = CULongType(3, 0, "T_ULONG")
1167 c_ulonglong_type = CULongLongType(4, 0, "T_ULONGLONG")
1169 c_char_type = CIntType(0, 1, "T_CHAR")
1170 c_short_type = CIntType(1, 1, "T_SHORT")
1171 c_int_type = CIntType(2, 1, "T_INT")
1172 c_long_type = CIntType(3, 1, "T_LONG")
1173 c_longlong_type = CLongLongType(4, 1, "T_LONGLONG")
1174 c_py_ssize_t_type = CPySSizeTType(5, 1)
1175 c_bint_type = CBIntType(2, 1, "T_INT")
1177 c_schar_type = CIntType(0, 2, "T_CHAR")
1178 c_sshort_type = CIntType(1, 2, "T_SHORT")
1179 c_sint_type = CIntType(2, 2, "T_INT")
1180 c_slong_type = CIntType(3, 2, "T_LONG")
1181 c_slonglong_type = CLongLongType(4, 2, "T_LONGLONG")
1183 c_float_type = CFloatType(6, "T_FLOAT")
1184 c_double_type = CFloatType(7, "T_DOUBLE")
1185 c_longdouble_type = CFloatType(8)
1187 c_null_ptr_type = CNullPtrType(c_void_type)
1188 c_char_array_type = CCharArrayType(None)
1189 c_char_ptr_type = CCharPtrType()
1190 c_utf8_char_array_type = CUTF8CharArrayType(None)
1191 c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
1192 c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
1193 c_int_ptr_type = CPtrType(c_int_type)
1195 c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1)
1197 c_anon_enum_type = CAnonEnumType(-1, 1)
1199 # the Py_buffer type is defined in Builtin.py
1200 c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
1201 c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
1203 error_type = ErrorType()
1204 unspecified_type = UnspecifiedType()
1206 lowest_float_rank = 6
1208 sign_and_rank_to_type = {
1209 #(signed, rank)
1210 (0, 0, ): c_uchar_type,
1211 (0, 1): c_ushort_type,
1212 (0, 2): c_uint_type,
1213 (0, 3): c_ulong_type,
1214 (0, 4): c_ulonglong_type,
1215 (0, 5): c_ulonglong_type, # I'm not sure about this. this should be for size_t Py_ssize_t
1216 (1, 0): c_char_type,
1217 (1, 1): c_short_type,
1218 (1, 2): c_int_type,
1219 (1, 3): c_long_type,
1220 (1, 4): c_longlong_type,
1221 (1, 5): c_py_ssize_t_type,
1222 (2, 0): c_schar_type,
1223 (2, 1): c_sshort_type,
1224 (2, 2): c_sint_type,
1225 (2, 3): c_slong_type,
1226 (2, 4): c_slonglong_type,
1227 (2, 5): c_py_ssize_t_type,
1228 (1, 6): c_float_type,
1229 (1, 7): c_double_type,
1230 (1, 8): c_longdouble_type,
1231 # In case we're mixing unsigned ints and floats...
1232 (0, 6): c_float_type,
1233 (0, 7): c_double_type,
1234 (0, 8): c_longdouble_type,
1237 modifiers_and_name_to_type = {
1238 #(signed, longness, name)
1239 (0, 0, "char"): c_uchar_type,
1240 (0, -1, "int"): c_ushort_type,
1241 (0, 0, "int"): c_uint_type,
1242 (0, 1, "int"): c_ulong_type,
1243 (0, 2, "int"): c_ulonglong_type,
1244 (1, 0, "void"): c_void_type,
1245 (1, 0, "char"): c_char_type,
1246 (1, -1, "int"): c_short_type,
1247 (1, 0, "int"): c_int_type,
1248 (1, 1, "int"): c_long_type,
1249 (1, 2, "int"): c_longlong_type,
1250 (1, 0, "Py_ssize_t"): c_py_ssize_t_type,
1251 (1, 0, "float"): c_float_type,
1252 (1, 0, "double"): c_double_type,
1253 (1, 1, "double"): c_longdouble_type,
1254 (1, 0, "object"): py_object_type,
1255 (1, 0, "bint"): c_bint_type,
1256 (2, 0, "char"): c_schar_type,
1257 (2, -1, "int"): c_sshort_type,
1258 (2, 0, "int"): c_sint_type,
1259 (2, 1, "int"): c_slong_type,
1260 (2, 2, "int"): c_slonglong_type,
1261 (2, 0, "Py_ssize_t"): c_py_ssize_t_type,
1263 (1, 0, "long"): c_long_type,
1264 (1, 0, "short"): c_short_type,
1265 (1, 0, "longlong"): c_longlong_type,
1266 (1, 0, "bint"): c_bint_type,
1269 def widest_numeric_type(type1, type2):
1270 # Given two numeric types, return the narrowest type
1271 # encompassing both of them.
1272 if type1.is_enum and type2.is_enum:
1273 return c_int_type
1274 elif type1 is type2:
1275 return type1
1276 elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
1277 if type2.rank > type1.rank:
1278 return type2
1279 else:
1280 return type1
1281 else:
1282 return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
1283 return widest_type
1285 def simple_c_type(signed, longness, name):
1286 # Find type descriptor for simple type given name and modifiers.
1287 # Returns None if arguments don't make sense.
1288 return modifiers_and_name_to_type.get((signed, longness, name))
1290 def parse_basic_type(name):
1291 base = None
1292 if name.startswith('p_'):
1293 base = parse_basic_type(name[2:])
1294 elif name.startswith('p'):
1295 base = parse_basic_type(name[1:])
1296 elif name.endswith('*'):
1297 base = parse_basic_type(name[:-1])
1298 if base:
1299 return CPtrType(base)
1300 elif name.startswith('u'):
1301 return simple_c_type(0, 0, name[1:])
1302 else:
1303 return simple_c_type(1, 0, name)
1305 def c_array_type(base_type, size):
1306 # Construct a C array type.
1307 if base_type is c_char_type:
1308 return CCharArrayType(size)
1309 elif base_type is error_type:
1310 return error_type
1311 else:
1312 return CArrayType(base_type, size)
1314 def c_ptr_type(base_type):
1315 # Construct a C pointer type.
1316 if base_type is c_char_type:
1317 return c_char_ptr_type
1318 elif base_type is error_type:
1319 return error_type
1320 else:
1321 return CPtrType(base_type)
1323 def Node_to_type(node, env):
1324 from ExprNodes import NameNode, AttributeNode, StringNode, error
1325 if isinstance(node, StringNode):
1326 node = NameNode(node.pos, name=node.value)
1327 if isinstance(node, NameNode) and node.name in rank_to_type_name:
1328 return simple_c_type(1, 0, node.name)
1329 elif isinstance(node, (AttributeNode, NameNode)):
1330 node.analyze_types(env)
1331 if not node.entry.is_type:
1332 pass
1333 else:
1334 error(node.pos, "Bad type")
1336 def public_decl(base, dll_linkage):
1337 if dll_linkage:
1338 return "%s(%s)" % (dll_linkage, base)
1339 else:
1340 return base
1342 def same_type(type1, type2):
1343 return type1.same_as(type2)
1345 def assignable_from(type1, type2):
1346 return type1.assignable_from(type2)
1348 def typecast(to_type, from_type, expr_code):
1349 # Return expr_code cast to a C type which can be
1350 # assigned to to_type, assuming its existing C type
1351 # is from_type.
1352 if to_type is from_type or \
1353 (not to_type.is_pyobject and assignable_from(to_type, from_type)):
1354 return expr_code
1355 else:
1356 #print "typecast: to", to_type, "from", from_type ###
1357 return to_type.cast_code(expr_code)
1360 type_conversion_predeclarations = """
1361 /* Type Conversion Predeclarations */
1363 #if PY_MAJOR_VERSION < 3
1364 #define __Pyx_PyBytes_FromString PyString_FromString
1365 #define __Pyx_PyBytes_AsString PyString_AsString
1366 #else
1367 #define __Pyx_PyBytes_FromString PyBytes_FromString
1368 #define __Pyx_PyBytes_AsString PyBytes_AsString
1369 #endif
1371 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
1372 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x);
1373 static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x);
1374 static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x);
1375 static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b);
1377 #define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x))
1378 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
1379 """ + type_conversion_predeclarations
1381 type_conversion_functions = """
1382 /* Type Conversion Functions */
1384 static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) {
1385 Py_ssize_t ival;
1386 PyObject* x = PyNumber_Index(b);
1387 if (!x) return -1;
1388 ival = PyInt_AsSsize_t(x);
1389 Py_DECREF(x);
1390 return ival;
1393 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
1394 if (x == Py_True) return 1;
1395 else if (x == Py_False) return 0;
1396 else return PyObject_IsTrue(x);
1399 static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) {
1400 if (PyInt_CheckExact(x)) {
1401 return PyInt_AS_LONG(x);
1403 else if (PyLong_CheckExact(x)) {
1404 return PyLong_AsLongLong(x);
1406 else {
1407 PY_LONG_LONG val;
1408 PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
1409 val = __pyx_PyInt_AsLongLong(tmp);
1410 Py_DECREF(tmp);
1411 return val;
1415 static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
1416 if (PyInt_CheckExact(x)) {
1417 long val = PyInt_AS_LONG(x);
1418 if (unlikely(val < 0)) {
1419 PyErr_SetString(PyExc_TypeError, "Negative assignment to unsigned type.");
1420 return (unsigned PY_LONG_LONG)-1;
1422 return val;
1424 else if (PyLong_CheckExact(x)) {
1425 return PyLong_AsUnsignedLongLong(x);
1427 else {
1428 PY_LONG_LONG val;
1429 PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
1430 val = __pyx_PyInt_AsUnsignedLongLong(tmp);
1431 Py_DECREF(tmp);
1432 return val;
1436 """ + type_conversion_functions