1#
2#   Cython/Python language types
3#
4
5from __future__ import absolute_import
6
7import copy
8import hashlib
9import re
10
11try:
12    reduce
13except NameError:
14    from functools import reduce
15
16from Cython.Utils import cached_function
17from .Code import UtilityCode, LazyUtilityCode, TempitaUtilityCode
18from . import StringEncoding
19from . import Naming
20
21from .Errors import error, warning
22
23
24class BaseType(object):
25    #
26    #  Base class for all Cython types including pseudo-types.
27
28    # List of attribute names of any subtypes
29    subtypes = []
30    _empty_declaration = None
31    _specialization_name = None
32    default_format_spec = None
33
34    def can_coerce_to_pyobject(self, env):
35        return False
36
37    def can_coerce_from_pyobject(self, env):
38        return False
39
40    def can_coerce_to_pystring(self, env, format_spec=None):
41        return False
42
43    def convert_to_pystring(self, cvalue, code, format_spec=None):
44        raise NotImplementedError("C types that support string formatting must override this method")
45
46    def cast_code(self, expr_code):
47        return "((%s)%s)" % (self.empty_declaration_code(), expr_code)
48
49    def empty_declaration_code(self):
50        if self._empty_declaration is None:
51            self._empty_declaration = self.declaration_code('')
52        return self._empty_declaration
53
54    def specialization_name(self):
55        if self._specialization_name is None:
56            # This is not entirely robust.
57            common_subs = (self.empty_declaration_code()
58                           .replace("unsigned ", "unsigned_")
59                           .replace("long long", "long_long")
60                           .replace(" ", "__"))
61            self._specialization_name = re.sub(
62                '[^a-zA-Z0-9_]', lambda x: '_%x_' % ord(x.group(0)), common_subs)
63        return self._specialization_name
64
65    def base_declaration_code(self, base_code, entity_code):
66        if entity_code:
67            return "%s %s" % (base_code, entity_code)
68        else:
69            return base_code
70
71    def __deepcopy__(self, memo):
72        """
73        Types never need to be copied, if we do copy, Unfortunate Things
74        Will Happen!
75        """
76        return self
77
78    def get_fused_types(self, result=None, seen=None, subtypes=None):
79        subtypes = subtypes or self.subtypes
80        if not subtypes:
81            return None
82
83        if result is None:
84            result = []
85            seen = set()
86
87        for attr in subtypes:
88            list_or_subtype = getattr(self, attr)
89            if list_or_subtype:
90                if isinstance(list_or_subtype, BaseType):
91                    list_or_subtype.get_fused_types(result, seen)
92                else:
93                    for subtype in list_or_subtype:
94                        subtype.get_fused_types(result, seen)
95
96        return result
97
98    def specialize_fused(self, env):
99        if env.fused_to_specific:
100            return self.specialize(env.fused_to_specific)
101
102        return self
103
104    @property
105    def is_fused(self):
106        """
107        Whether this type or any of its subtypes is a fused type
108        """
109        # Add this indirection for the is_fused property to allow overriding
110        # get_fused_types in subclasses.
111        return self.get_fused_types()
112
113    def deduce_template_params(self, actual):
114        """
115        Deduce any template params in this (argument) type given the actual
116        argument type.
117
118        http://en.cppreference.com/w/cpp/language/function_template#Template_argument_deduction
119        """
120        return {}
121
122    def __lt__(self, other):
123        """
124        For sorting. The sorting order should correspond to the preference of
125        conversion from Python types.
126
127        Override to provide something sensible. This is only implemented so that
128        python 3 doesn't trip
129        """
130        return id(type(self)) < id(type(other))
131
132    def py_type_name(self):
133        """
134        Return the name of the Python type that can coerce to this type.
135        """
136
137    def typeof_name(self):
138        """
139        Return the string with which fused python functions can be indexed.
140        """
141        if self.is_builtin_type or self.py_type_name() == 'object':
142            index_name = self.py_type_name()
143        else:
144            index_name = str(self)
145
146        return index_name
147
148    def check_for_null_code(self, cname):
149        """
150        Return the code for a NULL-check in case an UnboundLocalError should
151        be raised if an entry of this type is referenced before assignment.
152        Returns None if no check should be performed.
153        """
154        return None
155
156    def invalid_value(self):
157        """
158        Returns the most invalid value an object of this type can assume as a
159        C expression string. Returns None if no such value exists.
160        """
161
162
163class PyrexType(BaseType):
164    #
165    #  Base class for all Cython types
166    #
167    #  is_pyobject           boolean     Is a Python object type
168    #  is_extension_type     boolean     Is a Python extension type
169    #  is_final_type         boolean     Is a final extension type
170    #  is_numeric            boolean     Is a C numeric type
171    #  is_int                boolean     Is a C integer type
172    #  is_float              boolean     Is a C floating point type
173    #  is_complex            boolean     Is a C complex type
174    #  is_void               boolean     Is the C void type
175    #  is_array              boolean     Is a C array type
176    #  is_ptr                boolean     Is a C pointer type
177    #  is_null_ptr           boolean     Is the type of NULL
178    #  is_reference          boolean     Is a C reference type
179    #  is_const              boolean     Is a C const type.
180    #  is_cfunction          boolean     Is a C function type
181    #  is_struct_or_union    boolean     Is a C struct or union type
182    #  is_struct             boolean     Is a C struct type
183    #  is_enum               boolean     Is a C enum type
184    #  is_typedef            boolean     Is a typedef type
185    #  is_string             boolean     Is a C char * type
186    #  is_pyunicode_ptr      boolean     Is a C PyUNICODE * type
187    #  is_cpp_string         boolean     Is a C++ std::string type
188    #  is_unicode_char       boolean     Is either Py_UCS4 or Py_UNICODE
189    #  is_returncode         boolean     Is used only to signal exceptions
190    #  is_error              boolean     Is the dummy error type
191    #  is_buffer             boolean     Is buffer access type
192    #  is_pythran_expr       boolean     Is Pythran expr
193    #  is_numpy_buffer       boolean     Is Numpy array buffer
194    #  has_attributes        boolean     Has C dot-selectable attributes
195    #  default_value         string      Initial value that can be assigned before first user assignment.
196    #  declaration_value     string      The value statically assigned on declaration (if any).
197    #  entry                 Entry       The Entry for this type
198    #
199    #  declaration_code(entity_code,
200    #      for_display = 0, dll_linkage = None, pyrex = 0)
201    #    Returns a code fragment for the declaration of an entity
202    #    of this type, given a code fragment for the entity.
203    #    * If for_display, this is for reading by a human in an error
204    #      message; otherwise it must be valid C code.
205    #    * If dll_linkage is not None, it must be 'DL_EXPORT' or
206    #      'DL_IMPORT', and will be added to the base type part of
207    #      the declaration.
208    #    * If pyrex = 1, this is for use in a 'cdef extern'
209    #      statement of a Cython include file.
210    #
211    #  assignable_from(src_type)
212    #    Tests whether a variable of this type can be
213    #    assigned a value of type src_type.
214    #
215    #  same_as(other_type)
216    #    Tests whether this type represents the same type
217    #    as other_type.
218    #
219    #  as_argument_type():
220    #    Coerces array and C function types into pointer type for use as
221    #    a formal argument type.
222    #
223
224    is_pyobject = 0
225    is_unspecified = 0
226    is_extension_type = 0
227    is_final_type = 0
228    is_builtin_type = 0
229    is_numeric = 0
230    is_int = 0
231    is_float = 0
232    is_complex = 0
233    is_void = 0
234    is_array = 0
235    is_ptr = 0
236    is_null_ptr = 0
237    is_reference = 0
238    is_const = 0
239    is_cfunction = 0
240    is_struct_or_union = 0
241    is_cpp_class = 0
242    is_cpp_string = 0
243    is_struct = 0
244    is_enum = 0
245    is_typedef = 0
246    is_string = 0
247    is_pyunicode_ptr = 0
248    is_unicode_char = 0
249    is_returncode = 0
250    is_error = 0
251    is_buffer = 0
252    is_ctuple = 0
253    is_memoryviewslice = 0
254    is_pythran_expr = 0
255    is_numpy_buffer = 0
256    has_attributes = 0
257    default_value = ""
258    declaration_value = ""
259
260    def resolve(self):
261        # If a typedef, returns the base type.
262        return self
263
264    def specialize(self, values):
265        # TODO(danilo): Override wherever it makes sense.
266        return self
267
268    def literal_code(self, value):
269        # Returns a C code fragment representing a literal
270        # value of this type.
271        return str(value)
272
273    def __str__(self):
274        return self.declaration_code("", for_display = 1).strip()
275
276    def same_as(self, other_type, **kwds):
277        return self.same_as_resolved_type(other_type.resolve(), **kwds)
278
279    def same_as_resolved_type(self, other_type):
280        return self == other_type or other_type is error_type
281
282    def subtype_of(self, other_type):
283        return self.subtype_of_resolved_type(other_type.resolve())
284
285    def subtype_of_resolved_type(self, other_type):
286        return self.same_as(other_type)
287
288    def assignable_from(self, src_type):
289        return self.assignable_from_resolved_type(src_type.resolve())
290
291    def assignable_from_resolved_type(self, src_type):
292        return self.same_as(src_type)
293
294    def as_argument_type(self):
295        return self
296
297    def is_complete(self):
298        # A type is incomplete if it is an unsized array,
299        # a struct whose attributes are not defined, etc.
300        return 1
301
302    def is_simple_buffer_dtype(self):
303        return (self.is_int or self.is_float or self.is_complex or self.is_pyobject or
304                self.is_extension_type or self.is_ptr)
305
306    def struct_nesting_depth(self):
307        # Returns the number levels of nested structs. This is
308        # used for constructing a stack for walking the run-time
309        # type information of the struct.
310        return 1
311
312    def global_init_code(self, entry, code):
313        # abstract
314        pass
315
316    def needs_nonecheck(self):
317        return 0
318
319    def _assign_from_py_code(self, source_code, result_code, error_pos, code,
320                             from_py_function=None, error_condition=None, extra_args=None):
321        args = ', ' + ', '.join('%s' % arg for arg in extra_args) if extra_args else ''
322        convert_call = "%s(%s%s)" % (
323            from_py_function or self.from_py_function,
324            source_code,
325            args,
326        )
327        if self.is_enum:
328            convert_call = typecast(self, c_long_type, convert_call)
329        return '%s = %s; %s' % (
330            result_code,
331            convert_call,
332            code.error_goto_if(error_condition or self.error_condition(result_code), error_pos))
333
334
335def public_decl(base_code, dll_linkage):
336    if dll_linkage:
337        return "%s(%s)" % (dll_linkage, base_code.replace(',', ' __PYX_COMMA '))
338    else:
339        return base_code
340
341def create_typedef_type(name, base_type, cname, is_external=0, namespace=None):
342    is_fused = base_type.is_fused
343    if base_type.is_complex or is_fused:
344        if is_external:
345            if is_fused:
346                msg = "Fused"
347            else:
348                msg = "Complex"
349
350            raise ValueError("%s external typedefs not supported" % msg)
351
352        return base_type
353    else:
354        return CTypedefType(name, base_type, cname, is_external, namespace)
355
356
357class CTypedefType(BaseType):
358    #
359    #  Pseudo-type defined with a ctypedef statement in a
360    #  'cdef extern from' block.
361    #  Delegates most attribute lookups to the base type.
362    #  (Anything not defined here or in the BaseType is delegated.)
363    #
364    #  qualified_name      string
365    #  typedef_name        string
366    #  typedef_cname       string
367    #  typedef_base_type   PyrexType
368    #  typedef_is_external bool
369
370    is_typedef = 1
371    typedef_is_external = 0
372
373    to_py_utility_code = None
374    from_py_utility_code = None
375
376    subtypes = ['typedef_base_type']
377
378    def __init__(self, name, base_type, cname, is_external=0, namespace=None):
379        assert not base_type.is_complex
380        self.typedef_name = name
381        self.typedef_cname = cname
382        self.typedef_base_type = base_type
383        self.typedef_is_external = is_external
384        self.typedef_namespace = namespace
385
386    def invalid_value(self):
387        return self.typedef_base_type.invalid_value()
388
389    def resolve(self):
390        return self.typedef_base_type.resolve()
391
392    def declaration_code(self, entity_code,
393            for_display = 0, dll_linkage = None, pyrex = 0):
394        if pyrex or for_display:
395            base_code = self.typedef_name
396        else:
397            base_code = public_decl(self.typedef_cname, dll_linkage)
398        if self.typedef_namespace is not None and not pyrex:
399            base_code = "%s::%s" % (self.typedef_namespace.empty_declaration_code(), base_code)
400        return self.base_declaration_code(base_code, entity_code)
401
402    def as_argument_type(self):
403        return self
404
405    def cast_code(self, expr_code):
406        # If self is really an array (rather than pointer), we can't cast.
407        # For example, the gmp mpz_t.
408        if self.typedef_base_type.is_array:
409            base_type = self.typedef_base_type.base_type
410            return CPtrType(base_type).cast_code(expr_code)
411        else:
412            return BaseType.cast_code(self, expr_code)
413
414    def specialize(self, values):
415        base_type = self.typedef_base_type.specialize(values)
416        namespace = self.typedef_namespace.specialize(values) if self.typedef_namespace else None
417        if base_type is self.typedef_base_type and namespace is self.typedef_namespace:
418            return self
419        else:
420            return create_typedef_type(self.typedef_name, base_type, self.typedef_cname,
421                                0, namespace)
422
423    def __repr__(self):
424        return "<CTypedefType %s>" % self.typedef_cname
425
426    def __str__(self):
427        return self.typedef_name
428
429    def _create_utility_code(self, template_utility_code,
430                             template_function_name):
431        type_name = type_identifier(self.typedef_cname)
432        utility_code = template_utility_code.specialize(
433            type     = self.typedef_cname,
434            TypeName = type_name)
435        function_name = template_function_name % type_name
436        return utility_code, function_name
437
438    def create_to_py_utility_code(self, env):
439        if self.typedef_is_external:
440            if not self.to_py_utility_code:
441                base_type = self.typedef_base_type
442                if type(base_type) is CIntType:
443                    self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name()
444                    env.use_utility_code(TempitaUtilityCode.load_cached(
445                        "CIntToPy", "TypeConversion.c",
446                        context={"TYPE": self.empty_declaration_code(),
447                                 "TO_PY_FUNCTION": self.to_py_function}))
448                    return True
449                elif base_type.is_float:
450                    pass # XXX implement!
451                elif base_type.is_complex:
452                    pass # XXX implement!
453                    pass
454                elif base_type.is_cpp_string:
455                    cname = "__pyx_convert_PyObject_string_to_py_%s" % type_identifier(self)
456                    context = {
457                        'cname': cname,
458                        'type': self.typedef_cname,
459                    }
460                    from .UtilityCode import CythonUtilityCode
461                    env.use_utility_code(CythonUtilityCode.load(
462                        "string.to_py", "CppConvert.pyx", context=context))
463                    self.to_py_function = cname
464                    return True
465            if self.to_py_utility_code:
466                env.use_utility_code(self.to_py_utility_code)
467                return True
468        # delegation
469        return self.typedef_base_type.create_to_py_utility_code(env)
470
471    def create_from_py_utility_code(self, env):
472        if self.typedef_is_external:
473            if not self.from_py_utility_code:
474                base_type = self.typedef_base_type
475                if type(base_type) is CIntType:
476                    self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name()
477                    env.use_utility_code(TempitaUtilityCode.load_cached(
478                        "CIntFromPy", "TypeConversion.c",
479                        context={"TYPE": self.empty_declaration_code(),
480                                 "FROM_PY_FUNCTION": self.from_py_function}))
481                    return True
482                elif base_type.is_float:
483                    pass # XXX implement!
484                elif base_type.is_complex:
485                    pass # XXX implement!
486                elif base_type.is_cpp_string:
487                    cname = '__pyx_convert_string_from_py_%s' % type_identifier(self)
488                    context = {
489                        'cname': cname,
490                        'type': self.typedef_cname,
491                    }
492                    from .UtilityCode import CythonUtilityCode
493                    env.use_utility_code(CythonUtilityCode.load(
494                        "string.from_py", "CppConvert.pyx", context=context))
495                    self.from_py_function = cname
496                    return True
497            if self.from_py_utility_code:
498                env.use_utility_code(self.from_py_utility_code)
499                return True
500        # delegation
501        return self.typedef_base_type.create_from_py_utility_code(env)
502
503    def to_py_call_code(self, source_code, result_code, result_type, to_py_function=None):
504        if to_py_function is None:
505            to_py_function = self.to_py_function
506        return self.typedef_base_type.to_py_call_code(
507            source_code, result_code, result_type, to_py_function)
508
509    def from_py_call_code(self, source_code, result_code, error_pos, code,
510                          from_py_function=None, error_condition=None):
511        return self.typedef_base_type.from_py_call_code(
512            source_code, result_code, error_pos, code,
513            from_py_function or self.from_py_function,
514            error_condition or self.error_condition(result_code)
515        )
516
517    def overflow_check_binop(self, binop, env, const_rhs=False):
518        env.use_utility_code(UtilityCode.load("Common", "Overflow.c"))
519        type = self.empty_declaration_code()
520        name = self.specialization_name()
521        if binop == "lshift":
522            env.use_utility_code(TempitaUtilityCode.load_cached(
523                "LeftShift", "Overflow.c",
524                context={'TYPE': type, 'NAME': name, 'SIGNED': self.signed}))
525        else:
526            if const_rhs:
527                binop += "_const"
528            _load_overflow_base(env)
529            env.use_utility_code(TempitaUtilityCode.load_cached(
530                "SizeCheck", "Overflow.c",
531                context={'TYPE': type, 'NAME': name}))
532            env.use_utility_code(TempitaUtilityCode.load_cached(
533                "Binop", "Overflow.c",
534                context={'TYPE': type, 'NAME': name, 'BINOP': binop}))
535        return "__Pyx_%s_%s_checking_overflow" % (binop, name)
536
537    def error_condition(self, result_code):
538        if self.typedef_is_external:
539            if self.exception_value:
540                condition = "(%s == %s)" % (
541                    result_code, self.cast_code(self.exception_value))
542                if self.exception_check:
543                    condition += " && PyErr_Occurred()"
544                return condition
545        # delegation
546        return self.typedef_base_type.error_condition(result_code)
547
548    def __getattr__(self, name):
549        return getattr(self.typedef_base_type, name)
550
551    def py_type_name(self):
552        return self.typedef_base_type.py_type_name()
553
554    def can_coerce_to_pyobject(self, env):
555        return self.typedef_base_type.can_coerce_to_pyobject(env)
556
557    def can_coerce_from_pyobject(self, env):
558        return self.typedef_base_type.can_coerce_from_pyobject(env)
559
560
561class MemoryViewSliceType(PyrexType):
562
563    is_memoryviewslice = 1
564
565    has_attributes = 1
566    scope = None
567
568    # These are special cased in Defnode
569    from_py_function = None
570    to_py_function = None
571
572    exception_value = None
573    exception_check = True
574
575    subtypes = ['dtype']
576
577    def __init__(self, base_dtype, axes):
578        """
579        MemoryViewSliceType(base, axes)
580
581        Base is the C base type; axes is a list of (access, packing) strings,
582        where access is one of 'full', 'direct' or 'ptr' and packing is one of
583        'contig', 'strided' or 'follow'.  There is one (access, packing) tuple
584        for each dimension.
585
586        the access specifiers determine whether the array data contains
587        pointers that need to be dereferenced along that axis when
588        retrieving/setting:
589
590        'direct' -- No pointers stored in this dimension.
591        'ptr' -- Pointer stored in this dimension.
592        'full' -- Check along this dimension, don't assume either.
593
594        the packing specifiers specify how the array elements are layed-out
595        in memory.
596
597        'contig' -- The data is contiguous in memory along this dimension.
598                At most one dimension may be specified as 'contig'.
599        'strided' -- The data isn't contiguous along this dimension.
600        'follow' -- Used for C/Fortran contiguous arrays, a 'follow' dimension
601            has its stride automatically computed from extents of the other
602            dimensions to ensure C or Fortran memory layout.
603
604        C-contiguous memory has 'direct' as the access spec, 'contig' as the
605        *last* axis' packing spec and 'follow' for all other packing specs.
606
607        Fortran-contiguous memory has 'direct' as the access spec, 'contig' as
608        the *first* axis' packing spec and 'follow' for all other packing
609        specs.
610        """
611        from . import Buffer, MemoryView
612
613        self.dtype = base_dtype
614        self.axes = axes
615        self.ndim = len(axes)
616        self.flags = MemoryView.get_buf_flags(self.axes)
617
618        self.is_c_contig, self.is_f_contig = MemoryView.is_cf_contig(self.axes)
619        assert not (self.is_c_contig and self.is_f_contig)
620
621        self.mode = MemoryView.get_mode(axes)
622        self.writable_needed = False
623
624        if not self.dtype.is_fused:
625            self.dtype_name = Buffer.mangle_dtype_name(self.dtype)
626
627    def __hash__(self):
628        return hash(self.__class__) ^ hash(self.dtype) ^ hash(tuple(self.axes))
629
630    def __eq__(self, other):
631        if isinstance(other, BaseType):
632            return self.same_as_resolved_type(other)
633        else:
634            return False
635
636    def same_as_resolved_type(self, other_type):
637        return ((other_type.is_memoryviewslice and
638            #self.writable_needed == other_type.writable_needed and  # FIXME: should be only uni-directional
639            self.dtype.same_as(other_type.dtype) and
640            self.axes == other_type.axes) or
641            other_type is error_type)
642
643    def needs_nonecheck(self):
644        return True
645
646    def is_complete(self):
647        # incomplete since the underlying struct doesn't have a cython.memoryview object.
648        return 0
649
650    def declaration_code(self, entity_code,
651            for_display = 0, dll_linkage = None, pyrex = 0):
652        # XXX: we put these guards in for now...
653        assert not pyrex
654        assert not dll_linkage
655        from . import MemoryView
656        base_code = str(self) if for_display else MemoryView.memviewslice_cname
657        return self.base_declaration_code(
658                base_code,
659                entity_code)
660
661    def attributes_known(self):
662        if self.scope is None:
663            from . import Symtab
664
665            self.scope = scope = Symtab.CClassScope(
666                    'mvs_class_'+self.specialization_suffix(),
667                    None,
668                    visibility='extern')
669
670            scope.parent_type = self
671            scope.directives = {}
672
673            scope.declare_var('_data', c_char_ptr_type, None,
674                              cname='data', is_cdef=1)
675
676        return True
677
678    def declare_attribute(self, attribute, env, pos):
679        from . import MemoryView, Options
680
681        scope = self.scope
682
683        if attribute == 'shape':
684            scope.declare_var('shape',
685                    c_array_type(c_py_ssize_t_type,
686                                 Options.buffer_max_dims),
687                    pos,
688                    cname='shape',
689                    is_cdef=1)
690
691        elif attribute == 'strides':
692            scope.declare_var('strides',
693                    c_array_type(c_py_ssize_t_type,
694                                 Options.buffer_max_dims),
695                    pos,
696                    cname='strides',
697                    is_cdef=1)
698
699        elif attribute == 'suboffsets':
700            scope.declare_var('suboffsets',
701                    c_array_type(c_py_ssize_t_type,
702                                 Options.buffer_max_dims),
703                    pos,
704                    cname='suboffsets',
705                    is_cdef=1)
706
707        elif attribute in ("copy", "copy_fortran"):
708            ndim = len(self.axes)
709
710            follow_dim = [('direct', 'follow')]
711            contig_dim = [('direct', 'contig')]
712            to_axes_c = follow_dim * (ndim - 1) + contig_dim
713            to_axes_f = contig_dim + follow_dim * (ndim -1)
714
715            dtype = self.dtype
716            if dtype.is_const:
717                dtype = dtype.const_base_type
718
719            to_memview_c = MemoryViewSliceType(dtype, to_axes_c)
720            to_memview_f = MemoryViewSliceType(dtype, to_axes_f)
721
722            for to_memview, cython_name in [(to_memview_c, "copy"),
723                                            (to_memview_f, "copy_fortran")]:
724                copy_func_type = CFuncType(
725                    to_memview,
726                    [CFuncTypeArg("memviewslice", self, None)])
727                copy_cname = MemoryView.copy_c_or_fortran_cname(to_memview)
728
729                entry = scope.declare_cfunction(
730                    cython_name,
731                    copy_func_type, pos=pos, defining=1,
732                    cname=copy_cname)
733
734                utility = MemoryView.get_copy_new_utility(pos, self, to_memview)
735                env.use_utility_code(utility)
736
737            MemoryView.use_cython_array_utility_code(env)
738
739        elif attribute in ("is_c_contig", "is_f_contig"):
740            # is_c_contig and is_f_contig functions
741            for (c_or_f, cython_name) in (('C', 'is_c_contig'), ('F', 'is_f_contig')):
742
743                is_contig_name = MemoryView.get_is_contig_func_name(c_or_f, self.ndim)
744
745                cfunctype = CFuncType(
746                        return_type=c_bint_type,
747                        args=[CFuncTypeArg("memviewslice", self, None)],
748                        exception_value="-1",
749                )
750
751                entry = scope.declare_cfunction(cython_name,
752                            cfunctype,
753                            pos=pos,
754                            defining=1,
755                            cname=is_contig_name)
756
757                entry.utility_code_definition = MemoryView.get_is_contig_utility(c_or_f, self.ndim)
758
759        return True
760
761    def get_entry(self, node, cname=None, type=None):
762        from . import MemoryView, Symtab
763
764        if cname is None:
765            assert node.is_simple() or node.is_temp or node.is_elemental
766            cname = node.result()
767
768        if type is None:
769            type = node.type
770
771        entry = Symtab.Entry(cname, cname, type, node.pos)
772        return MemoryView.MemoryViewSliceBufferEntry(entry)
773
774    def conforms_to(self, dst, broadcast=False, copying=False):
775        """
776        Returns True if src conforms to dst, False otherwise.
777
778        If conformable, the types are the same, the ndims are equal, and each axis spec is conformable.
779
780        Any packing/access spec is conformable to itself.
781
782        'direct' and 'ptr' are conformable to 'full'.
783        'contig' and 'follow' are conformable to 'strided'.
784        Any other combo is not conformable.
785        """
786        from . import MemoryView
787
788        src = self
789
790        #if not copying and self.writable_needed and not dst.writable_needed:
791        #    return False
792
793        src_dtype, dst_dtype = src.dtype, dst.dtype
794        if dst_dtype.is_const:
795            # Requesting read-only views is always ok => consider only the non-const base type.
796            dst_dtype = dst_dtype.const_base_type
797            if src_dtype.is_const:
798                # When assigning between read-only views, compare only the non-const base types.
799                src_dtype = src_dtype.const_base_type
800        elif copying and src_dtype.is_const:
801            # Copying by value => ignore const on source.
802            src_dtype = src_dtype.const_base_type
803
804        if src_dtype != dst_dtype:
805            return False
806
807        if src.ndim != dst.ndim:
808            if broadcast:
809                src, dst = MemoryView.broadcast_types(src, dst)
810            else:
811                return False
812
813        for src_spec, dst_spec in zip(src.axes, dst.axes):
814            src_access, src_packing = src_spec
815            dst_access, dst_packing = dst_spec
816            if src_access != dst_access and dst_access != 'full':
817                return False
818            if src_packing != dst_packing and dst_packing != 'strided' and not copying:
819                return False
820
821        return True
822
823    def valid_dtype(self, dtype, i=0):
824        """
825        Return whether type dtype can be used as the base type of a
826        memoryview slice.
827
828        We support structs, numeric types and objects
829        """
830        if dtype.is_complex and dtype.real_type.is_int:
831            return False
832
833        if dtype.is_struct and dtype.kind == 'struct':
834            for member in dtype.scope.var_entries:
835                if not self.valid_dtype(member.type):
836                    return False
837
838            return True
839
840        return (
841            dtype.is_error or
842            # Pointers are not valid (yet)
843            # (dtype.is_ptr and valid_memslice_dtype(dtype.base_type)) or
844            (dtype.is_array and i < 8 and self.valid_dtype(dtype.base_type, i + 1)) or
845            dtype.is_numeric or
846            dtype.is_pyobject or
847            dtype.is_fused or  # accept this as it will be replaced by specializations later
848            (dtype.is_typedef and self.valid_dtype(dtype.typedef_base_type))
849        )
850
851    def validate_memslice_dtype(self, pos):
852        if not self.valid_dtype(self.dtype):
853            error(pos, "Invalid base type for memoryview slice: %s" % self.dtype)
854
855    def assert_direct_dims(self, pos):
856        for access, packing in self.axes:
857            if access != 'direct':
858                error(pos, "All dimensions must be direct")
859                return False
860        return True
861
862    def transpose(self, pos):
863        if not self.assert_direct_dims(pos):
864            return error_type
865        return MemoryViewSliceType(self.dtype, self.axes[::-1])
866
867    def specialization_name(self):
868        return '%s_%s' % (
869            super(MemoryViewSliceType,self).specialization_name(),
870            self.specialization_suffix())
871
872    def specialization_suffix(self):
873        return "%s_%s" % (self.axes_to_name(), self.dtype_name)
874
875    def can_coerce_to_pyobject(self, env):
876        return True
877
878    def can_coerce_from_pyobject(self, env):
879        return True
880
881    def check_for_null_code(self, cname):
882        return cname + '.memview'
883
884    def create_from_py_utility_code(self, env):
885        from . import MemoryView, Buffer
886
887        # We don't have 'code', so use a LazyUtilityCode with a callback.
888        def lazy_utility_callback(code):
889            context['dtype_typeinfo'] = Buffer.get_type_information_cname(code, self.dtype)
890            return TempitaUtilityCode.load(
891                "ObjectToMemviewSlice", "MemoryView_C.c", context=context)
892
893        env.use_utility_code(MemoryView.memviewslice_init_code)
894        env.use_utility_code(LazyUtilityCode(lazy_utility_callback))
895
896        if self.is_c_contig:
897            c_or_f_flag = "__Pyx_IS_C_CONTIG"
898        elif self.is_f_contig:
899            c_or_f_flag = "__Pyx_IS_F_CONTIG"
900        else:
901            c_or_f_flag = "0"
902
903        suffix = self.specialization_suffix()
904        funcname = "__Pyx_PyObject_to_MemoryviewSlice_" + suffix
905
906        context = dict(
907            MemoryView.context,
908            buf_flag = self.flags,
909            ndim = self.ndim,
910            axes_specs = ', '.join(self.axes_to_code()),
911            dtype_typedecl = self.dtype.empty_declaration_code(),
912            struct_nesting_depth = self.dtype.struct_nesting_depth(),
913            c_or_f_flag = c_or_f_flag,
914            funcname = funcname,
915        )
916
917        self.from_py_function = funcname
918        return True
919
920    def from_py_call_code(self, source_code, result_code, error_pos, code,
921                          from_py_function=None, error_condition=None):
922        # NOTE: auto-detection of readonly buffers is disabled:
923        # writable = self.writable_needed or not self.dtype.is_const
924        writable = not self.dtype.is_const
925        return self._assign_from_py_code(
926            source_code, result_code, error_pos, code, from_py_function, error_condition,
927            extra_args=['PyBUF_WRITABLE' if writable else '0'])
928
929    def create_to_py_utility_code(self, env):
930        self._dtype_to_py_func, self._dtype_from_py_func = self.dtype_object_conversion_funcs(env)
931        return True
932
933    def to_py_call_code(self, source_code, result_code, result_type, to_py_function=None):
934        assert self._dtype_to_py_func
935        assert self._dtype_from_py_func
936
937        to_py_func = "(PyObject *(*)(char *)) " + self._dtype_to_py_func
938        from_py_func = "(int (*)(char *, PyObject *)) " + self._dtype_from_py_func
939
940        tup = (result_code, source_code, self.ndim, to_py_func, from_py_func, self.dtype.is_pyobject)
941        return "%s = __pyx_memoryview_fromslice(%s, %s, %s, %s, %d);" % tup
942
943    def dtype_object_conversion_funcs(self, env):
944        get_function = "__pyx_memview_get_%s" % self.dtype_name
945        set_function = "__pyx_memview_set_%s" % self.dtype_name
946
947        context = dict(
948            get_function = get_function,
949            set_function = set_function,
950        )
951
952        if self.dtype.is_pyobject:
953            utility_name = "MemviewObjectToObject"
954        else:
955            self.dtype.create_to_py_utility_code(env)
956            to_py_function = self.dtype.to_py_function
957
958            from_py_function = None
959            if not self.dtype.is_const:
960                self.dtype.create_from_py_utility_code(env)
961                from_py_function = self.dtype.from_py_function
962
963            if not (to_py_function or from_py_function):
964                return "NULL", "NULL"
965            if not to_py_function:
966                get_function = "NULL"
967            if not from_py_function:
968                set_function = "NULL"
969
970            utility_name = "MemviewDtypeToObject"
971            error_condition = (self.dtype.error_condition('value') or
972                               'PyErr_Occurred()')
973            context.update(
974                to_py_function=to_py_function,
975                from_py_function=from_py_function,
976                dtype=self.dtype.empty_declaration_code(),
977                error_condition=error_condition,
978            )
979
980        utility = TempitaUtilityCode.load_cached(
981            utility_name, "MemoryView_C.c", context=context)
982        env.use_utility_code(utility)
983        return get_function, set_function
984
985    def axes_to_code(self):
986        """Return a list of code constants for each axis"""
987        from . import MemoryView
988        d = MemoryView._spec_to_const
989        return ["(%s | %s)" % (d[a], d[p]) for a, p in self.axes]
990
991    def axes_to_name(self):
992        """Return an abbreviated name for our axes"""
993        from . import MemoryView
994        d = MemoryView._spec_to_abbrev
995        return "".join(["%s%s" % (d[a], d[p]) for a, p in self.axes])
996
997    def error_condition(self, result_code):
998        return "!%s.memview" % result_code
999
1000    def __str__(self):
1001        from . import MemoryView
1002
1003        axes_code_list = []
1004        for idx, (access, packing) in enumerate(self.axes):
1005            flag = MemoryView.get_memoryview_flag(access, packing)
1006            if flag == "strided":
1007                axes_code_list.append(":")
1008            else:
1009                if flag == 'contiguous':
1010                    have_follow = [p for a, p in self.axes[idx - 1:idx + 2]
1011                                         if p == 'follow']
1012                    if have_follow or self.ndim == 1:
1013                        flag = '1'
1014
1015                axes_code_list.append("::" + flag)
1016
1017        if self.dtype.is_pyobject:
1018            dtype_name = self.dtype.name
1019        else:
1020            dtype_name = self.dtype
1021
1022        return "%s[%s]" % (dtype_name, ", ".join(axes_code_list))
1023
1024    def specialize(self, values):
1025        """This does not validate the base type!!"""
1026        dtype = self.dtype.specialize(values)
1027        if dtype is not self.dtype:
1028            return MemoryViewSliceType(dtype, self.axes)
1029
1030        return self
1031
1032    def cast_code(self, expr_code):
1033        return expr_code
1034
1035
1036class BufferType(BaseType):
1037    #
1038    #  Delegates most attribute lookups to the base type.
1039    #  (Anything not defined here or in the BaseType is delegated.)
1040    #
1041    # dtype            PyrexType
1042    # ndim             int
1043    # mode             str
1044    # negative_indices bool
1045    # cast             bool
1046    # is_buffer        bool
1047    # writable         bool
1048
1049    is_buffer = 1
1050    writable = True
1051
1052    subtypes = ['dtype']
1053
1054    def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
1055        self.base = base
1056        self.dtype = dtype
1057        self.ndim = ndim
1058        self.buffer_ptr_type = CPtrType(dtype)
1059        self.mode = mode
1060        self.negative_indices = negative_indices
1061        self.cast = cast
1062        self.is_numpy_buffer = self.base.name == "ndarray"
1063
1064    def can_coerce_to_pyobject(self,env):
1065        return True
1066
1067    def can_coerce_from_pyobject(self,env):
1068        return True
1069
1070    def as_argument_type(self):
1071        return self
1072
1073    def specialize(self, values):
1074        dtype = self.dtype.specialize(values)
1075        if dtype is not self.dtype:
1076            return BufferType(self.base, dtype, self.ndim, self.mode,
1077                              self.negative_indices, self.cast)
1078        return self
1079
1080    def get_entry(self, node):
1081        from . import Buffer
1082        assert node.is_name
1083        return Buffer.BufferEntry(node.entry)
1084
1085    def __getattr__(self, name):
1086        return getattr(self.base, name)
1087
1088    def __repr__(self):
1089        return "<BufferType %r>" % self.base
1090
1091    def __str__(self):
1092        # avoid ', ', as fused functions split the signature string on ', '
1093        cast_str = ''
1094        if self.cast:
1095            cast_str = ',cast=True'
1096
1097        return "%s[%s,ndim=%d%s]" % (self.base, self.dtype, self.ndim,
1098                                      cast_str)
1099
1100    def assignable_from(self, other_type):
1101        if other_type.is_buffer:
1102            return (self.same_as(other_type, compare_base=False) and
1103                    self.base.assignable_from(other_type.base))
1104
1105        return self.base.assignable_from(other_type)
1106
1107    def same_as(self, other_type, compare_base=True):
1108        if not other_type.is_buffer:
1109            return other_type.same_as(self.base)
1110
1111        return (self.dtype.same_as(other_type.dtype) and
1112                self.ndim == other_type.ndim and
1113                self.mode == other_type.mode and
1114                self.cast == other_type.cast and
1115                (not compare_base or self.base.same_as(other_type.base)))
1116
1117
1118class PyObjectType(PyrexType):
1119    #
1120    #  Base class for all Python object types (reference-counted).
1121    #
1122    #  buffer_defaults  dict or None     Default options for bu
1123
1124    name = "object"
1125    is_pyobject = 1
1126    default_value = "0"
1127    declaration_value = "0"
1128    buffer_defaults = None
1129    is_extern = False
1130    is_subclassed = False
1131    is_gc_simple = False
1132
1133    def __str__(self):
1134        return "Python object"
1135
1136    def __repr__(self):
1137        return "<PyObjectType>"
1138
1139    def can_coerce_to_pyobject(self, env):
1140        return True
1141
1142    def can_coerce_from_pyobject(self, env):
1143        return True
1144
1145    def default_coerced_ctype(self):
1146        """The default C type that this Python type coerces to, or None."""
1147        return None
1148
1149    def assignable_from(self, src_type):
1150        # except for pointers, conversion will be attempted
1151        return not src_type.is_ptr or src_type.is_string or src_type.is_pyunicode_ptr
1152
1153    def declaration_code(self, entity_code,
1154            for_display = 0, dll_linkage = None, pyrex = 0):
1155        if pyrex or for_display:
1156            base_code = "object"
1157        else:
1158            base_code = public_decl("PyObject", dll_linkage)
1159            entity_code = "*%s" % entity_code
1160        return self.base_declaration_code(base_code, entity_code)
1161
1162    def as_pyobject(self, cname):
1163        if (not self.is_complete()) or self.is_extension_type:
1164            return "(PyObject *)" + cname
1165        else:
1166            return cname
1167
1168    def py_type_name(self):
1169        return "object"
1170
1171    def __lt__(self, other):
1172        """
1173        Make sure we sort highest, as instance checking on py_type_name
1174        ('object') is always true
1175        """
1176        return False
1177
1178    def global_init_code(self, entry, code):
1179        code.put_init_var_to_py_none(entry, nanny=False)
1180
1181    def check_for_null_code(self, cname):
1182        return cname
1183
1184
1185builtin_types_that_cannot_create_refcycles = set([
1186    'bool', 'int', 'long', 'float', 'complex',
1187    'bytearray', 'bytes', 'unicode', 'str', 'basestring'
1188])
1189
1190
1191class BuiltinObjectType(PyObjectType):
1192    #  objstruct_cname  string           Name of PyObject struct
1193
1194    is_builtin_type = 1
1195    has_attributes = 1
1196    base_type = None
1197    module_name = '__builtin__'
1198    require_exact = 1
1199
1200    # fields that let it look like an extension type
1201    vtabslot_cname = None
1202    vtabstruct_cname = None
1203    vtabptr_cname = None
1204    typedef_flag = True
1205    is_external = True
1206    decl_type = 'PyObject'
1207
1208    def __init__(self, name, cname, objstruct_cname=None):
1209        self.name = name
1210        self.cname = cname
1211        self.typeptr_cname = "(&%s)" % cname
1212        self.objstruct_cname = objstruct_cname
1213        self.is_gc_simple = name in builtin_types_that_cannot_create_refcycles
1214        if name == 'type':
1215            # Special case the type type, as many C API calls (and other
1216            # libraries) actually expect a PyTypeObject* for type arguments.
1217            self.decl_type = objstruct_cname
1218        if name == 'Exception':
1219            self.require_exact = 0
1220
1221    def set_scope(self, scope):
1222        self.scope = scope
1223        if scope:
1224            scope.parent_type = self
1225
1226    def __str__(self):
1227        return "%s object" % self.name
1228
1229    def __repr__(self):
1230        return "<%s>"% self.cname
1231
1232    def default_coerced_ctype(self):
1233        if self.name in ('bytes', 'bytearray'):
1234            return c_char_ptr_type
1235        elif self.name == 'bool':
1236            return c_bint_type
1237        elif self.name == 'float':
1238            return c_double_type
1239        return None
1240
1241    def assignable_from(self, src_type):
1242        if isinstance(src_type, BuiltinObjectType):
1243            if self.name == 'basestring':
1244                return src_type.name in ('str', 'unicode', 'basestring')
1245            else:
1246                return src_type.name == self.name
1247        elif src_type.is_extension_type:
1248            # FIXME: This is an ugly special case that we currently
1249            # keep supporting.  It allows users to specify builtin
1250            # types as external extension types, while keeping them
1251            # compatible with the real builtin types.  We already
1252            # generate a warning for it.  Big TODO: remove!
1253            return (src_type.module_name == '__builtin__' and
1254                    src_type.name == self.name)
1255        else:
1256            return True
1257
1258    def typeobj_is_available(self):
1259        return True
1260
1261    def attributes_known(self):
1262        return True
1263
1264    def subtype_of(self, type):
1265        return type.is_pyobject and type.assignable_from(self)
1266
1267    def type_check_function(self, exact=True):
1268        type_name = self.name
1269        if type_name == 'str':
1270            type_check = 'PyString_Check'
1271        elif type_name == 'basestring':
1272            type_check = '__Pyx_PyBaseString_Check'
1273        elif type_name == 'Exception':
1274            type_check = '__Pyx_PyException_Check'
1275        elif type_name == 'bytearray':
1276            type_check = 'PyByteArray_Check'
1277        elif type_name == 'frozenset':
1278            type_check = 'PyFrozenSet_Check'
1279        else:
1280            type_check = 'Py%s_Check' % type_name.capitalize()
1281        if exact and type_name not in ('bool', 'slice', 'Exception'):
1282            type_check += 'Exact'
1283        return type_check
1284
1285    def isinstance_code(self, arg):
1286        return '%s(%s)' % (self.type_check_function(exact=False), arg)
1287
1288    def type_test_code(self, arg, notnone=False, exact=True):
1289        type_check = self.type_check_function(exact=exact)
1290        check = 'likely(%s(%s))' % (type_check, arg)
1291        if not notnone:
1292            check += '||((%s) == Py_None)' % arg
1293        if self.name == 'basestring':
1294            name = '(PY_MAJOR_VERSION < 3 ? "basestring" : "str")'
1295            space_for_name = 16
1296        else:
1297            name = '"%s"' % self.name
1298            # avoid wasting too much space but limit number of different format strings
1299            space_for_name = (len(self.name) // 16 + 1) * 16
1300        error = '(PyErr_Format(PyExc_TypeError, "Expected %%.%ds, got %%.200s", %s, Py_TYPE(%s)->tp_name), 0)' % (
1301            space_for_name, name, arg)
1302        return check + '||' + error
1303
1304    def declaration_code(self, entity_code,
1305            for_display = 0, dll_linkage = None, pyrex = 0):
1306        if pyrex or for_display:
1307            base_code = self.name
1308        else:
1309            base_code = public_decl(self.decl_type, dll_linkage)
1310            entity_code = "*%s" % entity_code
1311        return self.base_declaration_code(base_code, entity_code)
1312
1313    def as_pyobject(self, cname):
1314        if self.decl_type == 'PyObject':
1315            return cname
1316        else:
1317            return "(PyObject *)" + cname
1318
1319    def cast_code(self, expr_code, to_object_struct = False):
1320        return "((%s*)%s)" % (
1321            to_object_struct and self.objstruct_cname or self.decl_type, # self.objstruct_cname may be None
1322            expr_code)
1323
1324    def py_type_name(self):
1325        return self.name
1326
1327
1328
1329class PyExtensionType(PyObjectType):
1330    #
1331    #  A Python extension type.
1332    #
1333    #  name             string
1334    #  scope            CClassScope      Attribute namespace
1335    #  visibility       string
1336    #  typedef_flag     boolean
1337    #  base_type        PyExtensionType or None
1338    #  module_name      string or None   Qualified name of defining module
1339    #  objstruct_cname  string           Name of PyObject struct
1340    #  objtypedef_cname string           Name of PyObject struct typedef
1341    #  typeobj_cname    string or None   C code fragment referring to type object
1342    #  typeptr_cname    string or None   Name of pointer to external type object
1343    #  vtabslot_cname   string           Name of C method table member
1344    #  vtabstruct_cname string           Name of C method table struct
1345    #  vtabptr_cname    string           Name of pointer to C method table
1346    #  vtable_cname     string           Name of C method table definition
1347    #  early_init       boolean          Whether to initialize early (as opposed to during module execution).
1348    #  defered_declarations [thunk]      Used to declare class hierarchies in order
1349    #  check_size       'warn', 'error', 'ignore'    What to do if tp_basicsize does not match
1350
1351    is_extension_type = 1
1352    has_attributes = 1
1353    early_init = 1
1354
1355    objtypedef_cname = None
1356
1357    def __init__(self, name, typedef_flag, base_type, is_external=0, check_size=None):
1358        self.name = name
1359        self.scope = None
1360        self.typedef_flag = typedef_flag
1361        if base_type is not None:
1362            base_type.is_subclassed = True
1363        self.base_type = base_type
1364        self.module_name = None
1365        self.objstruct_cname = None
1366        self.typeobj_cname = None
1367        self.typeptr_cname = None
1368        self.vtabslot_cname = None
1369        self.vtabstruct_cname = None
1370        self.vtabptr_cname = None
1371        self.vtable_cname = None
1372        self.is_external = is_external
1373        self.check_size = check_size or 'warn'
1374        self.defered_declarations = []
1375
1376    def set_scope(self, scope):
1377        self.scope = scope
1378        if scope:
1379            scope.parent_type = self
1380
1381    def needs_nonecheck(self):
1382        return True
1383
1384    def subtype_of_resolved_type(self, other_type):
1385        if other_type.is_extension_type or other_type.is_builtin_type:
1386            return self is other_type or (
1387                self.base_type and self.base_type.subtype_of(other_type))
1388        else:
1389            return other_type is py_object_type
1390
1391    def typeobj_is_available(self):
1392        # Do we have a pointer to the type object?
1393        return self.typeptr_cname
1394
1395    def typeobj_is_imported(self):
1396        # If we don't know the C name of the type object but we do
1397        # know which module it's defined in, it will be imported.
1398        return self.typeobj_cname is None and self.module_name is not None
1399
1400    def assignable_from(self, src_type):
1401        if self == src_type:
1402            return True
1403        if isinstance(src_type, PyExtensionType):
1404            if src_type.base_type is not None:
1405                return self.assignable_from(src_type.base_type)
1406        if isinstance(src_type, BuiltinObjectType):
1407            # FIXME: This is an ugly special case that we currently
1408            # keep supporting.  It allows users to specify builtin
1409            # types as external extension types, while keeping them
1410            # compatible with the real builtin types.  We already
1411            # generate a warning for it.  Big TODO: remove!
1412            return (self.module_name == '__builtin__' and
1413                    self.name == src_type.name)
1414        return False
1415
1416    def declaration_code(self, entity_code,
1417            for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
1418        if pyrex or for_display:
1419            base_code = self.name
1420        else:
1421            if self.typedef_flag:
1422                objstruct = self.objstruct_cname
1423            else:
1424                objstruct = "struct %s" % self.objstruct_cname
1425            base_code = public_decl(objstruct, dll_linkage)
1426            if deref:
1427                assert not entity_code
1428            else:
1429                entity_code = "*%s" % entity_code
1430        return self.base_declaration_code(base_code, entity_code)
1431
1432    def type_test_code(self, py_arg, notnone=False):
1433
1434        none_check = "((%s) == Py_None)" % py_arg
1435        type_check = "likely(__Pyx_TypeTest(%s, %s))" % (
1436            py_arg, self.typeptr_cname)
1437        if notnone:
1438            return type_check
1439        else:
1440            return "likely(%s || %s)" % (none_check, type_check)
1441
1442    def attributes_known(self):
1443        return self.scope is not None
1444
1445    def __str__(self):
1446        return self.name
1447
1448    def __repr__(self):
1449        return "<PyExtensionType %s%s>" % (self.scope.class_name,
1450            ("", " typedef")[self.typedef_flag])
1451
1452    def py_type_name(self):
1453        if not self.module_name:
1454            return self.name
1455
1456        return "__import__(%r, None, None, ['']).%s" % (self.module_name,
1457                                                        self.name)
1458
1459class CType(PyrexType):
1460    #
1461    #  Base class for all C types (non-reference-counted).
1462    #
1463    #  to_py_function     string     C function for converting to Python object
1464    #  from_py_function   string     C function for constructing from Python object
1465    #
1466
1467    to_py_function = None
1468    from_py_function = None
1469    exception_value = None
1470    exception_check = 1
1471
1472    def create_to_py_utility_code(self, env):
1473        return self.to_py_function is not None
1474
1475    def create_from_py_utility_code(self, env):
1476        return self.from_py_function is not None
1477
1478    def can_coerce_to_pyobject(self, env):
1479        return self.create_to_py_utility_code(env)
1480
1481    def can_coerce_from_pyobject(self, env):
1482        return self.create_from_py_utility_code(env)
1483
1484    def error_condition(self, result_code):
1485        conds = []
1486        if self.is_string or self.is_pyunicode_ptr:
1487            conds.append("(!%s)" % result_code)
1488        elif self.exception_value is not None:
1489            conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
1490        if self.exception_check:
1491            conds.append("PyErr_Occurred()")
1492        if len(conds) > 0:
1493            return " && ".join(conds)
1494        else:
1495            return 0
1496
1497    def to_py_call_code(self, source_code, result_code, result_type, to_py_function=None):
1498        func = self.to_py_function if to_py_function is None else to_py_function
1499        assert func
1500        if self.is_string or self.is_cpp_string:
1501            if result_type.is_builtin_type:
1502                result_type_name = result_type.name
1503                if result_type_name in ('bytes', 'str', 'unicode'):
1504                    func = func.replace("Object", result_type_name.title(), 1)
1505                elif result_type_name == 'bytearray':
1506                    func = func.replace("Object", "ByteArray", 1)
1507        return '%s = %s(%s)' % (
1508            result_code,
1509            func,
1510            source_code or 'NULL')
1511
1512    def from_py_call_code(self, source_code, result_code, error_pos, code,
1513                          from_py_function=None, error_condition=None):
1514        return self._assign_from_py_code(
1515            source_code, result_code, error_pos, code, from_py_function, error_condition)
1516
1517
1518
1519class PythranExpr(CType):
1520    # Pythran object of a given type
1521
1522    to_py_function = "__Pyx_pythran_to_python"
1523    is_pythran_expr = True
1524    writable = True
1525    has_attributes = 1
1526
1527    def __init__(self, pythran_type, org_buffer=None):
1528        self.org_buffer = org_buffer
1529        self.pythran_type = pythran_type
1530        self.name = self.pythran_type
1531        self.cname = self.pythran_type
1532        self.from_py_function = "from_python<%s>" % (self.pythran_type)
1533        self.scope = None
1534
1535    def declaration_code(self, entity_code, for_display=0, dll_linkage=None, pyrex=0):
1536        assert not pyrex
1537        return "%s %s" % (self.cname, entity_code)
1538
1539    def attributes_known(self):
1540        if self.scope is None:
1541            from . import Symtab
1542            # FIXME: fake C scope, might be better represented by a struct or C++ class scope
1543            self.scope = scope = Symtab.CClassScope('', None, visibility="extern")
1544            scope.parent_type = self
1545            scope.directives = {}
1546            scope.declare_var("shape", CPtrType(c_long_type), None, cname="_shape", is_cdef=True)
1547            scope.declare_var("ndim", c_long_type, None, cname="value", is_cdef=True)
1548
1549        return True
1550
1551    def __eq__(self, other):
1552        return isinstance(other, PythranExpr) and self.pythran_type == other.pythran_type
1553
1554    def __ne__(self, other):
1555        return not (isinstance(other, PythranExpr) and self.pythran_type == other.pythran_type)
1556
1557    def __hash__(self):
1558        return hash(self.pythran_type)
1559
1560
1561class CConstType(BaseType):
1562
1563    is_const = 1
1564
1565    def __init__(self, const_base_type):
1566        self.const_base_type = const_base_type
1567        if const_base_type.has_attributes and const_base_type.scope is not None:
1568            from . import Symtab
1569            self.scope = Symtab.CConstScope(const_base_type.scope)
1570
1571    def __repr__(self):
1572        return "<CConstType %s>" % repr(self.const_base_type)
1573
1574    def __str__(self):
1575        return self.declaration_code("", for_display=1)
1576
1577    def declaration_code(self, entity_code,
1578            for_display = 0, dll_linkage = None, pyrex = 0):
1579        if for_display or pyrex:
1580            return "const " + self.const_base_type.declaration_code(entity_code, for_display, dll_linkage, pyrex)
1581        else:
1582            return self.const_base_type.declaration_code("const %s" % entity_code, for_display, dll_linkage, pyrex)
1583
1584    def specialize(self, values):
1585        base_type = self.const_base_type.specialize(values)
1586        if base_type == self.const_base_type:
1587            return self
1588        else:
1589            return CConstType(base_type)
1590
1591    def deduce_template_params(self, actual):
1592        return self.const_base_type.deduce_template_params(actual)
1593
1594    def can_coerce_to_pyobject(self, env):
1595        return self.const_base_type.can_coerce_to_pyobject(env)
1596
1597    def can_coerce_from_pyobject(self, env):
1598        return self.const_base_type.can_coerce_from_pyobject(env)
1599
1600    def create_to_py_utility_code(self, env):
1601        if self.const_base_type.create_to_py_utility_code(env):
1602            self.to_py_function = self.const_base_type.to_py_function
1603            return True
1604
1605    def same_as_resolved_type(self, other_type):
1606        if other_type.is_const:
1607            return self.const_base_type.same_as_resolved_type(other_type.const_base_type)
1608        # Accept const LHS <- non-const RHS.
1609        return self.const_base_type.same_as_resolved_type(other_type)
1610
1611    def __getattr__(self, name):
1612        return getattr(self.const_base_type, name)
1613
1614
1615class FusedType(CType):
1616    """
1617    Represents a Fused Type. All it needs to do is keep track of the types
1618    it aggregates, as it will be replaced with its specific version wherever
1619    needed.
1620
1621    See http://wiki.cython.org/enhancements/fusedtypes
1622
1623    types           [PyrexType]             is the list of types to be fused
1624    name            str                     the name of the ctypedef
1625    """
1626
1627    is_fused = 1
1628    exception_check = 0
1629
1630    def __init__(self, types, name=None):
1631        # Use list rather than set to preserve order (list should be short).
1632        flattened_types = []
1633        for t in types:
1634            if t.is_fused:
1635                # recursively merge in subtypes
1636                for subtype in t.types:
1637                    if subtype not in flattened_types:
1638                        flattened_types.append(subtype)
1639            elif t not in flattened_types:
1640                flattened_types.append(t)
1641        self.types = flattened_types
1642        self.name = name
1643
1644    def declaration_code(self, entity_code, for_display = 0,
1645                         dll_linkage = None, pyrex = 0):
1646        if pyrex or for_display:
1647            return self.name
1648
1649        raise Exception("This may never happen, please report a bug")
1650
1651    def __repr__(self):
1652        return 'FusedType(name=%r)' % self.name
1653
1654    def specialize(self, values):
1655        return values[self]
1656
1657    def get_fused_types(self, result=None, seen=None):
1658        if result is None:
1659            return [self]
1660
1661        if self not in seen:
1662            result.append(self)
1663            seen.add(self)
1664
1665
1666class CVoidType(CType):
1667    #
1668    #   C "void" type
1669    #
1670
1671    is_void = 1
1672    to_py_function = "__Pyx_void_to_None"
1673
1674    def __repr__(self):
1675        return "<CVoidType>"
1676
1677    def declaration_code(self, entity_code,
1678            for_display = 0, dll_linkage = None, pyrex = 0):
1679        if pyrex or for_display:
1680            base_code = "void"
1681        else:
1682            base_code = public_decl("void", dll_linkage)
1683        return self.base_declaration_code(base_code, entity_code)
1684
1685    def is_complete(self):
1686        return 0
1687
1688class InvisibleVoidType(CVoidType):
1689    #
1690    #   For use with C++ constructors and destructors return types.
1691    #   Acts like void, but does not print out a declaration.
1692    #
1693    def declaration_code(self, entity_code,
1694            for_display = 0, dll_linkage = None, pyrex = 0):
1695        if pyrex or for_display:
1696            base_code = "[void]"
1697        else:
1698            base_code = public_decl("", dll_linkage)
1699        return self.base_declaration_code(base_code, entity_code)
1700
1701
1702class CNumericType(CType):
1703    #
1704    #   Base class for all C numeric types.
1705    #
1706    #   rank      integer     Relative size
1707    #   signed    integer     0 = unsigned, 1 = unspecified, 2 = explicitly signed
1708    #
1709
1710    is_numeric = 1
1711    default_value = "0"
1712    has_attributes = True
1713    scope = None
1714
1715    sign_words = ("unsigned ", "", "signed ")
1716
1717    def __init__(self, rank, signed = 1):
1718        self.rank = rank
1719        if rank > 0 and signed == SIGNED:
1720            # Signed is meaningless for anything but char, and complicates
1721            # type promotion.
1722            signed = 1
1723        self.signed = signed
1724
1725    def sign_and_name(self):
1726        s = self.sign_words[self.signed]
1727        n = rank_to_type_name[self.rank]
1728        return s + n
1729
1730    def __repr__(self):
1731        return "<CNumericType %s>" % self.sign_and_name()
1732
1733    def declaration_code(self, entity_code,
1734            for_display = 0, dll_linkage = None, pyrex = 0):
1735        type_name = self.sign_and_name()
1736        if pyrex or for_display:
1737            base_code = type_name.replace('PY_LONG_LONG', 'long long')
1738        else:
1739            base_code = public_decl(type_name, dll_linkage)
1740        return self.base_declaration_code(base_code, entity_code)
1741
1742    def attributes_known(self):
1743        if self.scope is None:
1744            from . import Symtab
1745            self.scope = scope = Symtab.CClassScope(
1746                    '',
1747                    None,
1748                    visibility="extern")
1749            scope.parent_type = self
1750            scope.directives = {}
1751            scope.declare_cfunction(
1752                    "conjugate",
1753                    CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True),
1754                    pos=None,
1755                    defining=1,
1756                    cname=" ")
1757        return True
1758
1759    def __lt__(self, other):
1760        """Sort based on rank, preferring signed over unsigned"""
1761        if other.is_numeric:
1762            return self.rank > other.rank and self.signed >= other.signed
1763
1764        # Prefer numeric types over others
1765        return True
1766
1767    def py_type_name(self):
1768        if self.rank <= 4:
1769            return "(int, long)"
1770        return "float"
1771
1772
1773class ForbidUseClass:
1774    def __repr__(self):
1775        raise RuntimeError()
1776    def __str__(self):
1777        raise RuntimeError()
1778ForbidUse = ForbidUseClass()
1779
1780
1781class CIntLike(object):
1782    """Mixin for shared behaviour of C integers and enums.
1783    """
1784    to_py_function = None
1785    from_py_function = None
1786    to_pyunicode_utility = None
1787    default_format_spec = 'd'
1788
1789    def can_coerce_to_pyobject(self, env):
1790        return True
1791
1792    def can_coerce_from_pyobject(self, env):
1793        return True
1794
1795    def create_to_py_utility_code(self, env):
1796        if type(self).to_py_function is None:
1797            self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name()
1798            env.use_utility_code(TempitaUtilityCode.load_cached(
1799                "CIntToPy", "TypeConversion.c",
1800                context={"TYPE": self.empty_declaration_code(),
1801                         "TO_PY_FUNCTION": self.to_py_function}))
1802        return True
1803
1804    def create_from_py_utility_code(self, env):
1805        if type(self).from_py_function is None:
1806            self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name()
1807            env.use_utility_code(TempitaUtilityCode.load_cached(
1808                "CIntFromPy", "TypeConversion.c",
1809                context={"TYPE": self.empty_declaration_code(),
1810                         "FROM_PY_FUNCTION": self.from_py_function}))
1811        return True
1812
1813    @staticmethod
1814    def _parse_format(format_spec):
1815        padding = ' '
1816        if not format_spec:
1817            return ('d', 0, padding)
1818        format_type = format_spec[-1]
1819        if format_type in ('o', 'd', 'x', 'X'):
1820            prefix = format_spec[:-1]
1821        elif format_type.isdigit():
1822            format_type = 'd'
1823            prefix = format_spec
1824        else:
1825            return (None, 0, padding)
1826        if not prefix:
1827            return (format_type, 0, padding)
1828        if prefix[0] == '-':
1829            prefix = prefix[1:]
1830        if prefix and prefix[0] == '0':
1831            padding = '0'
1832            prefix = prefix.lstrip('0')
1833        if prefix.isdigit():
1834            return (format_type, int(prefix), padding)
1835        return (None, 0, padding)
1836
1837    def can_coerce_to_pystring(self, env, format_spec=None):
1838        format_type, width, padding = self._parse_format(format_spec)
1839        return format_type is not None and width <= 2**30
1840
1841    def convert_to_pystring(self, cvalue, code, format_spec=None):
1842        if self.to_pyunicode_utility is None:
1843            utility_code_name = "__Pyx_PyUnicode_From_" + self.specialization_name()
1844            to_pyunicode_utility = TempitaUtilityCode.load_cached(
1845                "CIntToPyUnicode", "TypeConversion.c",
1846                context={"TYPE": self.empty_declaration_code(),
1847                         "TO_PY_FUNCTION": utility_code_name})
1848            self.to_pyunicode_utility = (utility_code_name, to_pyunicode_utility)
1849        else:
1850            utility_code_name, to_pyunicode_utility = self.to_pyunicode_utility
1851        code.globalstate.use_utility_code(to_pyunicode_utility)
1852        format_type, width, padding_char = self._parse_format(format_spec)
1853        return "%s(%s, %d, '%s', '%s')" % (utility_code_name, cvalue, width, padding_char, format_type)
1854
1855
1856class CIntType(CIntLike, CNumericType):
1857
1858    is_int = 1
1859    typedef_flag = 0
1860    exception_value = -1
1861
1862    def get_to_py_type_conversion(self):
1863        if self.rank < list(rank_to_type_name).index('int'):
1864            # This assumes sizeof(short) < sizeof(int)
1865            return "PyInt_FromLong"
1866        else:
1867            # Py{Int|Long}_From[Unsigned]Long[Long]
1868            Prefix = "Int"
1869            SignWord = ""
1870            TypeName = "Long"
1871            if not self.signed:
1872                Prefix = "Long"
1873                SignWord = "Unsigned"
1874            if self.rank >= list(rank_to_type_name).index('PY_LONG_LONG'):
1875                Prefix = "Long"
1876                TypeName = "LongLong"
1877            return "Py%s_From%s%s" % (Prefix, SignWord, TypeName)
1878
1879    def assignable_from_resolved_type(self, src_type):
1880        return src_type.is_int or src_type.is_enum or src_type is error_type
1881
1882    def invalid_value(self):
1883        if rank_to_type_name[int(self.rank)] == 'char':
1884            return "'?'"
1885        else:
1886            # We do not really know the size of the type, so return
1887            # a 32-bit literal and rely on casting to final type. It will
1888            # be negative for signed ints, which is good.
1889            return "0xbad0bad0"
1890
1891    def overflow_check_binop(self, binop, env, const_rhs=False):
1892        env.use_utility_code(UtilityCode.load("Common", "Overflow.c"))
1893        type = self.empty_declaration_code()
1894        name = self.specialization_name()
1895        if binop == "lshift":
1896            env.use_utility_code(TempitaUtilityCode.load_cached(
1897                "LeftShift", "Overflow.c",
1898                context={'TYPE': type, 'NAME': name, 'SIGNED': self.signed}))
1899        else:
1900            if const_rhs:
1901                binop += "_const"
1902            if type in ('int', 'long', 'long long'):
1903                env.use_utility_code(TempitaUtilityCode.load_cached(
1904                    "BaseCaseSigned", "Overflow.c",
1905                    context={'INT': type, 'NAME': name}))
1906            elif type in ('unsigned int', 'unsigned long', 'unsigned long long'):
1907                env.use_utility_code(TempitaUtilityCode.load_cached(
1908                    "BaseCaseUnsigned", "Overflow.c",
1909                    context={'UINT': type, 'NAME': name}))
1910            elif self.rank <= 1:
1911                # sizeof(short) < sizeof(int)
1912                return "__Pyx_%s_%s_no_overflow" % (binop, name)
1913            else:
1914                _load_overflow_base(env)
1915                env.use_utility_code(TempitaUtilityCode.load_cached(
1916                    "SizeCheck", "Overflow.c",
1917                    context={'TYPE': type, 'NAME': name}))
1918                env.use_utility_code(TempitaUtilityCode.load_cached(
1919                    "Binop", "Overflow.c",
1920                    context={'TYPE': type, 'NAME': name, 'BINOP': binop}))
1921        return "__Pyx_%s_%s_checking_overflow" % (binop, name)
1922
1923
1924def _load_overflow_base(env):
1925    env.use_utility_code(UtilityCode.load("Common", "Overflow.c"))
1926    for type in ('int', 'long', 'long long'):
1927        env.use_utility_code(TempitaUtilityCode.load_cached(
1928            "BaseCaseSigned", "Overflow.c",
1929            context={'INT': type, 'NAME': type.replace(' ', '_')}))
1930    for type in ('unsigned int', 'unsigned long', 'unsigned long long'):
1931        env.use_utility_code(TempitaUtilityCode.load_cached(
1932            "BaseCaseUnsigned", "Overflow.c",
1933            context={'UINT': type, 'NAME': type.replace(' ', '_')}))
1934
1935
1936class CAnonEnumType(CIntType):
1937
1938    is_enum = 1
1939
1940    def sign_and_name(self):
1941        return 'int'
1942
1943
1944class CReturnCodeType(CIntType):
1945
1946    to_py_function = "__Pyx_Owned_Py_None"
1947
1948    is_returncode = True
1949    exception_check = False
1950    default_format_spec = ''
1951
1952    def can_coerce_to_pystring(self, env, format_spec=None):
1953        return not format_spec
1954
1955    def convert_to_pystring(self, cvalue, code, format_spec=None):
1956        return "__Pyx_NewRef(%s)" % code.globalstate.get_py_string_const(StringEncoding.EncodedString("None")).cname
1957
1958
1959class CBIntType(CIntType):
1960
1961    to_py_function = "__Pyx_PyBool_FromLong"
1962    from_py_function = "__Pyx_PyObject_IsTrue"
1963    exception_check = 1  # for C++ bool
1964    default_format_spec = ''
1965
1966    def can_coerce_to_pystring(self, env, format_spec=None):
1967        return not format_spec or super(CBIntType, self).can_coerce_to_pystring(env, format_spec)
1968
1969    def convert_to_pystring(self, cvalue, code, format_spec=None):
1970        if format_spec:
1971            return super(CBIntType, self).convert_to_pystring(cvalue, code, format_spec)
1972        # NOTE: no caching here as the string constant cnames depend on the current module
1973        utility_code_name = "__Pyx_PyUnicode_FromBInt_" + self.specialization_name()
1974        to_pyunicode_utility = TempitaUtilityCode.load_cached(
1975            "CBIntToPyUnicode", "TypeConversion.c", context={
1976                "TRUE_CONST":  code.globalstate.get_py_string_const(StringEncoding.EncodedString("True")).cname,
1977                "FALSE_CONST": code.globalstate.get_py_string_const(StringEncoding.EncodedString("False")).cname,
1978                "TO_PY_FUNCTION": utility_code_name,
1979            })
1980        code.globalstate.use_utility_code(to_pyunicode_utility)
1981        return "%s(%s)" % (utility_code_name, cvalue)
1982
1983    def declaration_code(self, entity_code,
1984            for_display = 0, dll_linkage = None, pyrex = 0):
1985        if for_display:
1986            base_code = 'bool'
1987        elif pyrex:
1988            base_code = 'bint'
1989        else:
1990            base_code = public_decl('int', dll_linkage)
1991        return self.base_declaration_code(base_code, entity_code)
1992
1993    def __repr__(self):
1994        return "<CNumericType bint>"
1995
1996    def __str__(self):
1997        return 'bint'
1998
1999    def py_type_name(self):
2000        return "bool"
2001
2002
2003class CPyUCS4IntType(CIntType):
2004    # Py_UCS4
2005
2006    is_unicode_char = True
2007
2008    # Py_UCS4 coerces from and to single character unicode strings (or
2009    # at most two characters on 16bit Unicode builds), but we also
2010    # allow Python integers as input.  The value range for Py_UCS4
2011    # is 0..1114111, which is checked when converting from an integer
2012    # value.
2013
2014    to_py_function = "PyUnicode_FromOrdinal"
2015    from_py_function = "__Pyx_PyObject_AsPy_UCS4"
2016
2017    def can_coerce_to_pystring(self, env, format_spec=None):
2018        return False  # does the right thing anyway
2019
2020    def create_from_py_utility_code(self, env):
2021        env.use_utility_code(UtilityCode.load_cached("ObjectAsUCS4", "TypeConversion.c"))
2022        return True
2023
2024    def sign_and_name(self):
2025        return "Py_UCS4"
2026
2027
2028class CPyUnicodeIntType(CIntType):
2029    # Py_UNICODE
2030
2031    is_unicode_char = True
2032
2033    # Py_UNICODE coerces from and to single character unicode strings,
2034    # but we also allow Python integers as input.  The value range for
2035    # Py_UNICODE is 0..1114111, which is checked when converting from
2036    # an integer value.
2037
2038    to_py_function = "PyUnicode_FromOrdinal"
2039    from_py_function = "__Pyx_PyObject_AsPy_UNICODE"
2040
2041    def can_coerce_to_pystring(self, env, format_spec=None):
2042        return False  # does the right thing anyway
2043
2044    def create_from_py_utility_code(self, env):
2045        env.use_utility_code(UtilityCode.load_cached("ObjectAsPyUnicode", "TypeConversion.c"))
2046        return True
2047
2048    def sign_and_name(self):
2049        return "Py_UNICODE"
2050
2051
2052class CPyHashTType(CIntType):
2053
2054    to_py_function = "__Pyx_PyInt_FromHash_t"
2055    from_py_function = "__Pyx_PyInt_AsHash_t"
2056
2057    def sign_and_name(self):
2058        return "Py_hash_t"
2059
2060class CPySSizeTType(CIntType):
2061
2062    to_py_function = "PyInt_FromSsize_t"
2063    from_py_function = "__Pyx_PyIndex_AsSsize_t"
2064
2065    def sign_and_name(self):
2066        return "Py_ssize_t"
2067
2068class CSSizeTType(CIntType):
2069
2070    to_py_function = "PyInt_FromSsize_t"
2071    from_py_function = "PyInt_AsSsize_t"
2072
2073    def sign_and_name(self):
2074        return "Py_ssize_t"
2075
2076class CSizeTType(CIntType):
2077
2078    to_py_function = "__Pyx_PyInt_FromSize_t"
2079
2080    def sign_and_name(self):
2081        return "size_t"
2082
2083class CPtrdiffTType(CIntType):
2084
2085    def sign_and_name(self):
2086        return "ptrdiff_t"
2087
2088
2089class CFloatType(CNumericType):
2090
2091    is_float = 1
2092    to_py_function = "PyFloat_FromDouble"
2093    from_py_function = "__pyx_PyFloat_AsDouble"
2094
2095    exception_value = -1
2096
2097    def __init__(self, rank, math_h_modifier = ''):
2098        CNumericType.__init__(self, rank, 1)
2099        self.math_h_modifier = math_h_modifier
2100        if rank == RANK_FLOAT:
2101            self.from_py_function = "__pyx_PyFloat_AsFloat"
2102
2103    def assignable_from_resolved_type(self, src_type):
2104        return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type
2105
2106    def invalid_value(self):
2107        return Naming.PYX_NAN
2108
2109class CComplexType(CNumericType):
2110
2111    is_complex = 1
2112    to_py_function = "__pyx_PyComplex_FromComplex"
2113    has_attributes = 1
2114    scope = None
2115
2116    def __init__(self, real_type):
2117        while real_type.is_typedef and not real_type.typedef_is_external:
2118            real_type = real_type.typedef_base_type
2119        self.funcsuffix = "_%s" % real_type.specialization_name()
2120        if real_type.is_float:
2121            self.math_h_modifier = real_type.math_h_modifier
2122        else:
2123            self.math_h_modifier = "_UNUSED"
2124
2125        self.real_type = real_type
2126        CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
2127        self.binops = {}
2128        self.from_parts = "%s_from_parts" % self.specialization_name()
2129        self.default_value = "%s(0, 0)" % self.from_parts
2130
2131    def __eq__(self, other):
2132        if isinstance(self, CComplexType) and isinstance(other, CComplexType):
2133            return self.real_type == other.real_type
2134        else:
2135            return False
2136
2137    def __ne__(self, other):
2138        if isinstance(self, CComplexType) and isinstance(other, CComplexType):
2139            return self.real_type != other.real_type
2140        else:
2141            return True
2142
2143    def __lt__(self, other):
2144        if isinstance(self, CComplexType) and isinstance(other, CComplexType):
2145            return self.real_type < other.real_type
2146        else:
2147            # this is arbitrary, but it makes sure we always have
2148            # *some* kind of order
2149            return False
2150
2151    def __hash__(self):
2152        return ~hash(self.real_type)
2153
2154    def declaration_code(self, entity_code,
2155            for_display = 0, dll_linkage = None, pyrex = 0):
2156        if pyrex or for_display:
2157            real_code = self.real_type.declaration_code("", for_display, dll_linkage, pyrex)
2158            base_code = "%s complex" % real_code
2159        else:
2160            base_code = public_decl(self.sign_and_name(), dll_linkage)
2161        return self.base_declaration_code(base_code, entity_code)
2162
2163    def sign_and_name(self):
2164        real_type_name = self.real_type.specialization_name()
2165        real_type_name = real_type_name.replace('long__double','long_double')
2166        real_type_name = real_type_name.replace('PY_LONG_LONG','long_long')
2167        return Naming.type_prefix + real_type_name + "_complex"
2168
2169    def assignable_from(self, src_type):
2170        # Temporary hack/feature disabling, see #441
2171        if (not src_type.is_complex and src_type.is_numeric and src_type.is_typedef
2172            and src_type.typedef_is_external):
2173             return False
2174        elif src_type.is_pyobject:
2175            return True
2176        else:
2177            return super(CComplexType, self).assignable_from(src_type)
2178
2179    def assignable_from_resolved_type(self, src_type):
2180        return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type)
2181                    or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type)
2182                    or src_type is error_type)
2183
2184    def attributes_known(self):
2185        if self.scope is None:
2186            from . import Symtab
2187            self.scope = scope = Symtab.CClassScope(
2188                    '',
2189                    None,
2190                    visibility="extern")
2191            scope.parent_type = self
2192            scope.directives = {}
2193            scope.declare_var("real", self.real_type, None, cname="real", is_cdef=True)
2194            scope.declare_var("imag", self.real_type, None, cname="imag", is_cdef=True)
2195            scope.declare_cfunction(
2196                    "conjugate",
2197                    CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True),
2198                    pos=None,
2199                    defining=1,
2200                    cname="__Pyx_c_conj%s" % self.funcsuffix)
2201
2202        return True
2203
2204    def _utility_code_context(self):
2205        return {
2206            'type': self.empty_declaration_code(),
2207            'type_name': self.specialization_name(),
2208            'real_type': self.real_type.empty_declaration_code(),
2209            'func_suffix': self.funcsuffix,
2210            'm': self.math_h_modifier,
2211            'is_float': int(self.real_type.is_float)
2212        }
2213
2214    def create_declaration_utility_code(self, env):
2215        # This must always be run, because a single CComplexType instance can be shared
2216        # across multiple compilations (the one created in the module scope)
2217        env.use_utility_code(UtilityCode.load_cached('Header', 'Complex.c'))
2218        env.use_utility_code(UtilityCode.load_cached('RealImag', 'Complex.c'))
2219        env.use_utility_code(TempitaUtilityCode.load_cached(
2220            'Declarations', 'Complex.c', self._utility_code_context()))
2221        env.use_utility_code(TempitaUtilityCode.load_cached(
2222            'Arithmetic', 'Complex.c', self._utility_code_context()))
2223        return True
2224
2225    def can_coerce_to_pyobject(self, env):
2226        return True
2227
2228    def can_coerce_from_pyobject(self, env):
2229        return True
2230
2231    def create_to_py_utility_code(self, env):
2232        env.use_utility_code(UtilityCode.load_cached('ToPy', 'Complex.c'))
2233        return True
2234
2235    def create_from_py_utility_code(self, env):
2236        env.use_utility_code(TempitaUtilityCode.load_cached(
2237            'FromPy', 'Complex.c', self._utility_code_context()))
2238        self.from_py_function = "__Pyx_PyComplex_As_" + self.specialization_name()
2239        return True
2240
2241    def lookup_op(self, nargs, op):
2242        try:
2243            return self.binops[nargs, op]
2244        except KeyError:
2245            pass
2246        try:
2247            op_name = complex_ops[nargs, op]
2248            self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, self.funcsuffix)
2249            return func_name
2250        except KeyError:
2251            return None
2252
2253    def unary_op(self, op):
2254        return self.lookup_op(1, op)
2255
2256    def binary_op(self, op):
2257        return self.lookup_op(2, op)
2258
2259    def py_type_name(self):
2260        return "complex"
2261
2262    def cast_code(self, expr_code):
2263        return expr_code
2264
2265complex_ops = {
2266    (1, '-'): 'neg',
2267    (1, 'zero'): 'is_zero',
2268    (2, '+'): 'sum',
2269    (2, '-'): 'diff',
2270    (2, '*'): 'prod',
2271    (2, '/'): 'quot',
2272    (2, '**'): 'pow',
2273    (2, '=='): 'eq',
2274}
2275
2276
2277class CPyTSSTType(CType):
2278    #
2279    #   PEP-539 "Py_tss_t" type
2280    #
2281
2282    declaration_value = "Py_tss_NEEDS_INIT"
2283
2284    def __repr__(self):
2285        return "<Py_tss_t>"
2286
2287    def declaration_code(self, entity_code,
2288                         for_display=0, dll_linkage=None, pyrex=0):
2289        if pyrex or for_display:
2290            base_code = "Py_tss_t"
2291        else:
2292            base_code = public_decl("Py_tss_t", dll_linkage)
2293        return self.base_declaration_code(base_code, entity_code)
2294
2295
2296class CPointerBaseType(CType):
2297    # common base type for pointer/array types
2298    #
2299    #  base_type     CType              Reference type
2300
2301    subtypes = ['base_type']
2302
2303    def __init__(self, base_type):
2304        self.base_type = base_type
2305        if base_type.is_const:
2306            base_type = base_type.const_base_type
2307        for char_type in (c_char_type, c_uchar_type, c_schar_type):
2308            if base_type.same_as(char_type):
2309                self.is_string = 1
2310                break
2311        else:
2312            if base_type.same_as(c_py_unicode_type):
2313                self.is_pyunicode_ptr = 1
2314
2315        if self.is_string and not base_type.is_error:
2316            if base_type.signed == 2:
2317                self.to_py_function = "__Pyx_PyObject_FromCString"
2318                if self.is_ptr:
2319                    self.from_py_function = "__Pyx_PyObject_As%sSString"
2320            elif base_type.signed:
2321                self.to_py_function = "__Pyx_PyObject_FromString"
2322                if self.is_ptr:
2323                    self.from_py_function = "__Pyx_PyObject_As%sString"
2324            else:
2325                self.to_py_function = "__Pyx_PyObject_FromCString"
2326                if self.is_ptr:
2327                    self.from_py_function = "__Pyx_PyObject_As%sUString"
2328            if self.is_ptr:
2329                self.from_py_function %= '' if self.base_type.is_const else 'Writable'
2330            self.exception_value = "NULL"
2331        elif self.is_pyunicode_ptr and not base_type.is_error:
2332            self.to_py_function = "__Pyx_PyUnicode_FromUnicode"
2333            if self.is_ptr:
2334                self.from_py_function = "__Pyx_PyUnicode_AsUnicode"
2335            self.exception_value = "NULL"
2336
2337    def py_type_name(self):
2338        if self.is_string:
2339            return "bytes"
2340        elif self.is_pyunicode_ptr:
2341            return "unicode"
2342        else:
2343            return super(CPointerBaseType, self).py_type_name()
2344
2345    def literal_code(self, value):
2346        if self.is_string:
2347            assert isinstance(value, str)
2348            return '"%s"' % StringEncoding.escape_byte_string(value)
2349
2350
2351class CArrayType(CPointerBaseType):
2352    #  base_type     CType              Element type
2353    #  size          integer or None    Number of elements
2354
2355    is_array = 1
2356    to_tuple_function = None
2357
2358    def __init__(self, base_type, size):
2359        super(CArrayType, self).__init__(base_type)
2360        self.size = size
2361
2362    def __eq__(self, other):
2363        if isinstance(other, CType) and other.is_array and self.size == other.size:
2364            return self.base_type.same_as(other.base_type)
2365        return False
2366
2367    def __hash__(self):
2368        return hash(self.base_type) + 28 # arbitrarily chosen offset
2369
2370    def __repr__(self):
2371        return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
2372
2373    def same_as_resolved_type(self, other_type):
2374        return ((other_type.is_array and
2375            self.base_type.same_as(other_type.base_type))
2376                or other_type is error_type)
2377
2378    def assignable_from_resolved_type(self, src_type):
2379        # C arrays are assigned by value, either Python containers or C arrays/pointers
2380        if src_type.is_pyobject:
2381            return True
2382        if src_type.is_ptr or src_type.is_array:
2383            return self.base_type.assignable_from(src_type.base_type)
2384        return False
2385
2386    def element_ptr_type(self):
2387        return c_ptr_type(self.base_type)
2388
2389    def declaration_code(self, entity_code,
2390            for_display = 0, dll_linkage = None, pyrex = 0):
2391        if self.size is not None:
2392            dimension_code = self.size
2393        else:
2394            dimension_code = ""
2395        if entity_code.startswith("*"):
2396            entity_code = "(%s)" % entity_code
2397        return self.base_type.declaration_code(
2398            "%s[%s]" % (entity_code, dimension_code),
2399            for_display, dll_linkage, pyrex)
2400
2401    def as_argument_type(self):
2402        return c_ptr_type(self.base_type)
2403
2404    def is_complete(self):
2405        return self.size is not None
2406
2407    def specialize(self, values):
2408        base_type = self.base_type.specialize(values)
2409        if base_type == self.base_type:
2410            return self
2411        else:
2412            return CArrayType(base_type, self.size)
2413
2414    def deduce_template_params(self, actual):
2415        if isinstance(actual, CArrayType):
2416            return self.base_type.deduce_template_params(actual.base_type)
2417        else:
2418            return {}
2419
2420    def can_coerce_to_pyobject(self, env):
2421        return self.base_type.can_coerce_to_pyobject(env)
2422
2423    def can_coerce_from_pyobject(self, env):
2424        return self.base_type.can_coerce_from_pyobject(env)
2425
2426    def create_to_py_utility_code(self, env):
2427        if self.to_py_function is not None:
2428            return self.to_py_function
2429        if not self.base_type.create_to_py_utility_code(env):
2430            return False
2431
2432        safe_typename = self.base_type.specialization_name()
2433        to_py_function = "__Pyx_carray_to_py_%s" % safe_typename
2434        to_tuple_function = "__Pyx_carray_to_tuple_%s" % safe_typename
2435
2436        from .UtilityCode import CythonUtilityCode
2437        context = {
2438            'cname': to_py_function,
2439            'to_tuple_cname': to_tuple_function,
2440            'base_type': self.base_type,
2441        }
2442        env.use_utility_code(CythonUtilityCode.load(
2443            "carray.to_py", "CConvert.pyx",
2444            outer_module_scope=env.global_scope(),  # need access to types declared in module
2445            context=context, compiler_directives=dict(env.global_scope().directives)))
2446        self.to_tuple_function = to_tuple_function
2447        self.to_py_function = to_py_function
2448        return True
2449
2450    def to_py_call_code(self, source_code, result_code, result_type, to_py_function=None):
2451        func = self.to_py_function if to_py_function is None else to_py_function
2452        if self.is_string or self.is_pyunicode_ptr:
2453            return '%s = %s(%s)' % (
2454                result_code,
2455                func,
2456                source_code)
2457        target_is_tuple = result_type.is_builtin_type and result_type.name == 'tuple'
2458        return '%s = %s(%s, %s)' % (
2459            result_code,
2460            self.to_tuple_function if target_is_tuple else func,
2461            source_code,
2462            self.size)
2463
2464    def create_from_py_utility_code(self, env):
2465        if self.from_py_function is not None:
2466            return self.from_py_function
2467        if not self.base_type.create_from_py_utility_code(env):
2468            return False
2469
2470        from_py_function = "__Pyx_carray_from_py_%s" % self.base_type.specialization_name()
2471
2472        from .UtilityCode import CythonUtilityCode
2473        context = {
2474            'cname': from_py_function,
2475            'base_type': self.base_type,
2476        }
2477        env.use_utility_code(CythonUtilityCode.load(
2478            "carray.from_py", "CConvert.pyx",
2479            outer_module_scope=env.global_scope(),  # need access to types declared in module
2480            context=context, compiler_directives=dict(env.global_scope().directives)))
2481        self.from_py_function = from_py_function
2482        return True
2483
2484    def from_py_call_code(self, source_code, result_code, error_pos, code,
2485                          from_py_function=None, error_condition=None):
2486        assert not error_condition, '%s: %s' % (error_pos, error_condition)
2487        call_code = "%s(%s, %s, %s)" % (
2488            from_py_function or self.from_py_function,
2489            source_code, result_code, self.size)
2490        return code.error_goto_if_neg(call_code, error_pos)
2491
2492
2493class CPtrType(CPointerBaseType):
2494    #  base_type     CType              Reference type
2495
2496    is_ptr = 1
2497    default_value = "0"
2498
2499    def __hash__(self):
2500        return hash(self.base_type) + 27 # arbitrarily chosen offset
2501
2502    def __eq__(self, other):
2503        if isinstance(other, CType) and other.is_ptr:
2504            return self.base_type.same_as(other.base_type)
2505        return False
2506
2507    def __ne__(self, other):
2508        return not (self == other)
2509
2510    def __repr__(self):
2511        return "<CPtrType %s>" % repr(self.base_type)
2512
2513    def same_as_resolved_type(self, other_type):
2514        return ((other_type.is_ptr and
2515            self.base_type.same_as(other_type.base_type))
2516                or other_type is error_type)
2517
2518    def declaration_code(self, entity_code,
2519            for_display = 0, dll_linkage = None, pyrex = 0):
2520        #print "CPtrType.declaration_code: pointer to", self.base_type ###
2521        return self.base_type.declaration_code(
2522            "*%s" % entity_code,
2523            for_display, dll_linkage, pyrex)
2524
2525    def assignable_from_resolved_type(self, other_type):
2526        if other_type is error_type:
2527            return 1
2528        if other_type.is_null_ptr:
2529            return 1
2530        if self.base_type.is_const:
2531            self = CPtrType(self.base_type.const_base_type)
2532        if self.base_type.is_cfunction:
2533            if other_type.is_ptr:
2534                other_type = other_type.base_type.resolve()
2535            if other_type.is_cfunction:
2536                return self.base_type.pointer_assignable_from_resolved_type(other_type)
2537            else:
2538                return 0
2539        if (self.base_type.is_cpp_class and other_type.is_ptr
2540                and other_type.base_type.is_cpp_class and other_type.base_type.is_subclass(self.base_type)):
2541            return 1
2542        if other_type.is_array or other_type.is_ptr:
2543            return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
2544        return 0
2545
2546    def specialize(self, values):
2547        base_type = self.base_type.specialize(values)
2548        if base_type == self.base_type:
2549            return self
2550        else:
2551            return CPtrType(base_type)
2552
2553    def deduce_template_params(self, actual):
2554        if isinstance(actual, CPtrType):
2555            return self.base_type.deduce_template_params(actual.base_type)
2556        else:
2557            return {}
2558
2559    def invalid_value(self):
2560        return "1"
2561
2562    def find_cpp_operation_type(self, operator, operand_type=None):
2563        if self.base_type.is_cpp_class:
2564            return self.base_type.find_cpp_operation_type(operator, operand_type)
2565        return None
2566
2567
2568class CNullPtrType(CPtrType):
2569
2570    is_null_ptr = 1
2571
2572
2573class CReferenceType(BaseType):
2574
2575    is_reference = 1
2576    is_fake_reference = 0
2577
2578    def __init__(self, base_type):
2579        self.ref_base_type = base_type
2580
2581    def __repr__(self):
2582        return "<CReferenceType %s>" % repr(self.ref_base_type)
2583
2584    def __str__(self):
2585        return "%s &" % self.ref_base_type
2586
2587    def declaration_code(self, entity_code,
2588            for_display = 0, dll_linkage = None, pyrex = 0):
2589        #print "CReferenceType.declaration_code: pointer to", self.base_type ###
2590        return self.ref_base_type.declaration_code(
2591            "&%s" % entity_code,
2592            for_display, dll_linkage, pyrex)
2593
2594    def specialize(self, values):
2595        base_type = self.ref_base_type.specialize(values)
2596        if base_type == self.ref_base_type:
2597            return self
2598        else:
2599            return type(self)(base_type)
2600
2601    def deduce_template_params(self, actual):
2602        return self.ref_base_type.deduce_template_params(actual)
2603
2604    def __getattr__(self, name):
2605        return getattr(self.ref_base_type, name)
2606
2607
2608class CFakeReferenceType(CReferenceType):
2609
2610    is_fake_reference = 1
2611
2612    def __repr__(self):
2613        return "<CFakeReferenceType %s>" % repr(self.ref_base_type)
2614
2615    def __str__(self):
2616        return "%s [&]" % self.ref_base_type
2617
2618    def declaration_code(self, entity_code,
2619            for_display = 0, dll_linkage = None, pyrex = 0):
2620        #print "CReferenceType.declaration_code: pointer to", self.base_type ###
2621        return "__Pyx_FakeReference<%s> %s" % (self.ref_base_type.empty_declaration_code(), entity_code)
2622
2623
2624class CFuncType(CType):
2625    #  return_type      CType
2626    #  args             [CFuncTypeArg]
2627    #  has_varargs      boolean
2628    #  exception_value  string
2629    #  exception_check  boolean    True if PyErr_Occurred check needed
2630    #  calling_convention  string  Function calling convention
2631    #  nogil            boolean    Can be called without gil
2632    #  with_gil         boolean    Acquire gil around function body
2633    #  templates        [string] or None
2634    #  cached_specialized_types [CFuncType]   cached specialized versions of the CFuncType if defined in a pxd
2635    #  from_fused       boolean    Indicates whether this is a specialized
2636    #                              C function
2637    #  is_strict_signature boolean  function refuses to accept coerced arguments
2638    #                               (used for optimisation overrides)
2639    #  is_const_method  boolean
2640    #  is_static_method boolean
2641
2642    is_cfunction = 1
2643    original_sig = None
2644    cached_specialized_types = None
2645    from_fused = False
2646    is_const_method = False
2647
2648    subtypes = ['return_type', 'args']
2649
2650    def __init__(self, return_type, args, has_varargs = 0,
2651            exception_value = None, exception_check = 0, calling_convention = "",
2652            nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0,
2653            is_const_method = False, is_static_method=False,
2654            templates = None, is_strict_signature = False):
2655        self.return_type = return_type
2656        self.args = args
2657        self.has_varargs = has_varargs
2658        self.optional_arg_count = optional_arg_count
2659        self.exception_value = exception_value
2660        self.exception_check = exception_check
2661        self.calling_convention = calling_convention
2662        self.nogil = nogil
2663        self.with_gil = with_gil
2664        self.is_overridable = is_overridable
2665        self.is_const_method = is_const_method
2666        self.is_static_method = is_static_method
2667        self.templates = templates
2668        self.is_strict_signature = is_strict_signature
2669
2670    def __repr__(self):
2671        arg_reprs = list(map(repr, self.args))
2672        if self.has_varargs:
2673            arg_reprs.append("...")
2674        if self.exception_value:
2675            except_clause = " %r" % self.exception_value
2676        else:
2677            except_clause = ""
2678        if self.exception_check:
2679            except_clause += "?"
2680        return "<CFuncType %s %s[%s]%s>" % (
2681            repr(self.return_type),
2682            self.calling_convention_prefix(),
2683            ",".join(arg_reprs),
2684            except_clause)
2685
2686    def with_with_gil(self, with_gil):
2687        if with_gil == self.with_gil:
2688            return self
2689        else:
2690            return CFuncType(
2691                self.return_type, self.args, self.has_varargs,
2692                self.exception_value, self.exception_check,
2693                self.calling_convention, self.nogil,
2694                with_gil,
2695                self.is_overridable, self.optional_arg_count,
2696                self.is_const_method, self.is_static_method,
2697                self.templates, self.is_strict_signature)
2698
2699    def calling_convention_prefix(self):
2700        cc = self.calling_convention
2701        if cc:
2702            return cc + " "
2703        else:
2704            return ""
2705
2706    def as_argument_type(self):
2707        return c_ptr_type(self)
2708
2709    def same_c_signature_as(self, other_type, as_cmethod = 0):
2710        return self.same_c_signature_as_resolved_type(
2711            other_type.resolve(), as_cmethod)
2712
2713    def same_c_signature_as_resolved_type(self, other_type, as_cmethod=False, as_pxd_definition=False,
2714                                          exact_semantics=True):
2715        # If 'exact_semantics' is false, allow any equivalent C signatures
2716        # if the Cython semantics are compatible, i.e. the same or wider for 'other_type'.
2717
2718        #print "CFuncType.same_c_signature_as_resolved_type:", \
2719        #    self, other_type, "as_cmethod =", as_cmethod ###
2720        if other_type is error_type:
2721            return 1
2722        if not other_type.is_cfunction:
2723            return 0
2724        if self.is_overridable != other_type.is_overridable:
2725            return 0
2726        nargs = len(self.args)
2727        if nargs != len(other_type.args):
2728            return 0
2729        # When comparing C method signatures, the first argument
2730        # is exempt from compatibility checking (the proper check
2731        # is performed elsewhere).
2732        for i in range(as_cmethod, nargs):
2733            if not self.args[i].type.same_as(other_type.args[i].type):
2734                return 0
2735        if self.has_varargs != other_type.has_varargs:
2736            return 0
2737        if self.optional_arg_count != other_type.optional_arg_count:
2738            return 0
2739        if as_pxd_definition:
2740            # A narrowing of the return type declared in the pxd is allowed.
2741            if not self.return_type.subtype_of_resolved_type(other_type.return_type):
2742                return 0
2743        else:
2744            if not self.return_type.same_as(other_type.return_type):
2745                return 0
2746        if not self.same_calling_convention_as(other_type):
2747            return 0
2748        if exact_semantics:
2749            if self.exception_check != other_type.exception_check:
2750                return 0
2751            if not self._same_exception_value(other_type.exception_value):
2752                return 0
2753        elif not self._is_exception_compatible_with(other_type):
2754            return 0
2755        return 1
2756
2757    def _same_exception_value(self, other_exc_value):
2758        if self.exception_value == other_exc_value:
2759            return 1
2760        if self.exception_check != '+':
2761            return 0
2762        if not self.exception_value or not other_exc_value:
2763            return 0
2764        if self.exception_value.type != other_exc_value.type:
2765            return 0
2766        if self.exception_value.entry and other_exc_value.entry:
2767            if self.exception_value.entry.cname != other_exc_value.entry.cname:
2768                return 0
2769        if self.exception_value.name != other_exc_value.name:
2770            return 0
2771        return 1
2772
2773    def compatible_signature_with(self, other_type, as_cmethod = 0):
2774        return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
2775
2776    def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
2777        #print "CFuncType.same_c_signature_as_resolved_type:", \
2778        #    self, other_type, "as_cmethod =", as_cmethod ###
2779        if other_type is error_type:
2780            return 1
2781        if not other_type.is_cfunction:
2782            return 0
2783        if not self.is_overridable and other_type.is_overridable:
2784            return 0
2785        nargs = len(self.args)
2786        if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
2787            return 0
2788        if self.optional_arg_count < other_type.optional_arg_count:
2789            return 0
2790        # When comparing C method signatures, the first argument
2791        # is exempt from compatibility checking (the proper check
2792        # is performed elsewhere).
2793        for i in range(as_cmethod, len(other_type.args)):
2794            if not self.args[i].type.same_as(
2795                other_type.args[i].type):
2796                    return 0
2797        if self.has_varargs != other_type.has_varargs:
2798            return 0
2799        if not self.return_type.subtype_of_resolved_type(other_type.return_type):
2800            return 0
2801        if not self.same_calling_convention_as(other_type):
2802            return 0
2803        if self.nogil != other_type.nogil:
2804            return 0
2805        if not self._is_exception_compatible_with(other_type):
2806            return 0
2807        self.original_sig = other_type.original_sig or other_type
2808        return 1
2809
2810    def _is_exception_compatible_with(self, other_type):
2811        # narrower exception checks are ok, but prevent mismatches
2812        if self.exception_check == '+' and other_type.exception_check != '+':
2813            # must catch C++ exceptions if we raise them
2814            return 0
2815        if not other_type.exception_check or other_type.exception_value is not None:
2816            # if other does not *always* check exceptions, self must comply
2817            if not self._same_exception_value(other_type.exception_value):
2818                return 0
2819            if self.exception_check and self.exception_check != other_type.exception_check:
2820                # a redundant exception check doesn't make functions incompatible, but a missing one does
2821                return 0
2822        return 1
2823
2824    def narrower_c_signature_than(self, other_type, as_cmethod = 0):
2825        return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
2826
2827    def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
2828        if other_type is error_type:
2829            return 1
2830        if not other_type.is_cfunction:
2831            return 0
2832        nargs = len(self.args)
2833        if nargs != len(other_type.args):
2834            return 0
2835        for i in range(as_cmethod, nargs):
2836            if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
2837                return 0
2838            else:
2839                self.args[i].needs_type_test = other_type.args[i].needs_type_test \
2840                        or not self.args[i].type.same_as(other_type.args[i].type)
2841        if self.has_varargs != other_type.has_varargs:
2842            return 0
2843        if self.optional_arg_count != other_type.optional_arg_count:
2844            return 0
2845        if not self.return_type.subtype_of_resolved_type(other_type.return_type):
2846            return 0
2847        if not self.exception_check and other_type.exception_check:
2848            # a redundant exception check doesn't make functions incompatible, but a missing one does
2849            return 0
2850        if not self._same_exception_value(other_type.exception_value):
2851            return 0
2852        return 1
2853
2854    def same_calling_convention_as(self, other):
2855        ## XXX Under discussion ...
2856        ## callspec_words = ("__stdcall", "__cdecl", "__fastcall")
2857        ## cs1 = self.calling_convention
2858        ## cs2 = other.calling_convention
2859        ## if (cs1 in callspec_words or
2860        ##     cs2 in callspec_words):
2861        ##     return cs1 == cs2
2862        ## else:
2863        ##     return True
2864        sc1 = self.calling_convention == '__stdcall'
2865        sc2 = other.calling_convention == '__stdcall'
2866        return sc1 == sc2
2867
2868    def same_as_resolved_type(self, other_type, as_cmethod=False):
2869        return self.same_c_signature_as_resolved_type(other_type, as_cmethod=as_cmethod) \
2870            and self.nogil == other_type.nogil
2871
2872    def pointer_assignable_from_resolved_type(self, rhs_type):
2873        # Accept compatible exception/nogil declarations for the RHS.
2874        if rhs_type is error_type:
2875            return 1
2876        if not rhs_type.is_cfunction:
2877            return 0
2878        return rhs_type.same_c_signature_as_resolved_type(self, exact_semantics=False) \
2879            and not (self.nogil and not rhs_type.nogil)
2880
2881    def declaration_code(self, entity_code,
2882                         for_display = 0, dll_linkage = None, pyrex = 0,
2883                         with_calling_convention = 1):
2884        arg_decl_list = []
2885        for arg in self.args[:len(self.args)-self.optional_arg_count]:
2886            arg_decl_list.append(
2887                arg.type.declaration_code("", for_display, pyrex = pyrex))
2888        if self.is_overridable:
2889            arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
2890        if self.optional_arg_count:
2891            arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
2892        if self.has_varargs:
2893            arg_decl_list.append("...")
2894        arg_decl_code = ", ".join(arg_decl_list)
2895        if not arg_decl_code and not pyrex:
2896            arg_decl_code = "void"
2897        trailer = ""
2898        if (pyrex or for_display) and not self.return_type.is_pyobject:
2899            if self.exception_value and self.exception_check:
2900                trailer = " except? %s" % self.exception_value
2901            elif self.exception_value:
2902                trailer = " except %s" % self.exception_value
2903            elif self.exception_check == '+':
2904                trailer = " except +"
2905            elif self.exception_check and for_display:
2906                # not spelled out by default, unless for human eyes
2907                trailer = " except *"
2908            if self.nogil:
2909                trailer += " nogil"
2910        if not with_calling_convention:
2911            cc = ''
2912        else:
2913            cc = self.calling_convention_prefix()
2914            if (not entity_code and cc) or entity_code.startswith("*"):
2915                entity_code = "(%s%s)" % (cc, entity_code)
2916                cc = ""
2917        if self.is_const_method:
2918            trailer += " const"
2919        return self.return_type.declaration_code(
2920            "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
2921            for_display, dll_linkage, pyrex)
2922
2923    def function_header_code(self, func_name, arg_code):
2924        if self.is_const_method:
2925            trailer = " const"
2926        else:
2927            trailer = ""
2928        return "%s%s(%s)%s" % (self.calling_convention_prefix(),
2929            func_name, arg_code, trailer)
2930
2931    def signature_string(self):
2932        s = self.empty_declaration_code()
2933        return s
2934
2935    def signature_cast_string(self):
2936        s = self.declaration_code("(*)", with_calling_convention=False)
2937        return '(%s)' % s
2938
2939    def specialize(self, values):
2940        result = CFuncType(self.return_type.specialize(values),
2941                           [arg.specialize(values) for arg in self.args],
2942                           has_varargs = self.has_varargs,
2943                           exception_value = self.exception_value,
2944                           exception_check = self.exception_check,
2945                           calling_convention = self.calling_convention,
2946                           nogil = self.nogil,
2947                           with_gil = self.with_gil,
2948                           is_overridable = self.is_overridable,
2949                           optional_arg_count = self.optional_arg_count,
2950                           is_const_method = self.is_const_method,
2951                           is_static_method = self.is_static_method,
2952                           templates = self.templates)
2953
2954        result.from_fused = self.is_fused
2955        return result
2956
2957    def opt_arg_cname(self, arg_name):
2958        return self.op_arg_struct.base_type.scope.lookup(arg_name).cname
2959
2960    # Methods that deal with Fused Types
2961    # All but map_with_specific_entries should be called only on functions
2962    # with fused types (and not on their corresponding specific versions).
2963
2964    def get_all_specialized_permutations(self, fused_types=None):
2965        """
2966        Permute all the types. For every specific instance of a fused type, we
2967        want all other specific instances of all other fused types.
2968
2969        It returns an iterable of two-tuples of the cname that should prefix
2970        the cname of the function, and a dict mapping any fused types to their
2971        respective specific types.
2972        """
2973        assert self.is_fused
2974
2975        if fused_types is None:
2976            fused_types = self.get_fused_types()
2977
2978        return get_all_specialized_permutations(fused_types)
2979
2980    def get_all_specialized_function_types(self):
2981        """
2982        Get all the specific function types of this one.
2983        """
2984        assert self.is_fused
2985
2986        if self.entry.fused_cfunction:
2987            return [n.type for n in self.entry.fused_cfunction.nodes]
2988        elif self.cached_specialized_types is not None:
2989            return self.cached_specialized_types
2990
2991        result = []
2992        permutations = self.get_all_specialized_permutations()
2993
2994        new_cfunc_entries = []
2995        for cname, fused_to_specific in permutations:
2996            new_func_type = self.entry.type.specialize(fused_to_specific)
2997
2998            if self.optional_arg_count:
2999                # Remember, this method is set by CFuncDeclaratorNode
3000                self.declare_opt_arg_struct(new_func_type, cname)
3001
3002            new_entry = copy.deepcopy(self.entry)
3003            new_func_type.specialize_entry(new_entry, cname)
3004
3005            new_entry.type = new_func_type
3006            new_func_type.entry = new_entry
3007            result.append(new_func_type)
3008
3009            new_cfunc_entries.append(new_entry)
3010
3011        cfunc_entries = self.entry.scope.cfunc_entries
3012        try:
3013            cindex = cfunc_entries.index(self.entry)
3014        except ValueError:
3015            cfunc_entries.extend(new_cfunc_entries)
3016        else:
3017            cfunc_entries[cindex:cindex+1] = new_cfunc_entries
3018
3019        self.cached_specialized_types = result
3020
3021        return result
3022
3023    def get_fused_types(self, result=None, seen=None, subtypes=None):
3024        """Return fused types in the order they appear as parameter types"""
3025        return super(CFuncType, self).get_fused_types(result, seen,
3026                                                      subtypes=['args'])
3027
3028    def specialize_entry(self, entry, cname):
3029        assert not self.is_fused
3030        specialize_entry(entry, cname)
3031
3032    def can_coerce_to_pyobject(self, env):
3033        # duplicating the decisions from create_to_py_utility_code() here avoids writing out unused code
3034        if self.has_varargs or self.optional_arg_count:
3035            return False
3036        if self.to_py_function is not None:
3037            return self.to_py_function
3038        for arg in self.args:
3039            if not arg.type.is_pyobject and not arg.type.can_coerce_to_pyobject(env):
3040                return False
3041        if not self.return_type.is_pyobject and not self.return_type.can_coerce_to_pyobject(env):
3042            return False
3043        return True
3044
3045    def create_to_py_utility_code(self, env):
3046        # FIXME: it seems we're trying to coerce in more cases than we should
3047        if self.to_py_function is not None:
3048            return self.to_py_function
3049        if not self.can_coerce_to_pyobject(env):
3050            return False
3051        from .UtilityCode import CythonUtilityCode
3052        safe_typename = re.sub('[^a-zA-Z0-9]', '__', self.declaration_code("", pyrex=1))
3053        to_py_function = "__Pyx_CFunc_%s_to_py" % safe_typename
3054
3055        for arg in self.args:
3056            if not arg.type.is_pyobject and not arg.type.create_from_py_utility_code(env):
3057                return False
3058        if not self.return_type.is_pyobject and not self.return_type.create_to_py_utility_code(env):
3059            return False
3060
3061        def declared_type(ctype):
3062            type_displayname = str(ctype.declaration_code("", for_display=True))
3063            if ctype.is_pyobject:
3064                arg_ctype = type_name = type_displayname
3065                if ctype.is_builtin_type:
3066                    arg_ctype = ctype.name
3067                elif not ctype.is_extension_type:
3068                    type_name = 'object'
3069                    type_displayname = None
3070                else:
3071                    type_displayname = repr(type_displayname)
3072            elif ctype is c_bint_type:
3073                type_name = arg_ctype = 'bint'
3074            else:
3075                type_name = arg_ctype = type_displayname
3076                if ctype is c_double_type:
3077                    type_displayname = 'float'
3078                else:
3079                    type_displayname = repr(type_displayname)
3080            return type_name, arg_ctype, type_displayname
3081
3082        class Arg(object):
3083            def __init__(self, arg_name, arg_type):
3084                self.name = arg_name
3085                self.type = arg_type
3086                self.type_cname, self.ctype, self.type_displayname = declared_type(arg_type)
3087
3088        if self.return_type.is_void:
3089            except_clause = 'except *'
3090        elif self.return_type.is_pyobject:
3091            except_clause = ''
3092        elif self.exception_value:
3093            except_clause = ('except? %s' if self.exception_check else 'except %s') % self.exception_value
3094        else:
3095            except_clause = 'except *'
3096
3097        context = {
3098            'cname': to_py_function,
3099            'args': [Arg(arg.name or 'arg%s' % ix, arg.type) for ix, arg in enumerate(self.args)],
3100            'return_type': Arg('return', self.return_type),
3101            'except_clause': except_clause,
3102        }
3103        # FIXME: directives come from first defining environment and do not adapt for reuse
3104        env.use_utility_code(CythonUtilityCode.load(
3105            "cfunc.to_py", "CConvert.pyx",
3106            outer_module_scope=env.global_scope(),  # need access to types declared in module
3107            context=context, compiler_directives=dict(env.global_scope().directives)))
3108        self.to_py_function = to_py_function
3109        return True
3110
3111
3112def specialize_entry(entry, cname):
3113    """
3114    Specialize an entry of a copied fused function or method
3115    """
3116    entry.is_fused_specialized = True
3117    entry.name = get_fused_cname(cname, entry.name)
3118
3119    if entry.is_cmethod:
3120        entry.cname = entry.name
3121        if entry.is_inherited:
3122            entry.cname = StringEncoding.EncodedString(
3123                    "%s.%s" % (Naming.obj_base_cname, entry.cname))
3124    else:
3125        entry.cname = get_fused_cname(cname, entry.cname)
3126
3127    if entry.func_cname:
3128        entry.func_cname = get_fused_cname(cname, entry.func_cname)
3129
3130def get_fused_cname(fused_cname, orig_cname):
3131    """
3132    Given the fused cname id and an original cname, return a specialized cname
3133    """
3134    assert fused_cname and orig_cname
3135    return StringEncoding.EncodedString('%s%s%s' % (Naming.fused_func_prefix,
3136                                                    fused_cname, orig_cname))
3137
3138def unique(somelist):
3139    seen = set()
3140    result = []
3141    for obj in somelist:
3142        if obj not in seen:
3143            result.append(obj)
3144            seen.add(obj)
3145
3146    return result
3147
3148def get_all_specialized_permutations(fused_types):
3149    return _get_all_specialized_permutations(unique(fused_types))
3150
3151def _get_all_specialized_permutations(fused_types, id="", f2s=()):
3152    fused_type, = fused_types[0].get_fused_types()
3153    result = []
3154
3155    for newid, specific_type in enumerate(fused_type.types):
3156        # f2s = dict(f2s, **{ fused_type: specific_type })
3157        f2s = dict(f2s)
3158        f2s.update({ fused_type: specific_type })
3159
3160        if id:
3161            cname = '%s_%s' % (id, newid)
3162        else:
3163            cname = str(newid)
3164
3165        if len(fused_types) > 1:
3166            result.extend(_get_all_specialized_permutations(
3167                                            fused_types[1:], cname, f2s))
3168        else:
3169            result.append((cname, f2s))
3170
3171    return result
3172
3173def specialization_signature_string(fused_compound_type, fused_to_specific):
3174    """
3175    Return the signature for a specialization of a fused type. e.g.
3176
3177        floating[:] ->
3178            'float' or 'double'
3179
3180        cdef fused ft:
3181            float[:]
3182            double[:]
3183
3184        ft ->
3185            'float[:]' or 'double[:]'
3186
3187        integral func(floating) ->
3188            'int (*func)(float)' or ...
3189    """
3190    fused_types = fused_compound_type.get_fused_types()
3191    if len(fused_types) == 1:
3192        fused_type = fused_types[0]
3193    else:
3194        fused_type = fused_compound_type
3195
3196    return fused_type.specialize(fused_to_specific).typeof_name()
3197
3198
3199def get_specialized_types(type):
3200    """
3201    Return a list of specialized types in their declared order.
3202    """
3203    assert type.is_fused
3204
3205    if isinstance(type, FusedType):
3206        result = list(type.types)
3207        for specialized_type in result:
3208            specialized_type.specialization_string = specialized_type.typeof_name()
3209    else:
3210        result = []
3211        for cname, f2s in get_all_specialized_permutations(type.get_fused_types()):
3212            specialized_type = type.specialize(f2s)
3213            specialized_type.specialization_string = (
3214                            specialization_signature_string(type, f2s))
3215            result.append(specialized_type)
3216
3217    return result
3218
3219
3220class CFuncTypeArg(BaseType):
3221    #  name       string
3222    #  cname      string
3223    #  type       PyrexType
3224    #  pos        source file position
3225
3226    # FIXME: is this the right setup? should None be allowed here?
3227    not_none = False
3228    or_none = False
3229    accept_none = True
3230    accept_builtin_subtypes = False
3231    annotation = None
3232
3233    subtypes = ['type']
3234
3235    def __init__(self, name, type, pos, cname=None, annotation=None):
3236        self.name = name
3237        if cname is not None:
3238            self.cname = cname
3239        else:
3240            self.cname = Naming.var_prefix + name
3241        if annotation is not None:
3242            self.annotation = annotation
3243        self.type = type
3244        self.pos = pos
3245        self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
3246
3247    def __repr__(self):
3248        return "%s:%s" % (self.name, repr(self.type))
3249
3250    def declaration_code(self, for_display = 0):
3251        return self.type.declaration_code(self.cname, for_display)
3252
3253    def specialize(self, values):
3254        return CFuncTypeArg(self.name, self.type.specialize(values), self.pos, self.cname)
3255
3256
3257class ToPyStructUtilityCode(object):
3258
3259    requires = None
3260
3261    def __init__(self, type, forward_decl, env):
3262        self.type = type
3263        self.header = "static PyObject* %s(%s)" % (type.to_py_function,
3264                                                   type.declaration_code('s'))
3265        self.forward_decl = forward_decl
3266        self.env = env
3267
3268    def __eq__(self, other):
3269        return isinstance(other, ToPyStructUtilityCode) and self.header == other.header
3270
3271    def __hash__(self):
3272        return hash(self.header)
3273
3274    def get_tree(self, **kwargs):
3275        pass
3276
3277    def put_code(self, output):
3278        code = output['utility_code_def']
3279        proto = output['utility_code_proto']
3280
3281        code.putln("%s {" % self.header)
3282        code.putln("PyObject* res;")
3283        code.putln("PyObject* member;")
3284        code.putln("res = __Pyx_PyDict_NewPresized(%d); if (unlikely(!res)) return NULL;" %
3285                   len(self.type.scope.var_entries))
3286        for member in self.type.scope.var_entries:
3287            nameconst_cname = code.get_py_string_const(member.name, identifier=True)
3288            code.putln("%s; if (unlikely(!member)) goto bad;" % (
3289                member.type.to_py_call_code('s.%s' % member.cname, 'member', member.type)))
3290            code.putln("if (unlikely(PyDict_SetItem(res, %s, member) < 0)) goto bad;" % nameconst_cname)
3291            code.putln("Py_DECREF(member);")
3292        code.putln("return res;")
3293        code.putln("bad:")
3294        code.putln("Py_XDECREF(member);")
3295        code.putln("Py_DECREF(res);")
3296        code.putln("return NULL;")
3297        code.putln("}")
3298
3299        # This is a bit of a hack, we need a forward declaration
3300        # due to the way things are ordered in the module...
3301        if self.forward_decl:
3302            proto.putln(self.type.empty_declaration_code() + ';')
3303        proto.putln(self.header + ";")
3304
3305    def inject_tree_and_scope_into(self, module_node):
3306        pass
3307
3308
3309class CStructOrUnionType(CType):
3310    #  name          string
3311    #  cname         string
3312    #  kind          string              "struct" or "union"
3313    #  scope         StructOrUnionScope, or None if incomplete
3314    #  typedef_flag  boolean
3315    #  packed        boolean
3316
3317    # entry          Entry
3318
3319    is_struct_or_union = 1
3320    has_attributes = 1
3321    exception_check = True
3322
3323    def __init__(self, name, kind, scope, typedef_flag, cname, packed=False):
3324        self.name = name
3325        self.cname = cname
3326        self.kind = kind
3327        self.scope = scope
3328        self.typedef_flag = typedef_flag
3329        self.is_struct = kind == 'struct'
3330        self.to_py_function = "%s_to_py_%s" % (
3331            Naming.convert_func_prefix, self.specialization_name())
3332        self.from_py_function = "%s_from_py_%s" % (
3333            Naming.convert_func_prefix, self.specialization_name())
3334        self.exception_check = True
3335        self._convert_to_py_code = None
3336        self._convert_from_py_code = None
3337        self.packed = packed
3338
3339    def can_coerce_to_pyobject(self, env):
3340        if self._convert_to_py_code is False:
3341            return None  # tri-state-ish
3342
3343        if env.outer_scope is None:
3344            return False
3345
3346        if self._convert_to_py_code is None:
3347            is_union = not self.is_struct
3348            unsafe_union_types = set()
3349            safe_union_types = set()
3350            for member in self.scope.var_entries:
3351                member_type = member.type
3352                if not member_type.can_coerce_to_pyobject(env):
3353                    self.to_py_function = None
3354                    self._convert_to_py_code = False
3355                    return False
3356                if is_union:
3357                    if member_type.is_ptr or member_type.is_cpp_class:
3358                        unsafe_union_types.add(member_type)
3359                    else:
3360                        safe_union_types.add(member_type)
3361
3362            if unsafe_union_types and (safe_union_types or len(unsafe_union_types) > 1):
3363                # unsafe mix of safe and unsafe to convert types
3364                self.from_py_function = None
3365                self._convert_from_py_code = False
3366                return False
3367
3368        return True
3369
3370    def create_to_py_utility_code(self, env):
3371        if not self.can_coerce_to_pyobject(env):
3372            return False
3373
3374        if self._convert_to_py_code is None:
3375            for member in self.scope.var_entries:
3376                member.type.create_to_py_utility_code(env)
3377            forward_decl = self.entry.visibility != 'extern' and not self.typedef_flag
3378            self._convert_to_py_code = ToPyStructUtilityCode(self, forward_decl, env)
3379
3380        env.use_utility_code(self._convert_to_py_code)
3381        return True
3382
3383    def can_coerce_from_pyobject(self, env):
3384        if env.outer_scope is None or self._convert_from_py_code is False:
3385            return False
3386        for member in self.scope.var_entries:
3387            if not member.type.can_coerce_from_pyobject(env):
3388                return False
3389        return True
3390
3391    def create_from_py_utility_code(self, env):
3392        if env.outer_scope is None:
3393            return False
3394
3395        if self._convert_from_py_code is False:
3396            return None  # tri-state-ish
3397
3398        if self._convert_from_py_code is None:
3399            if not self.scope.var_entries:
3400                # There are obviously missing fields; don't allow instantiation
3401                # where absolutely no content is provided.
3402                return False
3403
3404            for member in self.scope.var_entries:
3405                if not member.type.create_from_py_utility_code(env):
3406                    self.from_py_function = None
3407                    self._convert_from_py_code = False
3408                    return False
3409
3410            context = dict(
3411                struct_type=self,
3412                var_entries=self.scope.var_entries,
3413                funcname=self.from_py_function,
3414            )
3415            from .UtilityCode import CythonUtilityCode
3416            self._convert_from_py_code = CythonUtilityCode.load(
3417                "FromPyStructUtility" if self.is_struct else "FromPyUnionUtility",
3418                "CConvert.pyx",
3419                outer_module_scope=env.global_scope(),  # need access to types declared in module
3420                context=context)
3421
3422        env.use_utility_code(self._convert_from_py_code)
3423        return True
3424
3425    def __repr__(self):
3426        return "<CStructOrUnionType %s %s%s>" % (
3427            self.name, self.cname,
3428            ("", " typedef")[self.typedef_flag])
3429
3430    def declaration_code(self, entity_code,
3431                         for_display=0, dll_linkage=None, pyrex=0):
3432        if pyrex or for_display:
3433            base_code = self.name
3434        else:
3435            if self.typedef_flag:
3436                base_code = self.cname
3437            else:
3438                base_code = "%s %s" % (self.kind, self.cname)
3439            base_code = public_decl(base_code, dll_linkage)
3440        return self.base_declaration_code(base_code, entity_code)
3441
3442    def __eq__(self, other):
3443        try:
3444            return (isinstance(other, CStructOrUnionType) and
3445                    self.name == other.name)
3446        except AttributeError:
3447            return False
3448
3449    def __lt__(self, other):
3450        try:
3451            return self.name < other.name
3452        except AttributeError:
3453            # this is arbitrary, but it makes sure we always have
3454            # *some* kind of order
3455            return False
3456
3457    def __hash__(self):
3458        return hash(self.cname) ^ hash(self.kind)
3459
3460    def is_complete(self):
3461        return self.scope is not None
3462
3463    def attributes_known(self):
3464        return self.is_complete()
3465
3466    def can_be_complex(self):
3467        # Does the struct consist of exactly two identical floats?
3468        fields = self.scope.var_entries
3469        if len(fields) != 2: return False
3470        a, b = fields
3471        return (a.type.is_float and b.type.is_float and
3472                a.type.empty_declaration_code() ==
3473                b.type.empty_declaration_code())
3474
3475    def struct_nesting_depth(self):
3476        child_depths = [x.type.struct_nesting_depth()
3477                        for x in self.scope.var_entries]
3478        return max(child_depths) + 1
3479
3480    def cast_code(self, expr_code):
3481        if self.is_struct:
3482            return expr_code
3483        return super(CStructOrUnionType, self).cast_code(expr_code)
3484
3485cpp_string_conversions = ("std::string",)
3486
3487builtin_cpp_conversions = {
3488    # type                element template params
3489    "std::pair":          2,
3490    "std::vector":        1,
3491    "std::list":          1,
3492    "std::set":           1,
3493    "std::unordered_set": 1,
3494    "std::map":           2,
3495    "std::unordered_map": 2,
3496    "std::complex":       1,
3497}
3498
3499class CppClassType(CType):
3500    #  name          string
3501    #  cname         string
3502    #  scope         CppClassScope
3503    #  templates     [string] or None
3504
3505    is_cpp_class = 1
3506    has_attributes = 1
3507    exception_check = True
3508    namespace = None
3509
3510    # For struct-like declaration.
3511    kind = "struct"
3512    packed = False
3513    typedef_flag = False
3514
3515    subtypes = ['templates']
3516
3517    def __init__(self, name, scope, cname, base_classes, templates=None, template_type=None):
3518        self.name = name
3519        self.cname = cname
3520        self.scope = scope
3521        self.base_classes = base_classes
3522        self.operators = []
3523        self.templates = templates
3524        self.template_type = template_type
3525        self.num_optional_templates = sum(is_optional_template_param(T) for T in templates or ())
3526        if templates:
3527            self.specializations = {tuple(zip(templates, templates)): self}
3528        else:
3529            self.specializations = {}
3530        self.is_cpp_string = cname in cpp_string_conversions
3531
3532    def use_conversion_utility(self, from_or_to):
3533        pass
3534
3535    def maybe_unordered(self):
3536        if 'unordered' in self.cname:
3537            return 'unordered_'
3538        else:
3539            return ''
3540
3541    def can_coerce_from_pyobject(self, env):
3542        if self.cname in builtin_cpp_conversions:
3543            template_count = builtin_cpp_conversions[self.cname]
3544            for ix, T in enumerate(self.templates or []):
3545                if ix >= template_count:
3546                    break
3547                if T.is_pyobject or not T.can_coerce_from_pyobject(env):
3548                    return False
3549            return True
3550        elif self.cname in cpp_string_conversions:
3551            return True
3552        return False
3553
3554    def create_from_py_utility_code(self, env):
3555        if self.from_py_function is not None:
3556            return True
3557        if self.cname in builtin_cpp_conversions or self.cname in cpp_string_conversions:
3558            X = "XYZABC"
3559            tags = []
3560            context = {}
3561            for ix, T in enumerate(self.templates or []):
3562                if ix >= builtin_cpp_conversions[self.cname]:
3563                    break
3564                if T.is_pyobject or not T.create_from_py_utility_code(env):
3565                    return False
3566                tags.append(T.specialization_name())
3567                context[X[ix]] = T
3568
3569            if self.cname in cpp_string_conversions:
3570                cls = 'string'
3571                tags = type_identifier(self),
3572            else:
3573                cls = self.cname[5:]
3574            cname = '__pyx_convert_%s_from_py_%s' % (cls, '__and_'.join(tags))
3575            context.update({
3576                'cname': cname,
3577                'maybe_unordered': self.maybe_unordered(),
3578                'type': self.cname,
3579            })
3580            from .UtilityCode import CythonUtilityCode
3581            env.use_utility_code(CythonUtilityCode.load(
3582                cls.replace('unordered_', '') + ".from_py", "CppConvert.pyx",
3583                context=context, compiler_directives=env.directives))
3584            self.from_py_function = cname
3585            return True
3586
3587    def can_coerce_to_pyobject(self, env):
3588        if self.cname in builtin_cpp_conversions or self.cname in cpp_string_conversions:
3589            for ix, T in enumerate(self.templates or []):
3590                if ix >= builtin_cpp_conversions[self.cname]:
3591                    break
3592                if T.is_pyobject or not T.can_coerce_to_pyobject(env):
3593                    return False
3594            return True
3595
3596
3597    def create_to_py_utility_code(self, env):
3598        if self.to_py_function is not None:
3599            return True
3600        if self.cname in builtin_cpp_conversions or self.cname in cpp_string_conversions:
3601            X = "XYZABC"
3602            tags = []
3603            context = {}
3604            for ix, T in enumerate(self.templates or []):
3605                if ix >= builtin_cpp_conversions[self.cname]:
3606                    break
3607                if not T.create_to_py_utility_code(env):
3608                    return False
3609                tags.append(T.specialization_name())
3610                context[X[ix]] = T
3611
3612            if self.cname in cpp_string_conversions:
3613                cls = 'string'
3614                prefix = 'PyObject_'  # gets specialised by explicit type casts in CoerceToPyTypeNode
3615                tags = type_identifier(self),
3616            else:
3617                cls = self.cname[5:]
3618                prefix = ''
3619            cname = "__pyx_convert_%s%s_to_py_%s" % (prefix, cls, "____".join(tags))
3620            context.update({
3621                'cname': cname,
3622                'maybe_unordered': self.maybe_unordered(),
3623                'type': self.cname,
3624            })
3625            from .UtilityCode import CythonUtilityCode
3626            env.use_utility_code(CythonUtilityCode.load(
3627                cls.replace('unordered_', '') + ".to_py", "CppConvert.pyx",
3628                context=context, compiler_directives=env.directives))
3629            self.to_py_function = cname
3630            return True
3631
3632    def is_template_type(self):
3633        return self.templates is not None and self.template_type is None
3634
3635    def get_fused_types(self, result=None, seen=None):
3636        if result is None:
3637            result = []
3638            seen = set()
3639        if self.namespace:
3640            self.namespace.get_fused_types(result, seen)
3641        if self.templates:
3642            for T in self.templates:
3643                T.get_fused_types(result, seen)
3644        return result
3645
3646    def specialize_here(self, pos, template_values=None):
3647        if not self.is_template_type():
3648            error(pos, "'%s' type is not a template" % self)
3649            return error_type
3650        if len(self.templates) - self.num_optional_templates <= len(template_values) < len(self.templates):
3651            num_defaults = len(self.templates) - len(template_values)
3652            partial_specialization = self.declaration_code('', template_params=template_values)
3653            # Most of the time we don't need to declare anything typed to these
3654            # default template arguments, but when we do there's no way in C++
3655            # to reference this directly.  However, it is common convention to
3656            # provide a typedef in the template class that resolves to each
3657            # template type.  For now, allow the user to specify this name as
3658            # the template parameter.
3659            # TODO: Allow typedefs in cpp classes and search for it in this
3660            # classes scope as a concrete name we could use.
3661            template_values = template_values + [
3662                TemplatePlaceholderType(
3663                    "%s::%s" % (partial_specialization, param.name), True)
3664                for param in self.templates[-num_defaults:]]
3665        if len(self.templates) != len(template_values):
3666            error(pos, "%s templated type receives %d arguments, got %d" %
3667                  (self.name, len(self.templates), len(template_values)))
3668            return error_type
3669        has_object_template_param = False
3670        for value in template_values:
3671            if value.is_pyobject:
3672                has_object_template_param = True
3673                error(pos,
3674                      "Python object type '%s' cannot be used as a template argument" % value)
3675        if has_object_template_param:
3676            return error_type
3677        return self.specialize(dict(zip(self.templates, template_values)))
3678
3679    def specialize(self, values):
3680        if not self.templates and not self.namespace:
3681            return self
3682        if self.templates is None:
3683            self.templates = []
3684        key = tuple(values.items())
3685        if key in self.specializations:
3686            return self.specializations[key]
3687        template_values = [t.specialize(values) for t in self.templates]
3688        specialized = self.specializations[key] = \
3689            CppClassType(self.name, None, self.cname, [], template_values, template_type=self)
3690        # Need to do these *after* self.specializations[key] is set
3691        # to avoid infinite recursion on circular references.
3692        specialized.base_classes = [b.specialize(values) for b in self.base_classes]
3693        if self.namespace is not None:
3694            specialized.namespace = self.namespace.specialize(values)
3695        specialized.scope = self.scope.specialize(values, specialized)
3696        if self.cname == 'std::vector':
3697          # vector<bool> is special cased in the C++ standard, and its
3698          # accessors do not necessarily return references to the underlying
3699          # elements (which may be bit-packed).
3700          # http://www.cplusplus.com/reference/vector/vector-bool/
3701          # Here we pretend that the various methods return bool values
3702          # (as the actual returned values are coercable to such, and
3703          # we don't support call expressions as lvalues).
3704          T = values.get(self.templates[0], None)
3705          if T and not T.is_fused and T.empty_declaration_code() == 'bool':
3706            for bit_ref_returner in ('at', 'back', 'front'):
3707              if bit_ref_returner in specialized.scope.entries:
3708                specialized.scope.entries[bit_ref_returner].type.return_type = T
3709        return specialized
3710
3711    def deduce_template_params(self, actual):
3712        if actual.is_const:
3713            actual = actual.const_base_type
3714        if actual.is_reference:
3715            actual = actual.ref_base_type
3716        if self == actual:
3717            return {}
3718        elif actual.is_cpp_class:
3719            self_template_type = self
3720            while getattr(self_template_type, 'template_type', None):
3721                self_template_type = self_template_type.template_type
3722            def all_bases(cls):
3723                yield cls
3724                for parent in cls.base_classes:
3725                    for base in all_bases(parent):
3726                        yield base
3727            for actual_base in all_bases(actual):
3728                template_type = actual_base
3729                while getattr(template_type, 'template_type', None):
3730                    template_type = template_type.template_type
3731                    if (self_template_type.empty_declaration_code()
3732                            == template_type.empty_declaration_code()):
3733                        return reduce(
3734                            merge_template_deductions,
3735                            [formal_param.deduce_template_params(actual_param)
3736                             for (formal_param, actual_param)
3737                             in zip(self.templates, actual_base.templates)],
3738                            {})
3739        else:
3740            return {}
3741
3742    def declaration_code(self, entity_code,
3743            for_display = 0, dll_linkage = None, pyrex = 0,
3744            template_params = None):
3745        if template_params is None:
3746            template_params = self.templates
3747        if self.templates:
3748            template_strings = [param.declaration_code('', for_display, None, pyrex)
3749                                for param in template_params
3750                                if not is_optional_template_param(param) and not param.is_fused]
3751            if for_display:
3752                brackets = "[%s]"
3753            else:
3754                brackets = "<%s> "
3755            templates = brackets % ",".join(template_strings)
3756        else:
3757            templates = ""
3758        if pyrex or for_display:
3759            base_code = "%s%s" % (self.name, templates)
3760        else:
3761            base_code = "%s%s" % (self.cname, templates)
3762            if self.namespace is not None:
3763                base_code = "%s::%s" % (self.namespace.empty_declaration_code(), base_code)
3764            base_code = public_decl(base_code, dll_linkage)
3765        return self.base_declaration_code(base_code, entity_code)
3766
3767    def is_subclass(self, other_type):
3768        if self.same_as_resolved_type(other_type):
3769            return 1
3770        for base_class in self.base_classes:
3771            if base_class.is_subclass(other_type):
3772                return 1
3773        return 0
3774
3775    def subclass_dist(self, super_type):
3776        if self.same_as_resolved_type(super_type):
3777            return 0
3778        elif not self.base_classes:
3779            return float('inf')
3780        else:
3781            return 1 + min(b.subclass_dist(super_type) for b in self.base_classes)
3782
3783    def same_as_resolved_type(self, other_type):
3784        if other_type.is_cpp_class:
3785            if self == other_type:
3786                return 1
3787            # This messy logic is needed due to GH Issue #1852.
3788            elif (self.cname == other_type.cname and
3789                    (self.template_type and other_type.template_type
3790                     or self.templates
3791                     or other_type.templates)):
3792                if self.templates == other_type.templates:
3793                    return 1
3794                for t1, t2 in zip(self.templates, other_type.templates):
3795                    if is_optional_template_param(t1) and is_optional_template_param(t2):
3796                        break
3797                    if not t1.same_as_resolved_type(t2):
3798                        return 0
3799                return 1
3800        return 0
3801
3802    def assignable_from_resolved_type(self, other_type):
3803        # TODO: handle operator=(...) here?
3804        if other_type is error_type:
3805            return True
3806        elif other_type.is_cpp_class:
3807            return other_type.is_subclass(self)
3808        elif other_type.is_string and self.cname in cpp_string_conversions:
3809            return True
3810
3811    def attributes_known(self):
3812        return self.scope is not None
3813
3814    def find_cpp_operation_type(self, operator, operand_type=None):
3815        operands = [self]
3816        if operand_type is not None:
3817            operands.append(operand_type)
3818        # pos == None => no errors
3819        operator_entry = self.scope.lookup_operator_for_types(None, operator, operands)
3820        if not operator_entry:
3821            return None
3822        func_type = operator_entry.type
3823        if func_type.is_ptr:
3824            func_type = func_type.base_type
3825        return func_type.return_type
3826
3827    def get_constructor(self, pos):
3828        constructor = self.scope.lookup('<init>')
3829        if constructor is not None:
3830            return constructor
3831
3832        # Otherwise: automatically declare no-args default constructor.
3833        # Make it "nogil" if the base classes allow it.
3834        nogil = True
3835        for base in self.base_classes:
3836            base_constructor = base.scope.lookup('<init>')
3837            if base_constructor and not base_constructor.type.nogil:
3838                nogil = False
3839                break
3840
3841        func_type = CFuncType(self, [], exception_check='+', nogil=nogil)
3842        return self.scope.declare_cfunction(u'<init>', func_type, pos)
3843
3844    def check_nullary_constructor(self, pos, msg="stack allocated"):
3845        constructor = self.scope.lookup(u'<init>')
3846        if constructor is not None and best_match([], constructor.all_alternatives()) is None:
3847            error(pos, "C++ class must have a nullary constructor to be %s" % msg)
3848
3849
3850class TemplatePlaceholderType(CType):
3851
3852    def __init__(self, name, optional=False):
3853        self.name = name
3854        self.optional = optional
3855
3856    def declaration_code(self, entity_code,
3857            for_display = 0, dll_linkage = None, pyrex = 0):
3858        if entity_code:
3859            return self.name + " " + entity_code
3860        else:
3861            return self.name
3862
3863    def specialize(self, values):
3864        if self in values:
3865            return values[self]
3866        else:
3867            return self
3868
3869    def deduce_template_params(self, actual):
3870        return {self: actual}
3871
3872    def same_as_resolved_type(self, other_type):
3873        if isinstance(other_type, TemplatePlaceholderType):
3874            return self.name == other_type.name
3875        else:
3876            return 0
3877
3878    def __hash__(self):
3879        return hash(self.name)
3880
3881    def __cmp__(self, other):
3882        if isinstance(other, TemplatePlaceholderType):
3883            return cmp(self.name, other.name)
3884        else:
3885            return cmp(type(self), type(other))
3886
3887    def __eq__(self, other):
3888        if isinstance(other, TemplatePlaceholderType):
3889            return self.name == other.name
3890        else:
3891            return False
3892
3893def is_optional_template_param(type):
3894    return isinstance(type, TemplatePlaceholderType) and type.optional
3895
3896
3897class CEnumType(CIntLike, CType):
3898    #  name           string
3899    #  cname          string or None
3900    #  typedef_flag   boolean
3901    #  values         [string], populated during declaration analysis
3902
3903    is_enum = 1
3904    signed = 1
3905    rank = -1 # Ranks below any integer type
3906
3907    def __init__(self, name, cname, typedef_flag, namespace=None):
3908        self.name = name
3909        self.cname = cname
3910        self.values = []
3911        self.typedef_flag = typedef_flag
3912        self.namespace = namespace
3913        self.default_value = "(%s) 0" % self.empty_declaration_code()
3914
3915    def __str__(self):
3916        return self.name
3917
3918    def __repr__(self):
3919        return "<CEnumType %s %s%s>" % (self.name, self.cname,
3920            ("", " typedef")[self.typedef_flag])
3921
3922    def declaration_code(self, entity_code,
3923            for_display = 0, dll_linkage = None, pyrex = 0):
3924        if pyrex or for_display:
3925            base_code = self.name
3926        else:
3927            if self.namespace:
3928                base_code = "%s::%s" % (
3929                    self.namespace.empty_declaration_code(), self.cname)
3930            elif self.typedef_flag:
3931                base_code = self.cname
3932            else:
3933                base_code = "enum %s" % self.cname
3934            base_code = public_decl(base_code, dll_linkage)
3935        return self.base_declaration_code(base_code, entity_code)
3936
3937    def specialize(self, values):
3938        if self.namespace:
3939            namespace = self.namespace.specialize(values)
3940            if namespace != self.namespace:
3941                return CEnumType(
3942                    self.name, self.cname, self.typedef_flag, namespace)
3943        return self
3944
3945    def create_type_wrapper(self, env):
3946        from .UtilityCode import CythonUtilityCode
3947        env.use_utility_code(CythonUtilityCode.load(
3948            "EnumType", "CpdefEnums.pyx",
3949            context={"name": self.name,
3950                     "items": tuple(self.values)},
3951            outer_module_scope=env.global_scope()))
3952
3953
3954class CTupleType(CType):
3955    # components [PyrexType]
3956
3957    is_ctuple = True
3958
3959    def __init__(self, cname, components):
3960        self.cname = cname
3961        self.components = components
3962        self.size = len(components)
3963        self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
3964        self.from_py_function = "%s_from_py_%s" % (Naming.convert_func_prefix, self.cname)
3965        self.exception_check = True
3966        self._convert_to_py_code = None
3967        self._convert_from_py_code = None
3968
3969    def __str__(self):
3970        return "(%s)" % ", ".join(str(c) for c in self.components)
3971
3972    def declaration_code(self, entity_code,
3973            for_display = 0, dll_linkage = None, pyrex = 0):
3974        if pyrex or for_display:
3975            return str(self)
3976        else:
3977            return self.base_declaration_code(self.cname, entity_code)
3978
3979    def can_coerce_to_pyobject(self, env):
3980        for component in self.components:
3981            if not component.can_coerce_to_pyobject(env):
3982                return False
3983        return True
3984
3985    def can_coerce_from_pyobject(self, env):
3986        for component in self.components:
3987            if not component.can_coerce_from_pyobject(env):
3988                return False
3989        return True
3990
3991    def create_to_py_utility_code(self, env):
3992        if self._convert_to_py_code is False:
3993            return None  # tri-state-ish
3994
3995        if self._convert_to_py_code is None:
3996            for component in self.components:
3997                if not component.create_to_py_utility_code(env):
3998                    self.to_py_function = None
3999                    self._convert_to_py_code = False
4000                    return False
4001
4002            context = dict(
4003                struct_type_decl=self.empty_declaration_code(),
4004                components=self.components,
4005                funcname=self.to_py_function,
4006                size=len(self.components)
4007            )
4008            self._convert_to_py_code = TempitaUtilityCode.load(
4009                "ToPyCTupleUtility", "TypeConversion.c", context=context)
4010
4011        env.use_utility_code(self._convert_to_py_code)
4012        return True
4013
4014    def create_from_py_utility_code(self, env):
4015        if self._convert_from_py_code is False:
4016            return None  # tri-state-ish
4017
4018        if self._convert_from_py_code is None:
4019            for component in self.components:
4020                if not component.create_from_py_utility_code(env):
4021                    self.from_py_function = None
4022                    self._convert_from_py_code = False
4023                    return False
4024
4025            context = dict(
4026                struct_type_decl=self.empty_declaration_code(),
4027                components=self.components,
4028                funcname=self.from_py_function,
4029                size=len(self.components)
4030            )
4031            self._convert_from_py_code = TempitaUtilityCode.load(
4032                "FromPyCTupleUtility", "TypeConversion.c", context=context)
4033
4034        env.use_utility_code(self._convert_from_py_code)
4035        return True
4036
4037    def cast_code(self, expr_code):
4038        return expr_code
4039
4040
4041def c_tuple_type(components):
4042    components = tuple(components)
4043    cname = Naming.ctuple_type_prefix + type_list_identifier(components)
4044    tuple_type = CTupleType(cname, components)
4045    return tuple_type
4046
4047
4048class UnspecifiedType(PyrexType):
4049    # Used as a placeholder until the type can be determined.
4050
4051    is_unspecified = 1
4052
4053    def declaration_code(self, entity_code,
4054            for_display = 0, dll_linkage = None, pyrex = 0):
4055        return "<unspecified>"
4056
4057    def same_as_resolved_type(self, other_type):
4058        return False
4059
4060
4061class ErrorType(PyrexType):
4062    # Used to prevent propagation of error messages.
4063
4064    is_error = 1
4065    exception_value = "0"
4066    exception_check    = 0
4067    to_py_function = "dummy"
4068    from_py_function = "dummy"
4069
4070    def create_to_py_utility_code(self, env):
4071        return True
4072
4073    def create_from_py_utility_code(self, env):
4074        return True
4075
4076    def declaration_code(self, entity_code,
4077            for_display = 0, dll_linkage = None, pyrex = 0):
4078        return "<error>"
4079
4080    def same_as_resolved_type(self, other_type):
4081        return 1
4082
4083    def error_condition(self, result_code):
4084        return "dummy"
4085
4086
4087rank_to_type_name = (
4088    "char",         # 0
4089    "short",        # 1
4090    "int",          # 2
4091    "long",         # 3
4092    "PY_LONG_LONG", # 4
4093    "float",        # 5
4094    "double",       # 6
4095    "long double",  # 7
4096)
4097
4098_rank_to_type_name = list(rank_to_type_name)
4099RANK_INT  = _rank_to_type_name.index('int')
4100RANK_LONG = _rank_to_type_name.index('long')
4101RANK_FLOAT = _rank_to_type_name.index('float')
4102UNSIGNED = 0
4103SIGNED = 2
4104
4105error_type =    ErrorType()
4106unspecified_type = UnspecifiedType()
4107
4108py_object_type = PyObjectType()
4109
4110c_void_type =        CVoidType()
4111
4112c_uchar_type =       CIntType(0, UNSIGNED)
4113c_ushort_type =      CIntType(1, UNSIGNED)
4114c_uint_type =        CIntType(2, UNSIGNED)
4115c_ulong_type =       CIntType(3, UNSIGNED)
4116c_ulonglong_type =   CIntType(4, UNSIGNED)
4117
4118c_char_type =        CIntType(0)
4119c_short_type =       CIntType(1)
4120c_int_type =         CIntType(2)
4121c_long_type =        CIntType(3)
4122c_longlong_type =    CIntType(4)
4123
4124c_schar_type =       CIntType(0, SIGNED)
4125c_sshort_type =      CIntType(1, SIGNED)
4126c_sint_type =        CIntType(2, SIGNED)
4127c_slong_type =       CIntType(3, SIGNED)
4128c_slonglong_type =   CIntType(4, SIGNED)
4129
4130c_float_type =       CFloatType(5, math_h_modifier='f')
4131c_double_type =      CFloatType(6)
4132c_longdouble_type =  CFloatType(7, math_h_modifier='l')
4133
4134c_float_complex_type =      CComplexType(c_float_type)
4135c_double_complex_type =     CComplexType(c_double_type)
4136c_longdouble_complex_type = CComplexType(c_longdouble_type)
4137
4138c_anon_enum_type =   CAnonEnumType(-1)
4139c_returncode_type =  CReturnCodeType(RANK_INT)
4140c_bint_type =        CBIntType(RANK_INT)
4141c_py_unicode_type =  CPyUnicodeIntType(RANK_INT-0.5, UNSIGNED)
4142c_py_ucs4_type =     CPyUCS4IntType(RANK_LONG-0.5, UNSIGNED)
4143c_py_hash_t_type =   CPyHashTType(RANK_LONG+0.5, SIGNED)
4144c_py_ssize_t_type =  CPySSizeTType(RANK_LONG+0.5, SIGNED)
4145c_ssize_t_type =     CSSizeTType(RANK_LONG+0.5, SIGNED)
4146c_size_t_type =      CSizeTType(RANK_LONG+0.5, UNSIGNED)
4147c_ptrdiff_t_type =   CPtrdiffTType(RANK_LONG+0.75, SIGNED)
4148
4149c_null_ptr_type =     CNullPtrType(c_void_type)
4150c_void_ptr_type =     CPtrType(c_void_type)
4151c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
4152c_char_ptr_type =     CPtrType(c_char_type)
4153c_const_char_ptr_type = CPtrType(CConstType(c_char_type))
4154c_uchar_ptr_type =    CPtrType(c_uchar_type)
4155c_const_uchar_ptr_type = CPtrType(CConstType(c_uchar_type))
4156c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
4157c_int_ptr_type =      CPtrType(c_int_type)
4158c_py_unicode_ptr_type = CPtrType(c_py_unicode_type)
4159c_const_py_unicode_ptr_type = CPtrType(CConstType(c_py_unicode_type))
4160c_py_ssize_t_ptr_type =  CPtrType(c_py_ssize_t_type)
4161c_ssize_t_ptr_type =  CPtrType(c_ssize_t_type)
4162c_size_t_ptr_type =  CPtrType(c_size_t_type)
4163
4164# GIL state
4165c_gilstate_type = CEnumType("PyGILState_STATE", "PyGILState_STATE", True)
4166c_threadstate_type = CStructOrUnionType("PyThreadState", "struct", None, 1, "PyThreadState")
4167c_threadstate_ptr_type = CPtrType(c_threadstate_type)
4168
4169# PEP-539 "Py_tss_t" type
4170c_pytss_t_type = CPyTSSTType()
4171
4172# the Py_buffer type is defined in Builtin.py
4173c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
4174c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
4175
4176# Not sure whether the unsigned versions and 'long long' should be in there
4177# long long requires C99 and might be slow, and would always get preferred
4178# when specialization happens through calling and not indexing
4179cy_integral_type = FusedType([c_short_type, c_int_type, c_long_type],
4180                             name="integral")
4181# Omitting long double as it might be slow
4182cy_floating_type = FusedType([c_float_type, c_double_type], name="floating")
4183cy_numeric_type = FusedType([c_short_type,
4184                             c_int_type,
4185                             c_long_type,
4186                             c_float_type,
4187                             c_double_type,
4188                             c_float_complex_type,
4189                             c_double_complex_type], name="numeric")
4190
4191# buffer-related structs
4192c_buf_diminfo_type =  CStructOrUnionType("__Pyx_Buf_DimInfo", "struct",
4193                                      None, 1, "__Pyx_Buf_DimInfo")
4194c_pyx_buffer_type = CStructOrUnionType("__Pyx_Buffer", "struct", None, 1, "__Pyx_Buffer")
4195c_pyx_buffer_ptr_type = CPtrType(c_pyx_buffer_type)
4196c_pyx_buffer_nd_type = CStructOrUnionType("__Pyx_LocalBuf_ND", "struct",
4197                                      None, 1, "__Pyx_LocalBuf_ND")
4198
4199cython_memoryview_type = CStructOrUnionType("__pyx_memoryview_obj", "struct",
4200                                      None, 0, "__pyx_memoryview_obj")
4201
4202memoryviewslice_type = CStructOrUnionType("memoryviewslice", "struct",
4203                                          None, 1, "__Pyx_memviewslice")
4204
4205modifiers_and_name_to_type = {
4206    #(signed, longness, name) : type
4207    (0,  0, "char"): c_uchar_type,
4208    (1,  0, "char"): c_char_type,
4209    (2,  0, "char"): c_schar_type,
4210
4211    (0, -1, "int"): c_ushort_type,
4212    (0,  0, "int"): c_uint_type,
4213    (0,  1, "int"): c_ulong_type,
4214    (0,  2, "int"): c_ulonglong_type,
4215
4216    (1, -1, "int"): c_short_type,
4217    (1,  0, "int"): c_int_type,
4218    (1,  1, "int"): c_long_type,
4219    (1,  2, "int"): c_longlong_type,
4220
4221    (2, -1, "int"): c_sshort_type,
4222    (2,  0, "int"): c_sint_type,
4223    (2,  1, "int"): c_slong_type,
4224    (2,  2, "int"): c_slonglong_type,
4225
4226    (1,  0, "float"):  c_float_type,
4227    (1,  0, "double"): c_double_type,
4228    (1,  1, "double"): c_longdouble_type,
4229
4230    (1,  0, "complex"):  c_double_complex_type,  # C: float, Python: double => Python wins
4231    (1,  0, "floatcomplex"):  c_float_complex_type,
4232    (1,  0, "doublecomplex"): c_double_complex_type,
4233    (1,  1, "doublecomplex"): c_longdouble_complex_type,
4234
4235    #
4236    (1,  0, "void"): c_void_type,
4237    (1,  0, "Py_tss_t"): c_pytss_t_type,
4238
4239    (1,  0, "bint"):       c_bint_type,
4240    (0,  0, "Py_UNICODE"): c_py_unicode_type,
4241    (0,  0, "Py_UCS4"):    c_py_ucs4_type,
4242    (2,  0, "Py_hash_t"):  c_py_hash_t_type,
4243    (2,  0, "Py_ssize_t"): c_py_ssize_t_type,
4244    (2,  0, "ssize_t") :   c_ssize_t_type,
4245    (0,  0, "size_t") :    c_size_t_type,
4246    (2,  0, "ptrdiff_t") : c_ptrdiff_t_type,
4247
4248    (1,  0, "object"): py_object_type,
4249}
4250
4251def is_promotion(src_type, dst_type):
4252    # It's hard to find a hard definition of promotion, but empirical
4253    # evidence suggests that the below is all that's allowed.
4254    if src_type.is_numeric:
4255        if dst_type.same_as(c_int_type):
4256            unsigned = (not src_type.signed)
4257            return (src_type.is_enum or
4258                    (src_type.is_int and
4259                     unsigned + src_type.rank < dst_type.rank))
4260        elif dst_type.same_as(c_double_type):
4261            return src_type.is_float and src_type.rank <= dst_type.rank
4262    return False
4263
4264def best_match(arg_types, functions, pos=None, env=None, args=None):
4265    """
4266    Given a list args of arguments and a list of functions, choose one
4267    to call which seems to be the "best" fit for this list of arguments.
4268    This function is used, e.g., when deciding which overloaded method
4269    to dispatch for C++ classes.
4270
4271    We first eliminate functions based on arity, and if only one
4272    function has the correct arity, we return it. Otherwise, we weight
4273    functions based on how much work must be done to convert the
4274    arguments, with the following priorities:
4275      * identical types or pointers to identical types
4276      * promotions
4277      * non-Python types
4278    That is, we prefer functions where no arguments need converted,
4279    and failing that, functions where only promotions are required, and
4280    so on.
4281
4282    If no function is deemed a good fit, or if two or more functions have
4283    the same weight, we return None (as there is no best match). If pos
4284    is not None, we also generate an error.
4285    """
4286    # TODO: args should be a list of types, not a list of Nodes.
4287    actual_nargs = len(arg_types)
4288
4289    candidates = []
4290    errors = []
4291    for func in functions:
4292        error_mesg = ""
4293        func_type = func.type
4294        if func_type.is_ptr:
4295            func_type = func_type.base_type
4296        # Check function type
4297        if not func_type.is_cfunction:
4298            if not func_type.is_error and pos is not None:
4299                error_mesg = "Calling non-function type '%s'" % func_type
4300            errors.append((func, error_mesg))
4301            continue
4302        # Check no. of args
4303        max_nargs = len(func_type.args)
4304        min_nargs = max_nargs - func_type.optional_arg_count
4305        if actual_nargs < min_nargs or \
4306            (not func_type.has_varargs and actual_nargs > max_nargs):
4307            if max_nargs == min_nargs and not func_type.has_varargs:
4308                expectation = max_nargs
4309            elif actual_nargs < min_nargs:
4310                expectation = "at least %s" % min_nargs
4311            else:
4312                expectation = "at most %s" % max_nargs
4313            error_mesg = "Call with wrong number of arguments (expected %s, got %s)" \
4314                         % (expectation, actual_nargs)
4315            errors.append((func, error_mesg))
4316            continue
4317        if func_type.templates:
4318            deductions = reduce(
4319                merge_template_deductions,
4320                [pattern.type.deduce_template_params(actual) for (pattern, actual) in zip(func_type.args, arg_types)],
4321                {})
4322            if deductions is None:
4323                errors.append((func, "Unable to deduce type parameters for %s given (%s)" % (func_type, ', '.join(map(str, arg_types)))))
4324            elif len(deductions) < len(func_type.templates):
4325                errors.append((func, "Unable to deduce type parameter %s" % (
4326                    ", ".join([param.name for param in set(func_type.templates) - set(deductions.keys())]))))
4327            else:
4328                type_list = [deductions[param] for param in func_type.templates]
4329                from .Symtab import Entry
4330                specialization = Entry(
4331                    name = func.name + "[%s]" % ",".join([str(t) for t in type_list]),
4332                    cname = func.cname + "<%s>" % ",".join([t.empty_declaration_code() for t in type_list]),
4333                    type = func_type.specialize(deductions),
4334                    pos = func.pos)
4335                candidates.append((specialization, specialization.type))
4336        else:
4337            candidates.append((func, func_type))
4338
4339    # Optimize the most common case of no overloading...
4340    if len(candidates) == 1:
4341        return candidates[0][0]
4342    elif len(candidates) == 0:
4343        if pos is not None:
4344            func, errmsg = errors[0]
4345            if len(errors) == 1 or [1 for func, e in errors if e == errmsg]:
4346                error(pos, errmsg)
4347            else:
4348                error(pos, "no suitable method found")
4349        return None
4350
4351    possibilities = []
4352    bad_types = []
4353    needed_coercions = {}
4354
4355    for index, (func, func_type) in enumerate(candidates):
4356        score = [0,0,0,0,0,0,0]
4357        for i in range(min(actual_nargs, len(func_type.args))):
4358            src_type = arg_types[i]
4359            dst_type = func_type.args[i].type
4360
4361            assignable = dst_type.assignable_from(src_type)
4362
4363            # Now take care of unprefixed string literals. So when you call a cdef
4364            # function that takes a char *, the coercion will mean that the
4365            # type will simply become bytes. We need to do this coercion
4366            # manually for overloaded and fused functions
4367            if not assignable:
4368                c_src_type = None
4369                if src_type.is_pyobject:
4370                    if src_type.is_builtin_type and src_type.name == 'str' and dst_type.resolve().is_string:
4371                        c_src_type = dst_type.resolve()
4372                    else:
4373                        c_src_type = src_type.default_coerced_ctype()
4374                elif src_type.is_pythran_expr:
4375                        c_src_type = src_type.org_buffer
4376
4377                if c_src_type is not None:
4378                    assignable = dst_type.assignable_from(c_src_type)
4379                    if assignable:
4380                        src_type = c_src_type
4381                        needed_coercions[func] = (i, dst_type)
4382
4383            if assignable:
4384                if src_type == dst_type or dst_type.same_as(src_type):
4385                    pass  # score 0
4386                elif func_type.is_strict_signature:
4387                    break  # exact match requested but not found
4388                elif is_promotion(src_type, dst_type):
4389                    score[2] += 1
4390                elif ((src_type.is_int and dst_type.is_int) or
4391                      (src_type.is_float and dst_type.is_float)):
4392                    score[2] += abs(dst_type.rank + (not dst_type.signed) -
4393                                    (src_type.rank + (not src_type.signed))) + 1
4394                elif dst_type.is_ptr and src_type.is_ptr:
4395                    if dst_type.base_type == c_void_type:
4396                        score[4] += 1
4397                    elif src_type.base_type.is_cpp_class and src_type.base_type.is_subclass(dst_type.base_type):
4398                        score[6] += src_type.base_type.subclass_dist(dst_type.base_type)
4399                    else:
4400                        score[5] += 1
4401                elif not src_type.is_pyobject:
4402                    score[1] += 1
4403                else:
4404                    score[0] += 1
4405            else:
4406                error_mesg = "Invalid conversion from '%s' to '%s'" % (src_type, dst_type)
4407                bad_types.append((func, error_mesg))
4408                break
4409        else:
4410            possibilities.append((score, index, func))  # so we can sort it
4411
4412    if possibilities:
4413        possibilities.sort()
4414        if len(possibilities) > 1:
4415            score1 = possibilities[0][0]
4416            score2 = possibilities[1][0]
4417            if score1 == score2:
4418                if pos is not None:
4419                    error(pos, "ambiguous overloaded method")
4420                return None
4421
4422        function = possibilities[0][-1]
4423
4424        if function in needed_coercions and env:
4425            arg_i, coerce_to_type = needed_coercions[function]
4426            args[arg_i] = args[arg_i].coerce_to(coerce_to_type, env)
4427
4428        return function
4429
4430    if pos is not None:
4431        if len(bad_types) == 1:
4432            error(pos, bad_types[0][1])
4433        else:
4434            error(pos, "no suitable method found")
4435
4436    return None
4437
4438def merge_template_deductions(a, b):
4439    if a is None or b is None:
4440        return None
4441    all = a
4442    for param, value in b.items():
4443        if param in all:
4444            if a[param] != b[param]:
4445                return None
4446        else:
4447            all[param] = value
4448    return all
4449
4450
4451def widest_numeric_type(type1, type2):
4452    """Given two numeric types, return the narrowest type encompassing both of them.
4453    """
4454    if type1.is_reference:
4455        type1 = type1.ref_base_type
4456    if type2.is_reference:
4457        type2 = type2.ref_base_type
4458    if type1.is_const:
4459        type1 = type1.const_base_type
4460    if type2.is_const:
4461        type2 = type2.const_base_type
4462    if type1 == type2:
4463        widest_type = type1
4464    elif type1.is_complex or type2.is_complex:
4465        def real_type(ntype):
4466            if ntype.is_complex:
4467                return ntype.real_type
4468            return ntype
4469        widest_type = CComplexType(
4470            widest_numeric_type(
4471                real_type(type1),
4472                real_type(type2)))
4473    elif type1.is_enum and type2.is_enum:
4474        widest_type = c_int_type
4475    elif type1.rank < type2.rank:
4476        widest_type = type2
4477    elif type1.rank > type2.rank:
4478        widest_type = type1
4479    elif type1.signed < type2.signed:
4480        widest_type = type1
4481    elif type1.signed > type2.signed:
4482        widest_type = type2
4483    elif type1.is_typedef > type2.is_typedef:
4484        widest_type = type1
4485    else:
4486        widest_type = type2
4487    return widest_type
4488
4489
4490def numeric_type_fits(small_type, large_type):
4491    return widest_numeric_type(small_type, large_type) == large_type
4492
4493
4494def independent_spanning_type(type1, type2):
4495    # Return a type assignable independently from both type1 and
4496    # type2, but do not require any interoperability between the two.
4497    # For example, in "True * 2", it is safe to assume an integer
4498    # result type (so spanning_type() will do the right thing),
4499    # whereas "x = True or 2" must evaluate to a type that can hold
4500    # both a boolean value and an integer, so this function works
4501    # better.
4502    if type1.is_reference ^ type2.is_reference:
4503        if type1.is_reference:
4504            type1 = type1.ref_base_type
4505        else:
4506            type2 = type2.ref_base_type
4507    if type1 == type2:
4508        return type1
4509    elif (type1 is c_bint_type or type2 is c_bint_type) and (type1.is_numeric and type2.is_numeric):
4510        # special case: if one of the results is a bint and the other
4511        # is another C integer, we must prevent returning a numeric
4512        # type so that we do not lose the ability to coerce to a
4513        # Python bool if we have to.
4514        return py_object_type
4515    span_type = _spanning_type(type1, type2)
4516    if span_type is None:
4517        return error_type
4518    return span_type
4519
4520def spanning_type(type1, type2):
4521    # Return a type assignable from both type1 and type2, or
4522    # py_object_type if no better type is found.  Assumes that the
4523    # code that calls this will try a coercion afterwards, which will
4524    # fail if the types cannot actually coerce to a py_object_type.
4525    if type1 == type2:
4526        return type1
4527    elif type1 is py_object_type or type2 is py_object_type:
4528        return py_object_type
4529    elif type1 is c_py_unicode_type or type2 is c_py_unicode_type:
4530        # Py_UNICODE behaves more like a string than an int
4531        return py_object_type
4532    span_type = _spanning_type(type1, type2)
4533    if span_type is None:
4534        return py_object_type
4535    return span_type
4536
4537def _spanning_type(type1, type2):
4538    if type1.is_numeric and type2.is_numeric:
4539        return widest_numeric_type(type1, type2)
4540    elif type1.is_builtin_type and type1.name == 'float' and type2.is_numeric:
4541        return widest_numeric_type(c_double_type, type2)
4542    elif type2.is_builtin_type and type2.name == 'float' and type1.is_numeric:
4543        return widest_numeric_type(type1, c_double_type)
4544    elif type1.is_extension_type and type2.is_extension_type:
4545        return widest_extension_type(type1, type2)
4546    elif type1.is_pyobject or type2.is_pyobject:
4547        return py_object_type
4548    elif type1.assignable_from(type2):
4549        if type1.is_extension_type and type1.typeobj_is_imported():
4550            # external types are unsafe, so we use PyObject instead
4551            return py_object_type
4552        return type1
4553    elif type2.assignable_from(type1):
4554        if type2.is_extension_type and type2.typeobj_is_imported():
4555            # external types are unsafe, so we use PyObject instead
4556            return py_object_type
4557        return type2
4558    elif type1.is_ptr and type2.is_ptr:
4559        if type1.base_type.is_cpp_class and type2.base_type.is_cpp_class:
4560            common_base = widest_cpp_type(type1.base_type, type2.base_type)
4561            if common_base:
4562                return CPtrType(common_base)
4563        # incompatible pointers, void* will do as a result
4564        return c_void_ptr_type
4565    else:
4566        return None
4567
4568def widest_extension_type(type1, type2):
4569    if type1.typeobj_is_imported() or type2.typeobj_is_imported():
4570        return py_object_type
4571    while True:
4572        if type1.subtype_of(type2):
4573            return type2
4574        elif type2.subtype_of(type1):
4575            return type1
4576        type1, type2 = type1.base_type, type2.base_type
4577        if type1 is None or type2 is None:
4578            return py_object_type
4579
4580def widest_cpp_type(type1, type2):
4581    @cached_function
4582    def bases(type):
4583        all = set()
4584        for base in type.base_classes:
4585            all.add(base)
4586            all.update(bases(base))
4587        return all
4588    common_bases = bases(type1).intersection(bases(type2))
4589    common_bases_bases = reduce(set.union, [bases(b) for b in common_bases], set())
4590    candidates = [b for b in common_bases if b not in common_bases_bases]
4591    if len(candidates) == 1:
4592        return candidates[0]
4593    else:
4594        # Fall back to void* for now.
4595        return None
4596
4597
4598def simple_c_type(signed, longness, name):
4599    # Find type descriptor for simple type given name and modifiers.
4600    # Returns None if arguments don't make sense.
4601    return modifiers_and_name_to_type.get((signed, longness, name))
4602
4603def parse_basic_type(name):
4604    base = None
4605    if name.startswith('p_'):
4606        base = parse_basic_type(name[2:])
4607    elif name.startswith('p'):
4608        base = parse_basic_type(name[1:])
4609    elif name.endswith('*'):
4610        base = parse_basic_type(name[:-1])
4611    if base:
4612        return CPtrType(base)
4613    #
4614    basic_type = simple_c_type(1, 0, name)
4615    if basic_type:
4616        return basic_type
4617    #
4618    signed = 1
4619    longness = 0
4620    if name == 'Py_UNICODE':
4621        signed = 0
4622    elif name == 'Py_UCS4':
4623        signed = 0
4624    elif name == 'Py_hash_t':
4625        signed = 2
4626    elif name == 'Py_ssize_t':
4627        signed = 2
4628    elif name == 'ssize_t':
4629        signed = 2
4630    elif name == 'size_t':
4631        signed = 0
4632    else:
4633        if name.startswith('u'):
4634            name = name[1:]
4635            signed = 0
4636        elif (name.startswith('s') and
4637              not name.startswith('short')):
4638            name = name[1:]
4639            signed = 2
4640        longness = 0
4641        while name.startswith('short'):
4642            name = name.replace('short', '', 1).strip()
4643            longness -= 1
4644        while name.startswith('long'):
4645            name = name.replace('long', '', 1).strip()
4646            longness += 1
4647        if longness != 0 and not name:
4648            name = 'int'
4649    return simple_c_type(signed, longness, name)
4650
4651def c_array_type(base_type, size):
4652    # Construct a C array type.
4653    if base_type is error_type:
4654        return error_type
4655    else:
4656        return CArrayType(base_type, size)
4657
4658def c_ptr_type(base_type):
4659    # Construct a C pointer type.
4660    if base_type is error_type:
4661        return error_type
4662    elif base_type.is_reference:
4663        return CPtrType(base_type.ref_base_type)
4664    else:
4665        return CPtrType(base_type)
4666
4667def c_ref_type(base_type):
4668    # Construct a C reference type
4669    if base_type is error_type:
4670        return error_type
4671    else:
4672        return CReferenceType(base_type)
4673
4674def c_const_type(base_type):
4675    # Construct a C const type.
4676    if base_type is error_type:
4677        return error_type
4678    else:
4679        return CConstType(base_type)
4680
4681def same_type(type1, type2):
4682    return type1.same_as(type2)
4683
4684def assignable_from(type1, type2):
4685    return type1.assignable_from(type2)
4686
4687def typecast(to_type, from_type, expr_code):
4688    #  Return expr_code cast to a C type which can be
4689    #  assigned to to_type, assuming its existing C type
4690    #  is from_type.
4691    if (to_type is from_type or
4692            (not to_type.is_pyobject and assignable_from(to_type, from_type))):
4693        return expr_code
4694    elif (to_type is py_object_type and from_type and
4695            from_type.is_builtin_type and from_type.name != 'type'):
4696        # no cast needed, builtins are PyObject* already
4697        return expr_code
4698    else:
4699        #print "typecast: to", to_type, "from", from_type ###
4700        return to_type.cast_code(expr_code)
4701
4702def type_list_identifier(types):
4703    return cap_length('__and_'.join(type_identifier(type) for type in types))
4704
4705_type_identifier_cache = {}
4706def type_identifier(type):
4707    decl = type.empty_declaration_code()
4708    safe = _type_identifier_cache.get(decl)
4709    if safe is None:
4710        safe = decl
4711        safe = re.sub(' +', ' ', safe)
4712        safe = re.sub(' ([^a-zA-Z0-9_])', r'\1', safe)
4713        safe = re.sub('([^a-zA-Z0-9_]) ', r'\1', safe)
4714        safe = (safe.replace('__', '__dunder')
4715                    .replace('const ', '__const_')
4716                    .replace(' ', '__space_')
4717                    .replace('*', '__ptr')
4718                    .replace('&', '__ref')
4719                    .replace('[', '__lArr')
4720                    .replace(']', '__rArr')
4721                    .replace('<', '__lAng')
4722                    .replace('>', '__rAng')
4723                    .replace('(', '__lParen')
4724                    .replace(')', '__rParen')
4725                    .replace(',', '__comma_')
4726                    .replace('::', '__in_'))
4727        safe = cap_length(re.sub('[^a-zA-Z0-9_]', lambda x: '__%X' % ord(x.group(0)), safe))
4728        _type_identifier_cache[decl] = safe
4729    return safe
4730
4731def cap_length(s, max_prefix=63, max_len=1024):
4732    if len(s) <= max_prefix:
4733        return s
4734    hash_prefix = hashlib.sha256(s.encode('ascii')).hexdigest()[:6]
4735    return '%s__%s__etc' % (hash_prefix, s[:max_len-17])
4736