1#
2#   Parse tree nodes for expressions
3#
4
5import cython
6cython.declare(error=object, warning=object, warn_once=object, InternalError=object,
7               CompileError=object, UtilityCode=object, TempitaUtilityCode=object,
8               StringEncoding=object, operator=object,
9               Naming=object, Nodes=object, PyrexTypes=object, py_object_type=object,
10               list_type=object, tuple_type=object, set_type=object, dict_type=object,
11               unicode_type=object, str_type=object, bytes_type=object, type_type=object,
12               Builtin=object, Symtab=object, Utils=object, find_coercion_error=object,
13               debug_disposal_code=object, debug_temp_alloc=object, debug_coercion=object,
14               bytearray_type=object, slice_type=object)
15
16import sys
17import copy
18import operator
19
20from Errors import error, warning, warn_once, InternalError, CompileError
21from Errors import hold_errors, release_errors, held_errors, report_error
22from Code import UtilityCode, TempitaUtilityCode
23import StringEncoding
24import Naming
25import Nodes
26from Nodes import Node
27import PyrexTypes
28from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
29    unspecified_type
30import TypeSlots
31from Builtin import list_type, tuple_type, set_type, dict_type, type_type, \
32     unicode_type, str_type, bytes_type, bytearray_type, basestring_type, slice_type
33import Builtin
34import Symtab
35from Cython import Utils
36from Annotate import AnnotationItem
37from Cython.Compiler import Future
38from Cython.Debugging import print_call_chain
39from DebugFlags import debug_disposal_code, debug_temp_alloc, \
40    debug_coercion
41
42try:
43    from __builtin__ import basestring
44except ImportError:
45    basestring = str # Python 3
46
47try:
48    from builtins import bytes
49except ImportError:
50    bytes = str # Python 2
51
52
53class NotConstant(object):
54    _obj = None
55
56    def __new__(cls):
57        if NotConstant._obj is None:
58            NotConstant._obj = super(NotConstant, cls).__new__(cls)
59
60        return NotConstant._obj
61
62    def __repr__(self):
63        return "<NOT CONSTANT>"
64
65not_a_constant = NotConstant()
66constant_value_not_set = object()
67
68# error messages when coercing from key[0] to key[1]
69coercion_error_dict = {
70    # string related errors
71    (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
72    (Builtin.unicode_type, Builtin.str_type)   : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
73    (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects only support coercion to Py_UNICODE*.",
74    (Builtin.unicode_type, PyrexTypes.c_uchar_ptr_type) : "Unicode objects only support coercion to Py_UNICODE*.",
75    (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
76    (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
77    (Builtin.bytes_type, Builtin.basestring_type) : "Cannot convert 'bytes' object to basestring implicitly. This is not portable to Py3.",
78    (Builtin.bytes_type, PyrexTypes.c_py_unicode_ptr_type) : "Cannot convert 'bytes' object to Py_UNICODE*, use 'unicode'.",
79    (Builtin.basestring_type, Builtin.bytes_type) : "Cannot convert 'basestring' object to bytes implicitly. This is not portable.",
80    (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
81    (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
82    (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
83    (Builtin.str_type, PyrexTypes.c_uchar_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
84    (Builtin.str_type, PyrexTypes.c_py_unicode_ptr_type) : "'str' objects do not support coercion to C types (use 'unicode'?).",
85    (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
86    (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
87}
88
89def find_coercion_error(type_tuple, default, env):
90    err = coercion_error_dict.get(type_tuple)
91    if err is None:
92        return default
93    elif ((PyrexTypes.c_char_ptr_type in type_tuple or PyrexTypes.c_uchar_ptr_type in type_tuple)
94            and env.directives['c_string_encoding']):
95        if type_tuple[1].is_pyobject:
96            return default
97        elif env.directives['c_string_encoding'] in ('ascii', 'default'):
98            return default
99        else:
100            return "'%s' objects do not support coercion to C types with non-ascii or non-default c_string_encoding" % type_tuple[0].name
101    else:
102        return err
103
104
105def default_str_type(env):
106    return {
107        'bytes': bytes_type,
108        'bytearray': bytearray_type,
109        'str': str_type,
110        'unicode': unicode_type
111    }.get(env.directives['c_string_type'])
112
113
114def check_negative_indices(*nodes):
115    """
116    Raise a warning on nodes that are known to have negative numeric values.
117    Used to find (potential) bugs inside of "wraparound=False" sections.
118    """
119    for node in nodes:
120        if (node is None
121                or not isinstance(node.constant_result, (int, float, long))):
122            continue
123        if node.constant_result < 0:
124            warning(node.pos,
125                    "the result of using negative indices inside of "
126                    "code sections marked as 'wraparound=False' is "
127                    "undefined", level=1)
128
129
130def infer_sequence_item_type(env, seq_node, index_node=None, seq_type=None):
131    if not seq_node.is_sequence_constructor:
132        if seq_type is None:
133            seq_type = seq_node.infer_type(env)
134        if seq_type is tuple_type:
135            # tuples are immutable => we can safely follow assignments
136            if seq_node.cf_state and len(seq_node.cf_state) == 1:
137                try:
138                    seq_node = seq_node.cf_state[0].rhs
139                except AttributeError:
140                    pass
141    if seq_node is not None and seq_node.is_sequence_constructor:
142        if index_node is not None and index_node.has_constant_result():
143            try:
144                item = seq_node.args[index_node.constant_result]
145            except (ValueError, TypeError, IndexError):
146                pass
147            else:
148                return item.infer_type(env)
149        # if we're lucky, all items have the same type
150        item_types = set([item.infer_type(env) for item in seq_node.args])
151        if len(item_types) == 1:
152            return item_types.pop()
153    return None
154
155
156class ExprNode(Node):
157    #  subexprs     [string]     Class var holding names of subexpr node attrs
158    #  type         PyrexType    Type of the result
159    #  result_code  string       Code fragment
160    #  result_ctype string       C type of result_code if different from type
161    #  is_temp      boolean      Result is in a temporary variable
162    #  is_sequence_constructor
163    #               boolean      Is a list or tuple constructor expression
164    #  is_starred   boolean      Is a starred expression (e.g. '*a')
165    #  saved_subexpr_nodes
166    #               [ExprNode or [ExprNode or None] or None]
167    #                            Cached result of subexpr_nodes()
168    #  use_managed_ref boolean   use ref-counted temps/assignments/etc.
169    #  result_is_used  boolean   indicates that the result will be dropped and the
170    #                            result_code/temp_result can safely be set to None
171
172    result_ctype = None
173    type = None
174    temp_code = None
175    old_temp = None # error checker for multiple frees etc.
176    use_managed_ref = True # can be set by optimisation transforms
177    result_is_used = True
178
179    #  The Analyse Expressions phase for expressions is split
180    #  into two sub-phases:
181    #
182    #    Analyse Types
183    #      Determines the result type of the expression based
184    #      on the types of its sub-expressions, and inserts
185    #      coercion nodes into the expression tree where needed.
186    #      Marks nodes which will need to have temporary variables
187    #      allocated.
188    #
189    #    Allocate Temps
190    #      Allocates temporary variables where needed, and fills
191    #      in the result_code field of each node.
192    #
193    #  ExprNode provides some convenience routines which
194    #  perform both of the above phases. These should only
195    #  be called from statement nodes, and only when no
196    #  coercion nodes need to be added around the expression
197    #  being analysed. In that case, the above two phases
198    #  should be invoked separately.
199    #
200    #  Framework code in ExprNode provides much of the common
201    #  processing for the various phases. It makes use of the
202    #  'subexprs' class attribute of ExprNodes, which should
203    #  contain a list of the names of attributes which can
204    #  hold sub-nodes or sequences of sub-nodes.
205    #
206    #  The framework makes use of a number of abstract methods.
207    #  Their responsibilities are as follows.
208    #
209    #    Declaration Analysis phase
210    #
211    #      analyse_target_declaration
212    #        Called during the Analyse Declarations phase to analyse
213    #        the LHS of an assignment or argument of a del statement.
214    #        Nodes which cannot be the LHS of an assignment need not
215    #        implement it.
216    #
217    #    Expression Analysis phase
218    #
219    #      analyse_types
220    #        - Call analyse_types on all sub-expressions.
221    #        - Check operand types, and wrap coercion nodes around
222    #          sub-expressions where needed.
223    #        - Set the type of this node.
224    #        - If a temporary variable will be required for the
225    #          result, set the is_temp flag of this node.
226    #
227    #      analyse_target_types
228    #        Called during the Analyse Types phase to analyse
229    #        the LHS of an assignment or argument of a del
230    #        statement. Similar responsibilities to analyse_types.
231    #
232    #      target_code
233    #        Called by the default implementation of allocate_target_temps.
234    #        Should return a C lvalue for assigning to the node. The default
235    #        implementation calls calculate_result_code.
236    #
237    #      check_const
238    #        - Check that this node and its subnodes form a
239    #          legal constant expression. If so, do nothing,
240    #          otherwise call not_const.
241    #
242    #        The default implementation of check_const
243    #        assumes that the expression is not constant.
244    #
245    #      check_const_addr
246    #        - Same as check_const, except check that the
247    #          expression is a C lvalue whose address is
248    #          constant. Otherwise, call addr_not_const.
249    #
250    #        The default implementation of calc_const_addr
251    #        assumes that the expression is not a constant
252    #        lvalue.
253    #
254    #   Code Generation phase
255    #
256    #      generate_evaluation_code
257    #        - Call generate_evaluation_code for sub-expressions.
258    #        - Perform the functions of generate_result_code
259    #          (see below).
260    #        - If result is temporary, call generate_disposal_code
261    #          on all sub-expressions.
262    #
263    #        A default implementation of generate_evaluation_code
264    #        is provided which uses the following abstract methods:
265    #
266    #          generate_result_code
267    #            - Generate any C statements necessary to calculate
268    #              the result of this node from the results of its
269    #              sub-expressions.
270    #
271    #          calculate_result_code
272    #            - Should return a C code fragment evaluating to the
273    #              result. This is only called when the result is not
274    #              a temporary.
275    #
276    #      generate_assignment_code
277    #        Called on the LHS of an assignment.
278    #        - Call generate_evaluation_code for sub-expressions.
279    #        - Generate code to perform the assignment.
280    #        - If the assignment absorbed a reference, call
281    #          generate_post_assignment_code on the RHS,
282    #          otherwise call generate_disposal_code on it.
283    #
284    #      generate_deletion_code
285    #        Called on an argument of a del statement.
286    #        - Call generate_evaluation_code for sub-expressions.
287    #        - Generate code to perform the deletion.
288    #        - Call generate_disposal_code on all sub-expressions.
289    #
290    #
291
292    is_sequence_constructor = 0
293    is_string_literal = 0
294    is_attribute = 0
295    is_subscript = 0
296
297    saved_subexpr_nodes = None
298    is_temp = 0
299    is_target = 0
300    is_starred = 0
301
302    constant_result = constant_value_not_set
303
304    # whether this node with a memoryview type should be broadcast
305    memslice_broadcast = False
306
307    child_attrs = property(fget=operator.attrgetter('subexprs'))
308
309    def not_implemented(self, method_name):
310        print_call_chain(method_name, "not implemented") ###
311        raise InternalError(
312            "%s.%s not implemented" %
313                (self.__class__.__name__, method_name))
314
315    def is_lvalue(self):
316        return 0
317
318    def is_addressable(self):
319        return self.is_lvalue() and not self.type.is_memoryviewslice
320
321    def is_ephemeral(self):
322        #  An ephemeral node is one whose result is in
323        #  a Python temporary and we suspect there are no
324        #  other references to it. Certain operations are
325        #  disallowed on such values, since they are
326        #  likely to result in a dangling pointer.
327        return self.type.is_pyobject and self.is_temp
328
329    def subexpr_nodes(self):
330        #  Extract a list of subexpression nodes based
331        #  on the contents of the subexprs class attribute.
332        nodes = []
333        for name in self.subexprs:
334            item = getattr(self, name)
335            if item is not None:
336                if type(item) is list:
337                    nodes.extend(item)
338                else:
339                    nodes.append(item)
340        return nodes
341
342    def result(self):
343        if self.is_temp:
344            return self.temp_code
345        else:
346            return self.calculate_result_code()
347
348    def result_as(self, type = None):
349        #  Return the result code cast to the specified C type.
350        if (self.is_temp and self.type.is_pyobject and
351                type != py_object_type):
352            # Allocated temporaries are always PyObject *, which may not
353            # reflect the actual type (e.g. an extension type)
354            return typecast(type, py_object_type, self.result())
355        return typecast(type, self.ctype(), self.result())
356
357    def py_result(self):
358        #  Return the result code cast to PyObject *.
359        return self.result_as(py_object_type)
360
361    def ctype(self):
362        #  Return the native C type of the result (i.e. the
363        #  C type of the result_code expression).
364        return self.result_ctype or self.type
365
366    def get_constant_c_result_code(self):
367        # Return the constant value of this node as a result code
368        # string, or None if the node is not constant.  This method
369        # can be called when the constant result code is required
370        # before the code generation phase.
371        #
372        # The return value is a string that can represent a simple C
373        # value, a constant C name or a constant C expression.  If the
374        # node type depends on Python code, this must return None.
375        return None
376
377    def calculate_constant_result(self):
378        # Calculate the constant compile time result value of this
379        # expression and store it in ``self.constant_result``.  Does
380        # nothing by default, thus leaving ``self.constant_result``
381        # unknown.  If valid, the result can be an arbitrary Python
382        # value.
383        #
384        # This must only be called when it is assured that all
385        # sub-expressions have a valid constant_result value.  The
386        # ConstantFolding transform will do this.
387        pass
388
389    def has_constant_result(self):
390        return self.constant_result is not constant_value_not_set and \
391               self.constant_result is not not_a_constant
392
393    def compile_time_value(self, denv):
394        #  Return value of compile-time expression, or report error.
395        error(self.pos, "Invalid compile-time expression")
396
397    def compile_time_value_error(self, e):
398        error(self.pos, "Error in compile-time expression: %s: %s" % (
399            e.__class__.__name__, e))
400
401    # ------------- Declaration Analysis ----------------
402
403    def analyse_target_declaration(self, env):
404        error(self.pos, "Cannot assign to or delete this")
405
406    # ------------- Expression Analysis ----------------
407
408    def analyse_const_expression(self, env):
409        #  Called during the analyse_declarations phase of a
410        #  constant expression. Analyses the expression's type,
411        #  checks whether it is a legal const expression,
412        #  and determines its value.
413        node = self.analyse_types(env)
414        node.check_const()
415        return node
416
417    def analyse_expressions(self, env):
418        #  Convenience routine performing both the Type
419        #  Analysis and Temp Allocation phases for a whole
420        #  expression.
421        return self.analyse_types(env)
422
423    def analyse_target_expression(self, env, rhs):
424        #  Convenience routine performing both the Type
425        #  Analysis and Temp Allocation phases for the LHS of
426        #  an assignment.
427        return self.analyse_target_types(env)
428
429    def analyse_boolean_expression(self, env):
430        #  Analyse expression and coerce to a boolean.
431        node = self.analyse_types(env)
432        bool = node.coerce_to_boolean(env)
433        return bool
434
435    def analyse_temp_boolean_expression(self, env):
436        #  Analyse boolean expression and coerce result into
437        #  a temporary. This is used when a branch is to be
438        #  performed on the result and we won't have an
439        #  opportunity to ensure disposal code is executed
440        #  afterwards. By forcing the result into a temporary,
441        #  we ensure that all disposal has been done by the
442        #  time we get the result.
443        node = self.analyse_types(env)
444        return node.coerce_to_boolean(env).coerce_to_simple(env)
445
446    # --------------- Type Inference -----------------
447
448    def type_dependencies(self, env):
449        # Returns the list of entries whose types must be determined
450        # before the type of self can be inferred.
451        if hasattr(self, 'type') and self.type is not None:
452            return ()
453        return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
454
455    def infer_type(self, env):
456        # Attempt to deduce the type of self.
457        # Differs from analyse_types as it avoids unnecessary
458        # analysis of subexpressions, but can assume everything
459        # in self.type_dependencies() has been resolved.
460        if hasattr(self, 'type') and self.type is not None:
461            return self.type
462        elif hasattr(self, 'entry') and self.entry is not None:
463            return self.entry.type
464        else:
465            self.not_implemented("infer_type")
466
467    def nonlocally_immutable(self):
468        # Returns whether this variable is a safe reference, i.e.
469        # can't be modified as part of globals or closures.
470        return self.is_literal or self.is_temp or self.type.is_array or self.type.is_cfunction
471
472    # --------------- Type Analysis ------------------
473
474    def analyse_as_module(self, env):
475        # If this node can be interpreted as a reference to a
476        # cimported module, return its scope, else None.
477        return None
478
479    def analyse_as_type(self, env):
480        # If this node can be interpreted as a reference to a
481        # type, return that type, else None.
482        return None
483
484    def analyse_as_extension_type(self, env):
485        # If this node can be interpreted as a reference to an
486        # extension type or builtin type, return its type, else None.
487        return None
488
489    def analyse_types(self, env):
490        self.not_implemented("analyse_types")
491
492    def analyse_target_types(self, env):
493        return self.analyse_types(env)
494
495    def nogil_check(self, env):
496        # By default, any expression based on Python objects is
497        # prevented in nogil environments.  Subtypes must override
498        # this if they can work without the GIL.
499        if self.type and self.type.is_pyobject:
500            self.gil_error()
501
502    def gil_assignment_check(self, env):
503        if env.nogil and self.type.is_pyobject:
504            error(self.pos, "Assignment of Python object not allowed without gil")
505
506    def check_const(self):
507        self.not_const()
508        return False
509
510    def not_const(self):
511        error(self.pos, "Not allowed in a constant expression")
512
513    def check_const_addr(self):
514        self.addr_not_const()
515        return False
516
517    def addr_not_const(self):
518        error(self.pos, "Address is not constant")
519
520    # ----------------- Result Allocation -----------------
521
522    def result_in_temp(self):
523        #  Return true if result is in a temporary owned by
524        #  this node or one of its subexpressions. Overridden
525        #  by certain nodes which can share the result of
526        #  a subnode.
527        return self.is_temp
528
529    def target_code(self):
530        #  Return code fragment for use as LHS of a C assignment.
531        return self.calculate_result_code()
532
533    def calculate_result_code(self):
534        self.not_implemented("calculate_result_code")
535
536#    def release_target_temp(self, env):
537#        #  Release temporaries used by LHS of an assignment.
538#        self.release_subexpr_temps(env)
539
540    def allocate_temp_result(self, code):
541        if self.temp_code:
542            raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
543        type = self.type
544        if not type.is_void:
545            if type.is_pyobject:
546                type = PyrexTypes.py_object_type
547            self.temp_code = code.funcstate.allocate_temp(
548                type, manage_ref=self.use_managed_ref)
549        else:
550            self.temp_code = None
551
552    def release_temp_result(self, code):
553        if not self.temp_code:
554            if not self.result_is_used:
555                # not used anyway, so ignore if not set up
556                return
557            if self.old_temp:
558                raise RuntimeError("temp %s released multiple times in %s" % (
559                        self.old_temp, self.__class__.__name__))
560            else:
561                raise RuntimeError("no temp, but release requested in %s" % (
562                        self.__class__.__name__))
563        code.funcstate.release_temp(self.temp_code)
564        self.old_temp = self.temp_code
565        self.temp_code = None
566
567    # ---------------- Code Generation -----------------
568
569    def make_owned_reference(self, code):
570        """
571        If result is a pyobject, make sure we own a reference to it.
572        If the result is in a temp, it is already a new reference.
573        """
574        if self.type.is_pyobject and not self.result_in_temp():
575            code.put_incref(self.result(), self.ctype())
576
577    def make_owned_memoryviewslice(self, code):
578        """
579        Make sure we own the reference to this memoryview slice.
580        """
581        if not self.result_in_temp():
582            code.put_incref_memoryviewslice(self.result(),
583                                            have_gil=self.in_nogil_context)
584
585    def generate_evaluation_code(self, code):
586        #  Generate code to evaluate this node and
587        #  its sub-expressions, and dispose of any
588        #  temporary results of its sub-expressions.
589        self.generate_subexpr_evaluation_code(code)
590
591        code.mark_pos(self.pos)
592        if self.is_temp:
593            self.allocate_temp_result(code)
594
595        self.generate_result_code(code)
596        if self.is_temp:
597            # If we are temp we do not need to wait until this node is disposed
598            # before disposing children.
599            self.generate_subexpr_disposal_code(code)
600            self.free_subexpr_temps(code)
601
602    def generate_subexpr_evaluation_code(self, code):
603        for node in self.subexpr_nodes():
604            node.generate_evaluation_code(code)
605
606    def generate_result_code(self, code):
607        self.not_implemented("generate_result_code")
608
609    def generate_disposal_code(self, code):
610        if self.is_temp:
611            if self.result():
612                if self.type.is_pyobject:
613                    code.put_decref_clear(self.result(), self.ctype())
614                elif self.type.is_memoryviewslice:
615                    code.put_xdecref_memoryviewslice(
616                            self.result(), have_gil=not self.in_nogil_context)
617        else:
618            # Already done if self.is_temp
619            self.generate_subexpr_disposal_code(code)
620
621    def generate_subexpr_disposal_code(self, code):
622        #  Generate code to dispose of temporary results
623        #  of all sub-expressions.
624        for node in self.subexpr_nodes():
625            node.generate_disposal_code(code)
626
627    def generate_post_assignment_code(self, code):
628        if self.is_temp:
629            if self.type.is_pyobject:
630                code.putln("%s = 0;" % self.result())
631            elif self.type.is_memoryviewslice:
632                code.putln("%s.memview = NULL;" % self.result())
633                code.putln("%s.data = NULL;" % self.result())
634        else:
635            self.generate_subexpr_disposal_code(code)
636
637    def generate_assignment_code(self, rhs, code):
638        #  Stub method for nodes which are not legal as
639        #  the LHS of an assignment. An error will have
640        #  been reported earlier.
641        pass
642
643    def generate_deletion_code(self, code, ignore_nonexisting=False):
644        #  Stub method for nodes that are not legal as
645        #  the argument of a del statement. An error
646        #  will have been reported earlier.
647        pass
648
649    def free_temps(self, code):
650        if self.is_temp:
651            if not self.type.is_void:
652                self.release_temp_result(code)
653        else:
654            self.free_subexpr_temps(code)
655
656    def free_subexpr_temps(self, code):
657        for sub in self.subexpr_nodes():
658            sub.free_temps(code)
659
660    def generate_function_definitions(self, env, code):
661        pass
662
663    # ---------------- Annotation ---------------------
664
665    def annotate(self, code):
666        for node in self.subexpr_nodes():
667            node.annotate(code)
668
669    # ----------------- Coercion ----------------------
670
671    def coerce_to(self, dst_type, env):
672        #   Coerce the result so that it can be assigned to
673        #   something of type dst_type. If processing is necessary,
674        #   wraps this node in a coercion node and returns that.
675        #   Otherwise, returns this node unchanged.
676        #
677        #   This method is called during the analyse_expressions
678        #   phase of the src_node's processing.
679        #
680        #   Note that subclasses that override this (especially
681        #   ConstNodes) must not (re-)set their own .type attribute
682        #   here.  Since expression nodes may turn up in different
683        #   places in the tree (e.g. inside of CloneNodes in cascaded
684        #   assignments), this method must return a new node instance
685        #   if it changes the type.
686        #
687        src = self
688        src_type = self.type
689
690        if self.check_for_coercion_error(dst_type, env):
691            return self
692
693        if dst_type.is_reference and not src_type.is_reference:
694            dst_type = dst_type.ref_base_type
695
696        if src_type.is_const:
697            src_type = src_type.const_base_type
698
699        if src_type.is_fused or dst_type.is_fused:
700            # See if we are coercing a fused function to a pointer to a
701            # specialized function
702            if (src_type.is_cfunction and not dst_type.is_fused and
703                    dst_type.is_ptr and dst_type.base_type.is_cfunction):
704
705                dst_type = dst_type.base_type
706
707                for signature in src_type.get_all_specialized_function_types():
708                    if signature.same_as(dst_type):
709                        src.type = signature
710                        src.entry = src.type.entry
711                        src.entry.used = True
712                        return self
713
714            if src_type.is_fused:
715                error(self.pos, "Type is not specialized")
716            else:
717                error(self.pos, "Cannot coerce to a type that is not specialized")
718
719            self.type = error_type
720            return self
721
722        if self.coercion_type is not None:
723            # This is purely for error checking purposes!
724            node = NameNode(self.pos, name='', type=self.coercion_type)
725            node.coerce_to(dst_type, env)
726
727        if dst_type.is_memoryviewslice:
728            import MemoryView
729            if not src.type.is_memoryviewslice:
730                if src.type.is_pyobject:
731                    src = CoerceToMemViewSliceNode(src, dst_type, env)
732                elif src.type.is_array:
733                    src = CythonArrayNode.from_carray(src, env).coerce_to(
734                                                            dst_type, env)
735                elif not src_type.is_error:
736                    error(self.pos,
737                          "Cannot convert '%s' to memoryviewslice" %
738                                                                (src_type,))
739            elif not MemoryView.src_conforms_to_dst(
740                        src.type, dst_type, broadcast=self.memslice_broadcast):
741                if src.type.dtype.same_as(dst_type.dtype):
742                    msg = "Memoryview '%s' not conformable to memoryview '%s'."
743                    tup = src.type, dst_type
744                else:
745                    msg = "Different base types for memoryviews (%s, %s)"
746                    tup = src.type.dtype, dst_type.dtype
747
748                error(self.pos, msg % tup)
749
750        elif dst_type.is_pyobject:
751            if not src.type.is_pyobject:
752                if dst_type is bytes_type and src.type.is_int:
753                    src = CoerceIntToBytesNode(src, env)
754                else:
755                    src = CoerceToPyTypeNode(src, env, type=dst_type)
756            if not src.type.subtype_of(dst_type):
757                if src.constant_result is not None:
758                    src = PyTypeTestNode(src, dst_type, env)
759        elif src.type.is_pyobject:
760            src = CoerceFromPyTypeNode(dst_type, src, env)
761        elif (dst_type.is_complex
762              and src_type != dst_type
763              and dst_type.assignable_from(src_type)):
764            src = CoerceToComplexNode(src, dst_type, env)
765        else: # neither src nor dst are py types
766            # Added the string comparison, since for c types that
767            # is enough, but Cython gets confused when the types are
768            # in different pxi files.
769            if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
770                self.fail_assignment(dst_type)
771        return src
772
773    def fail_assignment(self, dst_type):
774        error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
775
776    def check_for_coercion_error(self, dst_type, env, fail=False, default=None):
777        if fail and not default:
778            default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
779        message = find_coercion_error((self.type, dst_type), default, env)
780        if message is not None:
781            error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
782            return True
783        if fail:
784            self.fail_assignment(dst_type)
785            return True
786        return False
787
788    def coerce_to_pyobject(self, env):
789        return self.coerce_to(PyrexTypes.py_object_type, env)
790
791    def coerce_to_boolean(self, env):
792        #  Coerce result to something acceptable as
793        #  a boolean value.
794
795        # if it's constant, calculate the result now
796        if self.has_constant_result():
797            bool_value = bool(self.constant_result)
798            return BoolNode(self.pos, value=bool_value,
799                            constant_result=bool_value)
800
801        type = self.type
802        if type.is_enum or type.is_error:
803            return self
804        elif type.is_pyobject or type.is_int or type.is_ptr or type.is_float:
805            return CoerceToBooleanNode(self, env)
806        else:
807            error(self.pos, "Type '%s' not acceptable as a boolean" % type)
808            return self
809
810    def coerce_to_integer(self, env):
811        # If not already some C integer type, coerce to longint.
812        if self.type.is_int:
813            return self
814        else:
815            return self.coerce_to(PyrexTypes.c_long_type, env)
816
817    def coerce_to_temp(self, env):
818        #  Ensure that the result is in a temporary.
819        if self.result_in_temp():
820            return self
821        else:
822            return CoerceToTempNode(self, env)
823
824    def coerce_to_simple(self, env):
825        #  Ensure that the result is simple (see is_simple).
826        if self.is_simple():
827            return self
828        else:
829            return self.coerce_to_temp(env)
830
831    def is_simple(self):
832        #  A node is simple if its result is something that can
833        #  be referred to without performing any operations, e.g.
834        #  a constant, local var, C global var, struct member
835        #  reference, or temporary.
836        return self.result_in_temp()
837
838    def may_be_none(self):
839        if self.type and not (self.type.is_pyobject or
840                              self.type.is_memoryviewslice):
841            return False
842        if self.has_constant_result():
843            return self.constant_result is not None
844        return True
845
846    def as_cython_attribute(self):
847        return None
848
849    def as_none_safe_node(self, message, error="PyExc_TypeError", format_args=()):
850        # Wraps the node in a NoneCheckNode if it is not known to be
851        # not-None (e.g. because it is a Python literal).
852        if self.may_be_none():
853            return NoneCheckNode(self, error, message, format_args)
854        else:
855            return self
856
857    @classmethod
858    def from_node(cls, node, **kwargs):
859        """Instantiate this node class from another node, properly
860        copying over all attributes that one would forget otherwise.
861        """
862        attributes = "cf_state cf_maybe_null cf_is_null constant_result".split()
863        for attr_name in attributes:
864            if attr_name in kwargs:
865                continue
866            try:
867                value = getattr(node, attr_name)
868            except AttributeError:
869                pass
870            else:
871                kwargs[attr_name] = value
872        return cls(node.pos, **kwargs)
873
874
875class AtomicExprNode(ExprNode):
876    #  Abstract base class for expression nodes which have
877    #  no sub-expressions.
878
879    subexprs = []
880
881    # Override to optimize -- we know we have no children
882    def generate_subexpr_evaluation_code(self, code):
883        pass
884    def generate_subexpr_disposal_code(self, code):
885        pass
886
887class PyConstNode(AtomicExprNode):
888    #  Abstract base class for constant Python values.
889
890    is_literal = 1
891    type = py_object_type
892
893    def is_simple(self):
894        return 1
895
896    def may_be_none(self):
897        return False
898
899    def analyse_types(self, env):
900        return self
901
902    def calculate_result_code(self):
903        return self.value
904
905    def generate_result_code(self, code):
906        pass
907
908
909class NoneNode(PyConstNode):
910    #  The constant value None
911
912    is_none = 1
913    value = "Py_None"
914
915    constant_result = None
916
917    nogil_check = None
918
919    def compile_time_value(self, denv):
920        return None
921
922    def may_be_none(self):
923        return True
924
925
926class EllipsisNode(PyConstNode):
927    #  '...' in a subscript list.
928
929    value = "Py_Ellipsis"
930
931    constant_result = Ellipsis
932
933    def compile_time_value(self, denv):
934        return Ellipsis
935
936
937class ConstNode(AtomicExprNode):
938    # Abstract base type for literal constant nodes.
939    #
940    # value     string      C code fragment
941
942    is_literal = 1
943    nogil_check = None
944
945    def is_simple(self):
946        return 1
947
948    def nonlocally_immutable(self):
949        return 1
950
951    def may_be_none(self):
952        return False
953
954    def analyse_types(self, env):
955        return self  # Types are held in class variables
956
957    def check_const(self):
958        return True
959
960    def get_constant_c_result_code(self):
961        return self.calculate_result_code()
962
963    def calculate_result_code(self):
964        return str(self.value)
965
966    def generate_result_code(self, code):
967        pass
968
969
970class BoolNode(ConstNode):
971    type = PyrexTypes.c_bint_type
972    #  The constant value True or False
973
974    def calculate_constant_result(self):
975        self.constant_result = self.value
976
977    def compile_time_value(self, denv):
978        return self.value
979
980    def calculate_result_code(self):
981        if self.type.is_pyobject:
982            return self.value and 'Py_True' or 'Py_False'
983        else:
984            return str(int(self.value))
985
986    def coerce_to(self, dst_type, env):
987        if dst_type.is_pyobject and self.type.is_int:
988            return BoolNode(
989                self.pos, value=self.value,
990                constant_result=self.constant_result,
991                type=Builtin.bool_type)
992        if dst_type.is_int and self.type.is_pyobject:
993            return BoolNode(
994                self.pos, value=self.value,
995                constant_result=self.constant_result,
996                type=PyrexTypes.c_bint_type)
997        return ConstNode.coerce_to(self, dst_type, env)
998
999
1000class NullNode(ConstNode):
1001    type = PyrexTypes.c_null_ptr_type
1002    value = "NULL"
1003    constant_result = 0
1004
1005    def get_constant_c_result_code(self):
1006        return self.value
1007
1008
1009class CharNode(ConstNode):
1010    type = PyrexTypes.c_char_type
1011
1012    def calculate_constant_result(self):
1013        self.constant_result = ord(self.value)
1014
1015    def compile_time_value(self, denv):
1016        return ord(self.value)
1017
1018    def calculate_result_code(self):
1019        return "'%s'" % StringEncoding.escape_char(self.value)
1020
1021
1022class IntNode(ConstNode):
1023
1024    # unsigned     "" or "U"
1025    # longness     "" or "L" or "LL"
1026    # is_c_literal   True/False/None   creator considers this a C integer literal
1027
1028    unsigned = ""
1029    longness = ""
1030    is_c_literal = None # unknown
1031
1032    def __init__(self, pos, **kwds):
1033        ExprNode.__init__(self, pos, **kwds)
1034        if 'type' not in kwds:
1035            self.type = self.find_suitable_type_for_value()
1036
1037    def find_suitable_type_for_value(self):
1038        if self.constant_result is constant_value_not_set:
1039            try:
1040                self.calculate_constant_result()
1041            except ValueError:
1042                pass
1043        # we ignore 'is_c_literal = True' and instead map signed 32bit
1044        # integers as C long values
1045        if self.is_c_literal or \
1046               self.constant_result in (constant_value_not_set, not_a_constant) or \
1047               self.unsigned or self.longness == 'LL':
1048            # clearly a C literal
1049            rank = (self.longness == 'LL') and 2 or 1
1050            suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
1051            if self.type:
1052                suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
1053        else:
1054            # C literal or Python literal - split at 32bit boundary
1055            if -2**31 <= self.constant_result < 2**31:
1056                if self.type and self.type.is_int:
1057                    suitable_type = self.type
1058                else:
1059                    suitable_type = PyrexTypes.c_long_type
1060            else:
1061                suitable_type = PyrexTypes.py_object_type
1062        return suitable_type
1063
1064    def coerce_to(self, dst_type, env):
1065        if self.type is dst_type:
1066            return self
1067        elif dst_type.is_float:
1068            if self.has_constant_result():
1069                return FloatNode(self.pos, value='%d.0' % int(self.constant_result), type=dst_type,
1070                                 constant_result=float(self.constant_result))
1071            else:
1072                return FloatNode(self.pos, value=self.value, type=dst_type,
1073                                 constant_result=not_a_constant)
1074        if dst_type.is_numeric and not dst_type.is_complex:
1075            node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
1076                           type = dst_type, is_c_literal = True,
1077                           unsigned=self.unsigned, longness=self.longness)
1078            return node
1079        elif dst_type.is_pyobject:
1080            node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
1081                           type = PyrexTypes.py_object_type, is_c_literal = False,
1082                           unsigned=self.unsigned, longness=self.longness)
1083        else:
1084            # FIXME: not setting the type here to keep it working with
1085            # complex numbers. Should they be special cased?
1086            node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
1087                           unsigned=self.unsigned, longness=self.longness)
1088        # We still need to perform normal coerce_to processing on the
1089        # result, because we might be coercing to an extension type,
1090        # in which case a type test node will be needed.
1091        return ConstNode.coerce_to(node, dst_type, env)
1092
1093    def coerce_to_boolean(self, env):
1094        return IntNode(
1095            self.pos, value=self.value,
1096            constant_result=self.constant_result,
1097            type=PyrexTypes.c_bint_type,
1098            unsigned=self.unsigned, longness=self.longness)
1099
1100    def generate_evaluation_code(self, code):
1101        if self.type.is_pyobject:
1102            # pre-allocate a Python version of the number
1103            plain_integer_string = str(Utils.str_to_number(self.value))
1104            self.result_code = code.get_py_int(plain_integer_string, self.longness)
1105        else:
1106            self.result_code = self.get_constant_c_result_code()
1107
1108    def get_constant_c_result_code(self):
1109        return self.value_as_c_integer_string() + self.unsigned + self.longness
1110
1111    def value_as_c_integer_string(self):
1112        value = self.value
1113        if len(value) > 2:
1114            # convert C-incompatible Py3 oct/bin notations
1115            if value[1] in 'oO':
1116                value = value[0] + value[2:] # '0o123' => '0123'
1117            elif value[1] in 'bB':
1118                value = int(value[2:], 2)
1119        return str(value)
1120
1121    def calculate_result_code(self):
1122        return self.result_code
1123
1124    def calculate_constant_result(self):
1125        self.constant_result = Utils.str_to_number(self.value)
1126
1127    def compile_time_value(self, denv):
1128        return Utils.str_to_number(self.value)
1129
1130
1131class FloatNode(ConstNode):
1132    type = PyrexTypes.c_double_type
1133
1134    def calculate_constant_result(self):
1135        self.constant_result = float(self.value)
1136
1137    def compile_time_value(self, denv):
1138        return float(self.value)
1139
1140    def coerce_to(self, dst_type, env):
1141        if dst_type.is_pyobject and self.type.is_float:
1142            return FloatNode(
1143                self.pos, value=self.value,
1144                constant_result=self.constant_result,
1145                type=Builtin.float_type)
1146        if dst_type.is_float and self.type.is_pyobject:
1147            return FloatNode(
1148                self.pos, value=self.value,
1149                constant_result=self.constant_result,
1150                type=dst_type)
1151        return ConstNode.coerce_to(self, dst_type, env)
1152
1153    def calculate_result_code(self):
1154        return self.result_code
1155
1156    def get_constant_c_result_code(self):
1157        strval = self.value
1158        assert isinstance(strval, (str, unicode))
1159        cmpval = repr(float(strval))
1160        if cmpval == 'nan':
1161            return "(Py_HUGE_VAL * 0)"
1162        elif cmpval == 'inf':
1163            return "Py_HUGE_VAL"
1164        elif cmpval == '-inf':
1165            return "(-Py_HUGE_VAL)"
1166        else:
1167            return strval
1168
1169    def generate_evaluation_code(self, code):
1170        c_value = self.get_constant_c_result_code()
1171        if self.type.is_pyobject:
1172            self.result_code = code.get_py_float(self.value, c_value)
1173        else:
1174            self.result_code = c_value
1175
1176
1177class BytesNode(ConstNode):
1178    # A char* or bytes literal
1179    #
1180    # value      BytesLiteral
1181
1182    is_string_literal = True
1183    # start off as Python 'bytes' to support len() in O(1)
1184    type = bytes_type
1185
1186    def calculate_constant_result(self):
1187        self.constant_result = self.value
1188
1189    def as_sliced_node(self, start, stop, step=None):
1190        value = StringEncoding.BytesLiteral(self.value[start:stop:step])
1191        value.encoding = self.value.encoding
1192        return BytesNode(
1193            self.pos, value=value, constant_result=value)
1194
1195    def compile_time_value(self, denv):
1196        return self.value
1197
1198    def analyse_as_type(self, env):
1199        type = PyrexTypes.parse_basic_type(self.value)
1200        if type is not None:
1201            return type
1202        from TreeFragment import TreeFragment
1203        pos = (self.pos[0], self.pos[1], self.pos[2]-7)
1204        declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
1205        sizeof_node = declaration.root.stats[0].expr
1206        sizeof_node = sizeof_node.analyse_types(env)
1207        if isinstance(sizeof_node, SizeofTypeNode):
1208            return sizeof_node.arg_type
1209
1210    def can_coerce_to_char_literal(self):
1211        return len(self.value) == 1
1212
1213    def coerce_to_boolean(self, env):
1214        # This is special because testing a C char* for truth directly
1215        # would yield the wrong result.
1216        bool_value = bool(self.value)
1217        return BoolNode(self.pos, value=bool_value, constant_result=bool_value)
1218
1219    def coerce_to(self, dst_type, env):
1220        if self.type == dst_type:
1221            return self
1222        if dst_type.is_int:
1223            if not self.can_coerce_to_char_literal():
1224                error(self.pos, "Only single-character string literals can be coerced into ints.")
1225                return self
1226            if dst_type.is_unicode_char:
1227                error(self.pos, "Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead.")
1228                return self
1229            return CharNode(self.pos, value=self.value,
1230                            constant_result=ord(self.value))
1231
1232        node = BytesNode(self.pos, value=self.value,
1233                         constant_result=self.constant_result)
1234        if dst_type.is_pyobject:
1235            if dst_type in (py_object_type, Builtin.bytes_type):
1236                node.type = Builtin.bytes_type
1237            else:
1238                self.check_for_coercion_error(dst_type, env, fail=True)
1239                return node
1240        elif dst_type == PyrexTypes.c_char_ptr_type:
1241            node.type = dst_type
1242            return node
1243        elif dst_type == PyrexTypes.c_uchar_ptr_type:
1244            node.type = PyrexTypes.c_char_ptr_type
1245            return CastNode(node, PyrexTypes.c_uchar_ptr_type)
1246        elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
1247            node.type = dst_type
1248            return node
1249
1250        # We still need to perform normal coerce_to processing on the
1251        # result, because we might be coercing to an extension type,
1252        # in which case a type test node will be needed.
1253        return ConstNode.coerce_to(node, dst_type, env)
1254
1255    def generate_evaluation_code(self, code):
1256        if self.type.is_pyobject:
1257            self.result_code = code.get_py_string_const(self.value)
1258        else:
1259            self.result_code = code.get_string_const(self.value)
1260
1261    def get_constant_c_result_code(self):
1262        return None # FIXME
1263
1264    def calculate_result_code(self):
1265        return self.result_code
1266
1267
1268class UnicodeNode(ConstNode):
1269    # A Py_UNICODE* or unicode literal
1270    #
1271    # value        EncodedString
1272    # bytes_value  BytesLiteral    the literal parsed as bytes string
1273    #                              ('-3' unicode literals only)
1274
1275    is_string_literal = True
1276    bytes_value = None
1277    type = unicode_type
1278
1279    def calculate_constant_result(self):
1280        self.constant_result = self.value
1281
1282    def as_sliced_node(self, start, stop, step=None):
1283        if StringEncoding.string_contains_surrogates(self.value[:stop]):
1284            # this is unsafe as it may give different results
1285            # in different runtimes
1286            return None
1287        value = StringEncoding.EncodedString(self.value[start:stop:step])
1288        value.encoding = self.value.encoding
1289        if self.bytes_value is not None:
1290            bytes_value = StringEncoding.BytesLiteral(
1291                self.bytes_value[start:stop:step])
1292            bytes_value.encoding = self.bytes_value.encoding
1293        else:
1294            bytes_value = None
1295        return UnicodeNode(
1296            self.pos, value=value, bytes_value=bytes_value,
1297            constant_result=value)
1298
1299    def coerce_to(self, dst_type, env):
1300        if dst_type is self.type:
1301            pass
1302        elif dst_type.is_unicode_char:
1303            if not self.can_coerce_to_char_literal():
1304                error(self.pos,
1305                      "Only single-character Unicode string literals or "
1306                      "surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.")
1307                return self
1308            int_value = ord(self.value)
1309            return IntNode(self.pos, type=dst_type, value=str(int_value),
1310                           constant_result=int_value)
1311        elif not dst_type.is_pyobject:
1312            if dst_type.is_string and self.bytes_value is not None:
1313                # special case: '-3' enforced unicode literal used in a
1314                # C char* context
1315                return BytesNode(self.pos, value=self.bytes_value
1316                    ).coerce_to(dst_type, env)
1317            if dst_type.is_pyunicode_ptr:
1318                node = UnicodeNode(self.pos, value=self.value)
1319                node.type = dst_type
1320                return node
1321            error(self.pos,
1322                  "Unicode literals do not support coercion to C types other "
1323                  "than Py_UNICODE/Py_UCS4 (for characters) or Py_UNICODE* "
1324                  "(for strings).")
1325        elif dst_type not in (py_object_type, Builtin.basestring_type):
1326            self.check_for_coercion_error(dst_type, env, fail=True)
1327        return self
1328
1329    def can_coerce_to_char_literal(self):
1330        return len(self.value) == 1
1331            ## or (len(self.value) == 2
1332            ##     and (0xD800 <= self.value[0] <= 0xDBFF)
1333            ##     and (0xDC00 <= self.value[1] <= 0xDFFF))
1334
1335    def coerce_to_boolean(self, env):
1336        bool_value = bool(self.value)
1337        return BoolNode(self.pos, value=bool_value, constant_result=bool_value)
1338
1339    def contains_surrogates(self):
1340        return StringEncoding.string_contains_surrogates(self.value)
1341
1342    def generate_evaluation_code(self, code):
1343        if self.type.is_pyobject:
1344            if self.contains_surrogates():
1345                # surrogates are not really portable and cannot be
1346                # decoded by the UTF-8 codec in Py3.3
1347                self.result_code = code.get_py_const(py_object_type, 'ustring')
1348                data_cname = code.get_pyunicode_ptr_const(self.value)
1349                code = code.get_cached_constants_writer()
1350                code.mark_pos(self.pos)
1351                code.putln(
1352                    "%s = PyUnicode_FromUnicode(%s, (sizeof(%s) / sizeof(Py_UNICODE))-1); %s" % (
1353                        self.result_code,
1354                        data_cname,
1355                        data_cname,
1356                        code.error_goto_if_null(self.result_code, self.pos)))
1357                code.putln("#if CYTHON_PEP393_ENABLED")
1358                code.put_error_if_neg(
1359                    self.pos, "PyUnicode_READY(%s)" % self.result_code)
1360                code.putln("#endif")
1361            else:
1362                self.result_code = code.get_py_string_const(self.value)
1363        else:
1364            self.result_code = code.get_pyunicode_ptr_const(self.value)
1365
1366    def calculate_result_code(self):
1367        return self.result_code
1368
1369    def compile_time_value(self, env):
1370        return self.value
1371
1372
1373class StringNode(PyConstNode):
1374    # A Python str object, i.e. a byte string in Python 2.x and a
1375    # unicode string in Python 3.x
1376    #
1377    # value          BytesLiteral (or EncodedString with ASCII content)
1378    # unicode_value  EncodedString or None
1379    # is_identifier  boolean
1380
1381    type = str_type
1382    is_string_literal = True
1383    is_identifier = None
1384    unicode_value = None
1385
1386    def calculate_constant_result(self):
1387        if self.unicode_value is not None:
1388            # only the Unicode value is portable across Py2/3
1389            self.constant_result = self.unicode_value
1390
1391    def as_sliced_node(self, start, stop, step=None):
1392        value = type(self.value)(self.value[start:stop:step])
1393        value.encoding = self.value.encoding
1394        if self.unicode_value is not None:
1395            if StringEncoding.string_contains_surrogates(self.unicode_value[:stop]):
1396                # this is unsafe as it may give different results in different runtimes
1397                return None
1398            unicode_value = StringEncoding.EncodedString(
1399                self.unicode_value[start:stop:step])
1400        else:
1401            unicode_value = None
1402        return StringNode(
1403            self.pos, value=value, unicode_value=unicode_value,
1404            constant_result=value, is_identifier=self.is_identifier)
1405
1406    def coerce_to(self, dst_type, env):
1407        if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1408#            if dst_type is Builtin.bytes_type:
1409#                # special case: bytes = 'str literal'
1410#                return BytesNode(self.pos, value=self.value)
1411            if not dst_type.is_pyobject:
1412                return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1413            if dst_type is not Builtin.basestring_type:
1414                self.check_for_coercion_error(dst_type, env, fail=True)
1415        return self
1416
1417    def can_coerce_to_char_literal(self):
1418        return not self.is_identifier and len(self.value) == 1
1419
1420    def generate_evaluation_code(self, code):
1421        self.result_code = code.get_py_string_const(
1422            self.value, identifier=self.is_identifier, is_str=True,
1423            unicode_value=self.unicode_value)
1424
1425    def get_constant_c_result_code(self):
1426        return None
1427
1428    def calculate_result_code(self):
1429        return self.result_code
1430
1431    def compile_time_value(self, env):
1432        return self.value
1433
1434
1435class IdentifierStringNode(StringNode):
1436    # A special str value that represents an identifier (bytes in Py2,
1437    # unicode in Py3).
1438    is_identifier = True
1439
1440
1441class ImagNode(AtomicExprNode):
1442    #  Imaginary number literal
1443    #
1444    #  value   float    imaginary part
1445
1446    type = PyrexTypes.c_double_complex_type
1447
1448    def calculate_constant_result(self):
1449        self.constant_result = complex(0.0, self.value)
1450
1451    def compile_time_value(self, denv):
1452        return complex(0.0, self.value)
1453
1454    def analyse_types(self, env):
1455        self.type.create_declaration_utility_code(env)
1456        return self
1457
1458    def may_be_none(self):
1459        return False
1460
1461    def coerce_to(self, dst_type, env):
1462        if self.type is dst_type:
1463            return self
1464        node = ImagNode(self.pos, value=self.value)
1465        if dst_type.is_pyobject:
1466            node.is_temp = 1
1467            node.type = PyrexTypes.py_object_type
1468        # We still need to perform normal coerce_to processing on the
1469        # result, because we might be coercing to an extension type,
1470        # in which case a type test node will be needed.
1471        return AtomicExprNode.coerce_to(node, dst_type, env)
1472
1473    gil_message = "Constructing complex number"
1474
1475    def calculate_result_code(self):
1476        if self.type.is_pyobject:
1477            return self.result()
1478        else:
1479            return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1480
1481    def generate_result_code(self, code):
1482        if self.type.is_pyobject:
1483            code.putln(
1484                "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1485                    self.result(),
1486                    float(self.value),
1487                    code.error_goto_if_null(self.result(), self.pos)))
1488            code.put_gotref(self.py_result())
1489
1490
1491class NewExprNode(AtomicExprNode):
1492
1493    # C++ new statement
1494    #
1495    # cppclass              node                 c++ class to create
1496
1497    type = None
1498
1499    def infer_type(self, env):
1500        type = self.cppclass.analyse_as_type(env)
1501        if type is None or not type.is_cpp_class:
1502            error(self.pos, "new operator can only be applied to a C++ class")
1503            self.type = error_type
1504            return
1505        self.cpp_check(env)
1506        constructor = type.scope.lookup(u'<init>')
1507        if constructor is None:
1508            func_type = PyrexTypes.CFuncType(type, [], exception_check='+')
1509            type.scope.declare_cfunction(u'<init>', func_type, self.pos)
1510            constructor = type.scope.lookup(u'<init>')
1511        self.class_type = type
1512        self.entry = constructor
1513        self.type = constructor.type
1514        return self.type
1515
1516    def analyse_types(self, env):
1517        if self.type is None:
1518            self.infer_type(env)
1519        return self
1520
1521    def may_be_none(self):
1522        return False
1523
1524    def generate_result_code(self, code):
1525        pass
1526
1527    def calculate_result_code(self):
1528        return "new " + self.class_type.declaration_code("")
1529
1530
1531class NameNode(AtomicExprNode):
1532    #  Reference to a local or global variable name.
1533    #
1534    #  name            string    Python name of the variable
1535    #  entry           Entry     Symbol table entry
1536    #  type_entry      Entry     For extension type names, the original type entry
1537    #  cf_is_null      boolean   Is uninitialized before this node
1538    #  cf_maybe_null   boolean   Maybe uninitialized before this node
1539    #  allow_null      boolean   Don't raise UnboundLocalError
1540    #  nogil           boolean   Whether it is used in a nogil context
1541
1542    is_name = True
1543    is_cython_module = False
1544    cython_attribute = None
1545    lhs_of_first_assignment = False # TODO: remove me
1546    is_used_as_rvalue = 0
1547    entry = None
1548    type_entry = None
1549    cf_maybe_null = True
1550    cf_is_null = False
1551    allow_null = False
1552    nogil = False
1553    inferred_type = None
1554
1555    def as_cython_attribute(self):
1556        return self.cython_attribute
1557
1558    def type_dependencies(self, env):
1559        if self.entry is None:
1560            self.entry = env.lookup(self.name)
1561        if self.entry is not None and self.entry.type.is_unspecified:
1562            return (self,)
1563        else:
1564            return ()
1565
1566    def infer_type(self, env):
1567        if self.entry is None:
1568            self.entry = env.lookup(self.name)
1569        if self.entry is None or self.entry.type is unspecified_type:
1570            if self.inferred_type is not None:
1571                return self.inferred_type
1572            return py_object_type
1573        elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1574                self.name == self.entry.type.name:
1575            # Unfortunately the type attribute of type objects
1576            # is used for the pointer to the type they represent.
1577            return type_type
1578        elif self.entry.type.is_cfunction:
1579            if self.entry.scope.is_builtin_scope:
1580                # special case: optimised builtin functions must be treated as Python objects
1581                return py_object_type
1582            else:
1583                # special case: referring to a C function must return its pointer
1584                return PyrexTypes.CPtrType(self.entry.type)
1585        else:
1586            # If entry is inferred as pyobject it's safe to use local
1587            # NameNode's inferred_type.
1588            if self.entry.type.is_pyobject and self.inferred_type:
1589                # Overflow may happen if integer
1590                if not (self.inferred_type.is_int and self.entry.might_overflow):
1591                    return self.inferred_type
1592            return self.entry.type
1593
1594    def compile_time_value(self, denv):
1595        try:
1596            return denv.lookup(self.name)
1597        except KeyError:
1598            error(self.pos, "Compile-time name '%s' not defined" % self.name)
1599
1600    def get_constant_c_result_code(self):
1601        if not self.entry or self.entry.type.is_pyobject:
1602            return None
1603        return self.entry.cname
1604
1605    def coerce_to(self, dst_type, env):
1606        #  If coercing to a generic pyobject and this is a builtin
1607        #  C function with a Python equivalent, manufacture a NameNode
1608        #  referring to the Python builtin.
1609        #print "NameNode.coerce_to:", self.name, dst_type ###
1610        if dst_type is py_object_type:
1611            entry = self.entry
1612            if entry and entry.is_cfunction:
1613                var_entry = entry.as_variable
1614                if var_entry:
1615                    if var_entry.is_builtin and var_entry.is_const:
1616                        var_entry = env.declare_builtin(var_entry.name, self.pos)
1617                    node = NameNode(self.pos, name = self.name)
1618                    node.entry = var_entry
1619                    node.analyse_rvalue_entry(env)
1620                    return node
1621
1622        return super(NameNode, self).coerce_to(dst_type, env)
1623
1624    def analyse_as_module(self, env):
1625        # Try to interpret this as a reference to a cimported module.
1626        # Returns the module scope, or None.
1627        entry = self.entry
1628        if not entry:
1629            entry = env.lookup(self.name)
1630        if entry and entry.as_module:
1631            return entry.as_module
1632        return None
1633
1634    def analyse_as_type(self, env):
1635        if self.cython_attribute:
1636            type = PyrexTypes.parse_basic_type(self.cython_attribute)
1637        else:
1638            type = PyrexTypes.parse_basic_type(self.name)
1639        if type:
1640            return type
1641        entry = self.entry
1642        if not entry:
1643            entry = env.lookup(self.name)
1644        if entry and entry.is_type:
1645            return entry.type
1646        else:
1647            return None
1648
1649    def analyse_as_extension_type(self, env):
1650        # Try to interpret this as a reference to an extension type.
1651        # Returns the extension type, or None.
1652        entry = self.entry
1653        if not entry:
1654            entry = env.lookup(self.name)
1655        if entry and entry.is_type:
1656            if entry.type.is_extension_type or entry.type.is_builtin_type:
1657                return entry.type
1658        return None
1659
1660    def analyse_target_declaration(self, env):
1661        if not self.entry:
1662            self.entry = env.lookup_here(self.name)
1663        if not self.entry:
1664            if env.directives['warn.undeclared']:
1665                warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1666            if env.directives['infer_types'] != False:
1667                type = unspecified_type
1668            else:
1669                type = py_object_type
1670            self.entry = env.declare_var(self.name, type, self.pos)
1671        if self.entry.is_declared_generic:
1672            self.result_ctype = py_object_type
1673
1674    def analyse_types(self, env):
1675        self.initialized_check = env.directives['initializedcheck']
1676        if self.entry is None:
1677            self.entry = env.lookup(self.name)
1678        if not self.entry:
1679            self.entry = env.declare_builtin(self.name, self.pos)
1680        if not self.entry:
1681            self.type = PyrexTypes.error_type
1682            return self
1683        entry = self.entry
1684        if entry:
1685            entry.used = 1
1686            if entry.type.is_buffer:
1687                import Buffer
1688                Buffer.used_buffer_aux_vars(entry)
1689        self.analyse_rvalue_entry(env)
1690        return self
1691
1692    def analyse_target_types(self, env):
1693        self.analyse_entry(env, is_target=True)
1694
1695        if (not self.is_lvalue() and self.entry.is_cfunction and
1696                self.entry.fused_cfunction and self.entry.as_variable):
1697            # We need this for the fused 'def' TreeFragment
1698            self.entry = self.entry.as_variable
1699            self.type = self.entry.type
1700
1701        if self.type.is_const:
1702            error(self.pos, "Assignment to const '%s'" % self.name)
1703        if self.type.is_reference:
1704            error(self.pos, "Assignment to reference '%s'" % self.name)
1705        if not self.is_lvalue():
1706            error(self.pos, "Assignment to non-lvalue '%s'"
1707                % self.name)
1708            self.type = PyrexTypes.error_type
1709        self.entry.used = 1
1710        if self.entry.type.is_buffer:
1711            import Buffer
1712            Buffer.used_buffer_aux_vars(self.entry)
1713        return self
1714
1715    def analyse_rvalue_entry(self, env):
1716        #print "NameNode.analyse_rvalue_entry:", self.name ###
1717        #print "Entry:", self.entry.__dict__ ###
1718        self.analyse_entry(env)
1719        entry = self.entry
1720
1721        if entry.is_declared_generic:
1722            self.result_ctype = py_object_type
1723
1724        if entry.is_pyglobal or entry.is_builtin:
1725            if entry.is_builtin and entry.is_const:
1726                self.is_temp = 0
1727            else:
1728                self.is_temp = 1
1729
1730            self.is_used_as_rvalue = 1
1731        elif entry.type.is_memoryviewslice:
1732            self.is_temp = False
1733            self.is_used_as_rvalue = True
1734            self.use_managed_ref = True
1735        return self
1736
1737    def nogil_check(self, env):
1738        self.nogil = True
1739        if self.is_used_as_rvalue:
1740            entry = self.entry
1741            if entry.is_builtin:
1742                if not entry.is_const: # cached builtins are ok
1743                    self.gil_error()
1744            elif entry.is_pyglobal:
1745                self.gil_error()
1746            elif self.entry.type.is_memoryviewslice:
1747                if self.cf_is_null or self.cf_maybe_null:
1748                    import MemoryView
1749                    MemoryView.err_if_nogil_initialized_check(self.pos, env)
1750
1751    gil_message = "Accessing Python global or builtin"
1752
1753    def analyse_entry(self, env, is_target=False):
1754        #print "NameNode.analyse_entry:", self.name ###
1755        self.check_identifier_kind()
1756        entry = self.entry
1757        type = entry.type
1758        if (not is_target and type.is_pyobject and self.inferred_type and
1759                self.inferred_type.is_builtin_type):
1760            # assume that type inference is smarter than the static entry
1761            type = self.inferred_type
1762        self.type = type
1763
1764    def check_identifier_kind(self):
1765        # Check that this is an appropriate kind of name for use in an
1766        # expression.  Also finds the variable entry associated with
1767        # an extension type.
1768        entry = self.entry
1769        if entry.is_type and entry.type.is_extension_type:
1770            self.type_entry = entry
1771        if not (entry.is_const or entry.is_variable
1772            or entry.is_builtin or entry.is_cfunction
1773            or entry.is_cpp_class):
1774                if self.entry.as_variable:
1775                    self.entry = self.entry.as_variable
1776                else:
1777                    error(self.pos,
1778                          "'%s' is not a constant, variable or function identifier" % self.name)
1779
1780    def is_simple(self):
1781        #  If it's not a C variable, it'll be in a temp.
1782        return 1
1783
1784    def may_be_none(self):
1785        if self.cf_state and self.type and (self.type.is_pyobject or
1786                                            self.type.is_memoryviewslice):
1787            # gard against infinite recursion on self-dependencies
1788            if getattr(self, '_none_checking', False):
1789                # self-dependency - either this node receives a None
1790                # value from *another* node, or it can not reference
1791                # None at this point => safe to assume "not None"
1792                return False
1793            self._none_checking = True
1794            # evaluate control flow state to see if there were any
1795            # potential None values assigned to the node so far
1796            may_be_none = False
1797            for assignment in self.cf_state:
1798                if assignment.rhs.may_be_none():
1799                    may_be_none = True
1800                    break
1801            del self._none_checking
1802            return may_be_none
1803        return super(NameNode, self).may_be_none()
1804
1805    def nonlocally_immutable(self):
1806        if ExprNode.nonlocally_immutable(self):
1807            return True
1808        entry = self.entry
1809        if not entry or entry.in_closure:
1810            return False
1811        return entry.is_local or entry.is_arg or entry.is_builtin or entry.is_readonly
1812
1813    def calculate_target_results(self, env):
1814        pass
1815
1816    def check_const(self):
1817        entry = self.entry
1818        if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1819            self.not_const()
1820            return False
1821        return True
1822
1823    def check_const_addr(self):
1824        entry = self.entry
1825        if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1826            self.addr_not_const()
1827            return False
1828        return True
1829
1830    def is_lvalue(self):
1831        return self.entry.is_variable and \
1832            not self.entry.type.is_array and \
1833            not self.entry.is_readonly
1834
1835    def is_addressable(self):
1836        return self.entry.is_variable and not self.type.is_memoryviewslice
1837
1838    def is_ephemeral(self):
1839        #  Name nodes are never ephemeral, even if the
1840        #  result is in a temporary.
1841        return 0
1842
1843    def calculate_result_code(self):
1844        entry = self.entry
1845        if not entry:
1846            return "<error>" # There was an error earlier
1847        return entry.cname
1848
1849    def generate_result_code(self, code):
1850        assert hasattr(self, 'entry')
1851        entry = self.entry
1852        if entry is None:
1853            return # There was an error earlier
1854        if entry.is_builtin and entry.is_const:
1855            return # Lookup already cached
1856        elif entry.is_pyclass_attr:
1857            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1858            interned_cname = code.intern_identifier(self.entry.name)
1859            if entry.is_builtin:
1860                namespace = Naming.builtins_cname
1861            else: # entry.is_pyglobal
1862                namespace = entry.scope.namespace_cname
1863            if not self.cf_is_null:
1864                code.putln(
1865                    '%s = PyObject_GetItem(%s, %s);' % (
1866                        self.result(),
1867                        namespace,
1868                        interned_cname))
1869                code.putln('if (unlikely(!%s)) {' % self.result())
1870                code.putln('PyErr_Clear();')
1871            code.globalstate.use_utility_code(
1872                UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
1873            code.putln(
1874                '%s = __Pyx_GetModuleGlobalName(%s);' % (
1875                    self.result(),
1876                    interned_cname))
1877            if not self.cf_is_null:
1878                code.putln("}")
1879            code.putln(code.error_goto_if_null(self.result(), self.pos))
1880            code.put_gotref(self.py_result())
1881
1882        elif entry.is_builtin:
1883            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1884            interned_cname = code.intern_identifier(self.entry.name)
1885            code.globalstate.use_utility_code(
1886                UtilityCode.load_cached("GetBuiltinName", "ObjectHandling.c"))
1887            code.putln(
1888                '%s = __Pyx_GetBuiltinName(%s); %s' % (
1889                self.result(),
1890                interned_cname,
1891                code.error_goto_if_null(self.result(), self.pos)))
1892            code.put_gotref(self.py_result())
1893
1894        elif entry.is_pyglobal:
1895            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1896            interned_cname = code.intern_identifier(self.entry.name)
1897            if entry.scope.is_module_scope:
1898                code.globalstate.use_utility_code(
1899                    UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
1900                code.putln(
1901                    '%s = __Pyx_GetModuleGlobalName(%s); %s' % (
1902                        self.result(),
1903                        interned_cname,
1904                        code.error_goto_if_null(self.result(), self.pos)))
1905            else:
1906                # FIXME: is_pyglobal is also used for class namespace
1907                code.globalstate.use_utility_code(
1908                    UtilityCode.load_cached("GetNameInClass", "ObjectHandling.c"))
1909                code.putln(
1910                    '%s = __Pyx_GetNameInClass(%s, %s); %s' % (
1911                        self.result(),
1912                        entry.scope.namespace_cname,
1913                        interned_cname,
1914                        code.error_goto_if_null(self.result(), self.pos)))
1915            code.put_gotref(self.py_result())
1916
1917        elif entry.is_local or entry.in_closure or entry.from_closure or entry.type.is_memoryviewslice:
1918            # Raise UnboundLocalError for objects and memoryviewslices
1919            raise_unbound = (
1920                (self.cf_maybe_null or self.cf_is_null) and not self.allow_null)
1921            null_code = entry.type.check_for_null_code(entry.cname)
1922
1923            memslice_check = entry.type.is_memoryviewslice and self.initialized_check
1924
1925            if null_code and raise_unbound and (entry.type.is_pyobject or memslice_check):
1926                code.put_error_if_unbound(self.pos, entry, self.in_nogil_context)
1927
1928    def generate_assignment_code(self, rhs, code):
1929        #print "NameNode.generate_assignment_code:", self.name ###
1930        entry = self.entry
1931        if entry is None:
1932            return # There was an error earlier
1933
1934        if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1935            and not self.lhs_of_first_assignment and not rhs.in_module_scope):
1936            error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1937
1938        # is_pyglobal seems to be True for module level-globals only.
1939        # We use this to access class->tp_dict if necessary.
1940        if entry.is_pyglobal:
1941            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1942            interned_cname = code.intern_identifier(self.entry.name)
1943            namespace = self.entry.scope.namespace_cname
1944            if entry.is_member:
1945                # if the entry is a member we have to cheat: SetAttr does not work
1946                # on types, so we create a descriptor which is then added to tp_dict
1947                setter = 'PyDict_SetItem'
1948                namespace = '%s->tp_dict' % namespace
1949            elif entry.scope.is_module_scope:
1950                setter = 'PyDict_SetItem'
1951                namespace = Naming.moddict_cname
1952            elif entry.is_pyclass_attr:
1953                setter = 'PyObject_SetItem'
1954            else:
1955                assert False, repr(entry)
1956            code.put_error_if_neg(
1957                self.pos,
1958                '%s(%s, %s, %s)' % (
1959                    setter,
1960                    namespace,
1961                    interned_cname,
1962                    rhs.py_result()))
1963            if debug_disposal_code:
1964                print("NameNode.generate_assignment_code:")
1965                print("...generating disposal code for %s" % rhs)
1966            rhs.generate_disposal_code(code)
1967            rhs.free_temps(code)
1968            if entry.is_member:
1969                # in Py2.6+, we need to invalidate the method cache
1970                code.putln("PyType_Modified(%s);" %
1971                           entry.scope.parent_type.typeptr_cname)
1972        else:
1973            if self.type.is_memoryviewslice:
1974                self.generate_acquire_memoryviewslice(rhs, code)
1975
1976            elif self.type.is_buffer:
1977                # Generate code for doing the buffer release/acquisition.
1978                # This might raise an exception in which case the assignment (done
1979                # below) will not happen.
1980                #
1981                # The reason this is not in a typetest-like node is because the
1982                # variables that the acquired buffer info is stored to is allocated
1983                # per entry and coupled with it.
1984                self.generate_acquire_buffer(rhs, code)
1985            assigned = False
1986            if self.type.is_pyobject:
1987                #print "NameNode.generate_assignment_code: to", self.name ###
1988                #print "...from", rhs ###
1989                #print "...LHS type", self.type, "ctype", self.ctype() ###
1990                #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1991                if self.use_managed_ref:
1992                    rhs.make_owned_reference(code)
1993                    is_external_ref = entry.is_cglobal or self.entry.in_closure or self.entry.from_closure
1994                    if is_external_ref:
1995                        if not self.cf_is_null:
1996                            if self.cf_maybe_null:
1997                                code.put_xgotref(self.py_result())
1998                            else:
1999                                code.put_gotref(self.py_result())
2000                    assigned = True
2001                    if entry.is_cglobal:
2002                        code.put_decref_set(
2003                            self.result(), rhs.result_as(self.ctype()))
2004                    else:
2005                        if not self.cf_is_null:
2006                            if self.cf_maybe_null:
2007                                code.put_xdecref_set(
2008                                    self.result(), rhs.result_as(self.ctype()))
2009                            else:
2010                                code.put_decref_set(
2011                                    self.result(), rhs.result_as(self.ctype()))
2012                        else:
2013                            assigned = False
2014                    if is_external_ref:
2015                        code.put_giveref(rhs.py_result())
2016            if not self.type.is_memoryviewslice:
2017                if not assigned:
2018                    code.putln('%s = %s;' % (
2019                        self.result(), rhs.result_as(self.ctype())))
2020                if debug_disposal_code:
2021                    print("NameNode.generate_assignment_code:")
2022                    print("...generating post-assignment code for %s" % rhs)
2023                rhs.generate_post_assignment_code(code)
2024            elif rhs.result_in_temp():
2025                rhs.generate_post_assignment_code(code)
2026
2027            rhs.free_temps(code)
2028
2029    def generate_acquire_memoryviewslice(self, rhs, code):
2030        """
2031        Slices, coercions from objects, return values etc are new references.
2032        We have a borrowed reference in case of dst = src
2033        """
2034        import MemoryView
2035
2036        MemoryView.put_acquire_memoryviewslice(
2037            lhs_cname=self.result(),
2038            lhs_type=self.type,
2039            lhs_pos=self.pos,
2040            rhs=rhs,
2041            code=code,
2042            have_gil=not self.in_nogil_context,
2043            first_assignment=self.cf_is_null)
2044
2045    def generate_acquire_buffer(self, rhs, code):
2046        # rhstmp is only used in case the rhs is a complicated expression leading to
2047        # the object, to avoid repeating the same C expression for every reference
2048        # to the rhs. It does NOT hold a reference.
2049        pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
2050        if pretty_rhs:
2051            rhstmp = rhs.result_as(self.ctype())
2052        else:
2053            rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
2054            code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
2055
2056        import Buffer
2057        Buffer.put_assign_to_buffer(self.result(), rhstmp, self.entry,
2058                                    is_initialized=not self.lhs_of_first_assignment,
2059                                    pos=self.pos, code=code)
2060
2061        if not pretty_rhs:
2062            code.putln("%s = 0;" % rhstmp)
2063            code.funcstate.release_temp(rhstmp)
2064
2065    def generate_deletion_code(self, code, ignore_nonexisting=False):
2066        if self.entry is None:
2067            return # There was an error earlier
2068        elif self.entry.is_pyclass_attr:
2069            namespace = self.entry.scope.namespace_cname
2070            interned_cname = code.intern_identifier(self.entry.name)
2071            if ignore_nonexisting:
2072                key_error_code = 'PyErr_Clear(); else'
2073            else:
2074                # minor hack: fake a NameError on KeyError
2075                key_error_code = (
2076                    '{ PyErr_Clear(); PyErr_Format(PyExc_NameError, "name \'%%s\' is not defined", "%s"); }' %
2077                    self.entry.name)
2078            code.putln(
2079                'if (unlikely(PyObject_DelItem(%s, %s) < 0)) {'
2080                ' if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) %s'
2081                ' %s '
2082                '}' % (namespace, interned_cname,
2083                       key_error_code,
2084                       code.error_goto(self.pos)))
2085        elif self.entry.is_pyglobal:
2086            code.globalstate.use_utility_code(
2087                UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
2088            interned_cname = code.intern_identifier(self.entry.name)
2089            del_code = '__Pyx_PyObject_DelAttrStr(%s, %s)' % (
2090                Naming.module_cname, interned_cname)
2091            if ignore_nonexisting:
2092                code.putln('if (unlikely(%s < 0)) { if (likely(PyErr_ExceptionMatches(PyExc_AttributeError))) PyErr_Clear(); else %s }' % (
2093                    del_code,
2094                    code.error_goto(self.pos)))
2095            else:
2096                code.put_error_if_neg(self.pos, del_code)
2097        elif self.entry.type.is_pyobject or self.entry.type.is_memoryviewslice:
2098            if not self.cf_is_null:
2099                if self.cf_maybe_null and not ignore_nonexisting:
2100                    code.put_error_if_unbound(self.pos, self.entry)
2101
2102                if self.entry.type.is_pyobject:
2103                    if self.entry.in_closure:
2104                        # generator
2105                        if ignore_nonexisting and self.cf_maybe_null:
2106                            code.put_xgotref(self.result())
2107                        else:
2108                            code.put_gotref(self.result())
2109                    if ignore_nonexisting and self.cf_maybe_null:
2110                        code.put_xdecref(self.result(), self.ctype())
2111                    else:
2112                        code.put_decref(self.result(), self.ctype())
2113                    code.putln('%s = NULL;' % self.result())
2114                else:
2115                    code.put_xdecref_memoryviewslice(self.entry.cname,
2116                                                     have_gil=not self.nogil)
2117        else:
2118            error(self.pos, "Deletion of C names not supported")
2119
2120    def annotate(self, code):
2121        if hasattr(self, 'is_called') and self.is_called:
2122            pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
2123            if self.type.is_pyobject:
2124                style, text = 'py_call', 'python function (%s)'
2125            else:
2126                style, text = 'c_call', 'c function (%s)'
2127            code.annotate(pos, AnnotationItem(style, text % self.type, size=len(self.name)))
2128
2129class BackquoteNode(ExprNode):
2130    #  `expr`
2131    #
2132    #  arg    ExprNode
2133
2134    type = py_object_type
2135
2136    subexprs = ['arg']
2137
2138    def analyse_types(self, env):
2139        self.arg = self.arg.analyse_types(env)
2140        self.arg = self.arg.coerce_to_pyobject(env)
2141        self.is_temp = 1
2142        return self
2143
2144    gil_message = "Backquote expression"
2145
2146    def calculate_constant_result(self):
2147        self.constant_result = repr(self.arg.constant_result)
2148
2149    def generate_result_code(self, code):
2150        code.putln(
2151            "%s = PyObject_Repr(%s); %s" % (
2152                self.result(),
2153                self.arg.py_result(),
2154                code.error_goto_if_null(self.result(), self.pos)))
2155        code.put_gotref(self.py_result())
2156
2157
2158class ImportNode(ExprNode):
2159    #  Used as part of import statement implementation.
2160    #  Implements result =
2161    #    __import__(module_name, globals(), None, name_list, level)
2162    #
2163    #  module_name   StringNode            dotted name of module. Empty module
2164    #                       name means importing the parent package according
2165    #                       to level
2166    #  name_list     ListNode or None      list of names to be imported
2167    #  level         int                   relative import level:
2168    #                       -1: attempt both relative import and absolute import;
2169    #                        0: absolute import;
2170    #                       >0: the number of parent directories to search
2171    #                           relative to the current module.
2172    #                     None: decide the level according to language level and
2173    #                           directives
2174
2175    type = py_object_type
2176
2177    subexprs = ['module_name', 'name_list']
2178
2179    def analyse_types(self, env):
2180        if self.level is None:
2181            if (env.directives['py2_import'] or
2182                Future.absolute_import not in env.global_scope().context.future_directives):
2183                self.level = -1
2184            else:
2185                self.level = 0
2186        module_name = self.module_name.analyse_types(env)
2187        self.module_name = module_name.coerce_to_pyobject(env)
2188        if self.name_list:
2189            name_list = self.name_list.analyse_types(env)
2190            self.name_list = name_list.coerce_to_pyobject(env)
2191        self.is_temp = 1
2192        env.use_utility_code(UtilityCode.load_cached("Import", "ImportExport.c"))
2193        return self
2194
2195    gil_message = "Python import"
2196
2197    def generate_result_code(self, code):
2198        if self.name_list:
2199            name_list_code = self.name_list.py_result()
2200        else:
2201            name_list_code = "0"
2202        code.putln(
2203            "%s = __Pyx_Import(%s, %s, %d); %s" % (
2204                self.result(),
2205                self.module_name.py_result(),
2206                name_list_code,
2207                self.level,
2208                code.error_goto_if_null(self.result(), self.pos)))
2209        code.put_gotref(self.py_result())
2210
2211
2212class IteratorNode(ExprNode):
2213    #  Used as part of for statement implementation.
2214    #
2215    #  Implements result = iter(sequence)
2216    #
2217    #  sequence   ExprNode
2218
2219    type = py_object_type
2220    iter_func_ptr = None
2221    counter_cname = None
2222    cpp_iterator_cname = None
2223    reversed = False      # currently only used for list/tuple types (see Optimize.py)
2224
2225    subexprs = ['sequence']
2226
2227    def analyse_types(self, env):
2228        self.sequence = self.sequence.analyse_types(env)
2229        if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
2230                not self.sequence.type.is_string:
2231            # C array iteration will be transformed later on
2232            self.type = self.sequence.type
2233        elif self.sequence.type.is_cpp_class:
2234            self.analyse_cpp_types(env)
2235        else:
2236            self.sequence = self.sequence.coerce_to_pyobject(env)
2237            if self.sequence.type is list_type or \
2238                   self.sequence.type is tuple_type:
2239                self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
2240        self.is_temp = 1
2241        return self
2242
2243    gil_message = "Iterating over Python object"
2244
2245    _func_iternext_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
2246        PyrexTypes.py_object_type, [
2247            PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None),
2248            ]))
2249
2250    def type_dependencies(self, env):
2251        return self.sequence.type_dependencies(env)
2252
2253    def infer_type(self, env):
2254        sequence_type = self.sequence.infer_type(env)
2255        if sequence_type.is_array or sequence_type.is_ptr:
2256            return sequence_type
2257        elif sequence_type.is_cpp_class:
2258            begin = sequence_type.scope.lookup("begin")
2259            if begin is not None:
2260                return begin.type.return_type
2261        elif sequence_type.is_pyobject:
2262            return sequence_type
2263        return py_object_type
2264
2265    def analyse_cpp_types(self, env):
2266        sequence_type = self.sequence.type
2267        if sequence_type.is_ptr:
2268            sequence_type = sequence_type.base_type
2269        begin = sequence_type.scope.lookup("begin")
2270        end = sequence_type.scope.lookup("end")
2271        if (begin is None
2272            or not begin.type.is_cfunction
2273            or begin.type.args):
2274            error(self.pos, "missing begin() on %s" % self.sequence.type)
2275            self.type = error_type
2276            return
2277        if (end is None
2278            or not end.type.is_cfunction
2279            or end.type.args):
2280            error(self.pos, "missing end() on %s" % self.sequence.type)
2281            self.type = error_type
2282            return
2283        iter_type = begin.type.return_type
2284        if iter_type.is_cpp_class:
2285            if env.lookup_operator_for_types(
2286                    self.pos,
2287                    "!=",
2288                    [iter_type, end.type.return_type]) is None:
2289                error(self.pos, "missing operator!= on result of begin() on %s" % self.sequence.type)
2290                self.type = error_type
2291                return
2292            if env.lookup_operator_for_types(self.pos, '++', [iter_type]) is None:
2293                error(self.pos, "missing operator++ on result of begin() on %s" % self.sequence.type)
2294                self.type = error_type
2295                return
2296            if env.lookup_operator_for_types(self.pos, '*', [iter_type]) is None:
2297                error(self.pos, "missing operator* on result of begin() on %s" % self.sequence.type)
2298                self.type = error_type
2299                return
2300            self.type = iter_type
2301        elif iter_type.is_ptr:
2302            if not (iter_type == end.type.return_type):
2303                error(self.pos, "incompatible types for begin() and end()")
2304            self.type = iter_type
2305        else:
2306            error(self.pos, "result type of begin() on %s must be a C++ class or pointer" % self.sequence.type)
2307            self.type = error_type
2308            return
2309
2310    def generate_result_code(self, code):
2311        sequence_type = self.sequence.type
2312        if sequence_type.is_cpp_class:
2313            if self.sequence.is_name:
2314                # safe: C++ won't allow you to reassign to class references
2315                begin_func = "%s.begin" % self.sequence.result()
2316            else:
2317                sequence_type = PyrexTypes.c_ptr_type(sequence_type)
2318                self.cpp_iterator_cname = code.funcstate.allocate_temp(sequence_type, manage_ref=False)
2319                code.putln("%s = &%s;" % (self.cpp_iterator_cname, self.sequence.result()))
2320                begin_func = "%s->begin" % self.cpp_iterator_cname
2321            # TODO: Limit scope.
2322            code.putln("%s = %s();" % (self.result(), begin_func))
2323            return
2324        if sequence_type.is_array or sequence_type.is_ptr:
2325            raise InternalError("for in carray slice not transformed")
2326        is_builtin_sequence = sequence_type is list_type or \
2327                              sequence_type is tuple_type
2328        if not is_builtin_sequence:
2329            # reversed() not currently optimised (see Optimize.py)
2330            assert not self.reversed, "internal error: reversed() only implemented for list/tuple objects"
2331        self.may_be_a_sequence = not sequence_type.is_builtin_type
2332        if self.may_be_a_sequence:
2333            code.putln(
2334                "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
2335                    self.sequence.py_result(),
2336                    self.sequence.py_result()))
2337        if is_builtin_sequence or self.may_be_a_sequence:
2338            self.counter_cname = code.funcstate.allocate_temp(
2339                PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2340            if self.reversed:
2341                if sequence_type is list_type:
2342                    init_value = 'PyList_GET_SIZE(%s) - 1' % self.result()
2343                else:
2344                    init_value = 'PyTuple_GET_SIZE(%s) - 1' % self.result()
2345            else:
2346                init_value = '0'
2347            code.putln(
2348                "%s = %s; __Pyx_INCREF(%s); %s = %s;" % (
2349                    self.result(),
2350                    self.sequence.py_result(),
2351                    self.result(),
2352                    self.counter_cname,
2353                    init_value
2354                    ))
2355        if not is_builtin_sequence:
2356            self.iter_func_ptr = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
2357            if self.may_be_a_sequence:
2358                code.putln("%s = NULL;" % self.iter_func_ptr)
2359                code.putln("} else {")
2360                code.put("%s = -1; " % self.counter_cname)
2361            code.putln("%s = PyObject_GetIter(%s); %s" % (
2362                    self.result(),
2363                    self.sequence.py_result(),
2364                    code.error_goto_if_null(self.result(), self.pos)))
2365            code.put_gotref(self.py_result())
2366            code.putln("%s = Py_TYPE(%s)->tp_iternext;" % (self.iter_func_ptr, self.py_result()))
2367        if self.may_be_a_sequence:
2368            code.putln("}")
2369
2370    def generate_next_sequence_item(self, test_name, result_name, code):
2371        assert self.counter_cname, "internal error: counter_cname temp not prepared"
2372        final_size = 'Py%s_GET_SIZE(%s)' % (test_name, self.py_result())
2373        if self.sequence.is_sequence_constructor:
2374            item_count = len(self.sequence.args)
2375            if self.sequence.mult_factor is None:
2376                final_size = item_count
2377            elif isinstance(self.sequence.mult_factor.constant_result, (int, long)):
2378                final_size = item_count * self.sequence.mult_factor.constant_result
2379        code.putln("if (%s >= %s) break;" % (self.counter_cname, final_size))
2380        if self.reversed:
2381            inc_dec = '--'
2382        else:
2383            inc_dec = '++'
2384        code.putln("#if CYTHON_COMPILING_IN_CPYTHON")
2385        code.putln(
2386            "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s%s; %s" % (
2387                result_name,
2388                test_name,
2389                self.py_result(),
2390                self.counter_cname,
2391                result_name,
2392                self.counter_cname,
2393                inc_dec,
2394                # use the error label to avoid C compiler warnings if we only use it below
2395                code.error_goto_if_neg('0', self.pos)
2396                ))
2397        code.putln("#else")
2398        code.putln(
2399            "%s = PySequence_ITEM(%s, %s); %s%s; %s" % (
2400                result_name,
2401                self.py_result(),
2402                self.counter_cname,
2403                self.counter_cname,
2404                inc_dec,
2405                code.error_goto_if_null(result_name, self.pos)))
2406        code.putln("#endif")
2407
2408    def generate_iter_next_result_code(self, result_name, code):
2409        sequence_type = self.sequence.type
2410        if self.reversed:
2411            code.putln("if (%s < 0) break;" % self.counter_cname)
2412        if sequence_type.is_cpp_class:
2413            if self.cpp_iterator_cname:
2414                end_func = "%s->end" % self.cpp_iterator_cname
2415            else:
2416                end_func = "%s.end" % self.sequence.result()
2417            # TODO: Cache end() call?
2418            code.putln("if (!(%s != %s())) break;" % (
2419                            self.result(),
2420                            end_func))
2421            code.putln("%s = *%s;" % (
2422                            result_name,
2423                            self.result()))
2424            code.putln("++%s;" % self.result())
2425            return
2426        elif sequence_type is list_type:
2427            self.generate_next_sequence_item('List', result_name, code)
2428            return
2429        elif sequence_type is tuple_type:
2430            self.generate_next_sequence_item('Tuple', result_name, code)
2431            return
2432
2433        if self.may_be_a_sequence:
2434            for test_name in ('List', 'Tuple'):
2435                code.putln("if (!%s && Py%s_CheckExact(%s)) {" % (
2436                    self.iter_func_ptr, test_name, self.py_result()))
2437                self.generate_next_sequence_item(test_name, result_name, code)
2438                code.put("} else ")
2439
2440        code.putln("{")
2441        code.putln(
2442            "%s = %s(%s);" % (
2443                result_name,
2444                self.iter_func_ptr,
2445                self.py_result()))
2446        code.putln("if (unlikely(!%s)) {" % result_name)
2447        code.putln("PyObject* exc_type = PyErr_Occurred();")
2448        code.putln("if (exc_type) {")
2449        code.putln("if (likely(exc_type == PyExc_StopIteration ||"
2450                   " PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();")
2451        code.putln("else %s" % code.error_goto(self.pos))
2452        code.putln("}")
2453        code.putln("break;")
2454        code.putln("}")
2455        code.put_gotref(result_name)
2456        code.putln("}")
2457
2458    def free_temps(self, code):
2459        if self.counter_cname:
2460            code.funcstate.release_temp(self.counter_cname)
2461        if self.iter_func_ptr:
2462            code.funcstate.release_temp(self.iter_func_ptr)
2463            self.iter_func_ptr = None
2464        if self.cpp_iterator_cname:
2465            code.funcstate.release_temp(self.cpp_iterator_cname)
2466        ExprNode.free_temps(self, code)
2467
2468
2469class NextNode(AtomicExprNode):
2470    #  Used as part of for statement implementation.
2471    #  Implements result = iterator.next()
2472    #  Created during analyse_types phase.
2473    #  The iterator is not owned by this node.
2474    #
2475    #  iterator   IteratorNode
2476
2477    def __init__(self, iterator):
2478        AtomicExprNode.__init__(self, iterator.pos)
2479        self.iterator = iterator
2480
2481    def type_dependencies(self, env):
2482        return self.iterator.type_dependencies(env)
2483
2484    def infer_type(self, env, iterator_type = None):
2485        if iterator_type is None:
2486            iterator_type = self.iterator.infer_type(env)
2487        if iterator_type.is_ptr or iterator_type.is_array:
2488            return iterator_type.base_type
2489        elif iterator_type.is_cpp_class:
2490            item_type = env.lookup_operator_for_types(self.pos, "*", [iterator_type]).type.return_type
2491            if item_type.is_reference:
2492                item_type = item_type.ref_base_type
2493            if item_type.is_const:
2494                item_type = item_type.const_base_type
2495            return item_type
2496        else:
2497            # Avoid duplication of complicated logic.
2498            fake_index_node = IndexNode(
2499                self.pos,
2500                base=self.iterator.sequence,
2501                index=IntNode(self.pos, value='PY_SSIZE_T_MAX',
2502                              type=PyrexTypes.c_py_ssize_t_type))
2503            return fake_index_node.infer_type(env)
2504
2505    def analyse_types(self, env):
2506        self.type = self.infer_type(env, self.iterator.type)
2507        self.is_temp = 1
2508        return self
2509
2510    def generate_result_code(self, code):
2511        self.iterator.generate_iter_next_result_code(self.result(), code)
2512
2513
2514class WithExitCallNode(ExprNode):
2515    # The __exit__() call of a 'with' statement.  Used in both the
2516    # except and finally clauses.
2517
2518    # with_stat  WithStatNode                the surrounding 'with' statement
2519    # args       TupleNode or ResultStatNode the exception info tuple
2520
2521    subexprs = ['args']
2522    test_if_run = True
2523
2524    def analyse_types(self, env):
2525        self.args = self.args.analyse_types(env)
2526        self.type = PyrexTypes.c_bint_type
2527        self.is_temp = True
2528        return self
2529
2530    def generate_evaluation_code(self, code):
2531        if self.test_if_run:
2532            # call only if it was not already called (and decref-cleared)
2533            code.putln("if (%s) {" % self.with_stat.exit_var)
2534
2535        self.args.generate_evaluation_code(code)
2536        result_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
2537
2538        code.mark_pos(self.pos)
2539        code.globalstate.use_utility_code(UtilityCode.load_cached(
2540            "PyObjectCall", "ObjectHandling.c"))
2541        code.putln("%s = __Pyx_PyObject_Call(%s, %s, NULL);" % (
2542            result_var,
2543            self.with_stat.exit_var,
2544            self.args.result()))
2545        code.put_decref_clear(self.with_stat.exit_var, type=py_object_type)
2546        self.args.generate_disposal_code(code)
2547        self.args.free_temps(code)
2548
2549        code.putln(code.error_goto_if_null(result_var, self.pos))
2550        code.put_gotref(result_var)
2551        if self.result_is_used:
2552            self.allocate_temp_result(code)
2553            code.putln("%s = __Pyx_PyObject_IsTrue(%s);" % (self.result(), result_var))
2554        code.put_decref_clear(result_var, type=py_object_type)
2555        if self.result_is_used:
2556            code.put_error_if_neg(self.pos, self.result())
2557        code.funcstate.release_temp(result_var)
2558        if self.test_if_run:
2559            code.putln("}")
2560
2561
2562class ExcValueNode(AtomicExprNode):
2563    #  Node created during analyse_types phase
2564    #  of an ExceptClauseNode to fetch the current
2565    #  exception value.
2566
2567    type = py_object_type
2568
2569    def __init__(self, pos):
2570        ExprNode.__init__(self, pos)
2571
2572    def set_var(self, var):
2573        self.var = var
2574
2575    def calculate_result_code(self):
2576        return self.var
2577
2578    def generate_result_code(self, code):
2579        pass
2580
2581    def analyse_types(self, env):
2582        return self
2583
2584
2585class TempNode(ExprNode):
2586    # Node created during analyse_types phase
2587    # of some nodes to hold a temporary value.
2588    #
2589    # Note: One must call "allocate" and "release" on
2590    # the node during code generation to get/release the temp.
2591    # This is because the temp result is often used outside of
2592    # the regular cycle.
2593
2594    subexprs = []
2595
2596    def __init__(self, pos, type, env=None):
2597        ExprNode.__init__(self, pos)
2598        self.type = type
2599        if type.is_pyobject:
2600            self.result_ctype = py_object_type
2601        self.is_temp = 1
2602
2603    def analyse_types(self, env):
2604        return self
2605
2606    def analyse_target_declaration(self, env):
2607        pass
2608
2609    def generate_result_code(self, code):
2610        pass
2611
2612    def allocate(self, code):
2613        self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
2614
2615    def release(self, code):
2616        code.funcstate.release_temp(self.temp_cname)
2617        self.temp_cname = None
2618
2619    def result(self):
2620        try:
2621            return self.temp_cname
2622        except:
2623            assert False, "Remember to call allocate/release on TempNode"
2624            raise
2625
2626    # Do not participate in normal temp alloc/dealloc:
2627    def allocate_temp_result(self, code):
2628        pass
2629
2630    def release_temp_result(self, code):
2631        pass
2632
2633class PyTempNode(TempNode):
2634    #  TempNode holding a Python value.
2635
2636    def __init__(self, pos, env):
2637        TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
2638
2639class RawCNameExprNode(ExprNode):
2640    subexprs = []
2641
2642    def __init__(self, pos, type=None, cname=None):
2643        ExprNode.__init__(self, pos, type=type)
2644        if cname is not None:
2645            self.cname = cname
2646
2647    def analyse_types(self, env):
2648        return self
2649
2650    def set_cname(self, cname):
2651        self.cname = cname
2652
2653    def result(self):
2654        return self.cname
2655
2656    def generate_result_code(self, code):
2657        pass
2658
2659
2660#-------------------------------------------------------------------
2661#
2662#  Parallel nodes (cython.parallel.thread(savailable|id))
2663#
2664#-------------------------------------------------------------------
2665
2666class ParallelThreadsAvailableNode(AtomicExprNode):
2667    """
2668    Note: this is disabled and not a valid directive at this moment
2669
2670    Implements cython.parallel.threadsavailable(). If we are called from the
2671    sequential part of the application, we need to call omp_get_max_threads(),
2672    and in the parallel part we can just call omp_get_num_threads()
2673    """
2674
2675    type = PyrexTypes.c_int_type
2676
2677    def analyse_types(self, env):
2678        self.is_temp = True
2679        # env.add_include_file("omp.h")
2680        return self
2681
2682    def generate_result_code(self, code):
2683        code.putln("#ifdef _OPENMP")
2684        code.putln("if (omp_in_parallel()) %s = omp_get_max_threads();" %
2685                                                            self.temp_code)
2686        code.putln("else %s = omp_get_num_threads();" % self.temp_code)
2687        code.putln("#else")
2688        code.putln("%s = 1;" % self.temp_code)
2689        code.putln("#endif")
2690
2691    def result(self):
2692        return self.temp_code
2693
2694
2695class ParallelThreadIdNode(AtomicExprNode): #, Nodes.ParallelNode):
2696    """
2697    Implements cython.parallel.threadid()
2698    """
2699
2700    type = PyrexTypes.c_int_type
2701
2702    def analyse_types(self, env):
2703        self.is_temp = True
2704        # env.add_include_file("omp.h")
2705        return self
2706
2707    def generate_result_code(self, code):
2708        code.putln("#ifdef _OPENMP")
2709        code.putln("%s = omp_get_thread_num();" % self.temp_code)
2710        code.putln("#else")
2711        code.putln("%s = 0;" % self.temp_code)
2712        code.putln("#endif")
2713
2714    def result(self):
2715        return self.temp_code
2716
2717
2718#-------------------------------------------------------------------
2719#
2720#  Trailer nodes
2721#
2722#-------------------------------------------------------------------
2723
2724class IndexNode(ExprNode):
2725    #  Sequence indexing.
2726    #
2727    #  base     ExprNode
2728    #  index    ExprNode
2729    #  indices  [ExprNode]
2730    #  type_indices  [PyrexType]
2731    #  is_buffer_access boolean Whether this is a buffer access.
2732    #
2733    #  indices is used on buffer access, index on non-buffer access.
2734    #  The former contains a clean list of index parameters, the
2735    #  latter whatever Python object is needed for index access.
2736    #
2737    #  is_fused_index boolean   Whether the index is used to specialize a
2738    #                           c(p)def function
2739
2740    subexprs = ['base', 'index', 'indices']
2741    indices = None
2742    type_indices = None
2743
2744    is_subscript = True
2745    is_fused_index = False
2746
2747    # Whether we're assigning to a buffer (in that case it needs to be
2748    # writable)
2749    writable_needed = False
2750
2751    # Whether we are indexing or slicing a memoryviewslice
2752    memslice_index = False
2753    memslice_slice = False
2754    is_memslice_copy = False
2755    memslice_ellipsis_noop = False
2756    warned_untyped_idx = False
2757    # set by SingleAssignmentNode after analyse_types()
2758    is_memslice_scalar_assignment = False
2759
2760    def __init__(self, pos, index, **kw):
2761        ExprNode.__init__(self, pos, index=index, **kw)
2762        self._index = index
2763
2764    def calculate_constant_result(self):
2765        self.constant_result = \
2766            self.base.constant_result[self.index.constant_result]
2767
2768    def compile_time_value(self, denv):
2769        base = self.base.compile_time_value(denv)
2770        index = self.index.compile_time_value(denv)
2771        try:
2772            return base[index]
2773        except Exception, e:
2774            self.compile_time_value_error(e)
2775
2776    def is_ephemeral(self):
2777        return self.base.is_ephemeral()
2778
2779    def is_simple(self):
2780        if self.is_buffer_access or self.memslice_index:
2781            return False
2782        elif self.memslice_slice:
2783            return True
2784
2785        base = self.base
2786        return (base.is_simple() and self.index.is_simple()
2787                and base.type and (base.type.is_ptr or base.type.is_array))
2788
2789    def may_be_none(self):
2790        base_type = self.base.type
2791        if base_type:
2792            if base_type.is_string:
2793                return False
2794            if isinstance(self.index, SliceNode):
2795                # slicing!
2796                if base_type in (bytes_type, str_type, unicode_type,
2797                                 basestring_type, list_type, tuple_type):
2798                    return False
2799        return ExprNode.may_be_none(self)
2800
2801    def analyse_target_declaration(self, env):
2802        pass
2803
2804    def analyse_as_type(self, env):
2805        base_type = self.base.analyse_as_type(env)
2806        if base_type and not base_type.is_pyobject:
2807            if base_type.is_cpp_class:
2808                if isinstance(self.index, TupleNode):
2809                    template_values = self.index.args
2810                else:
2811                    template_values = [self.index]
2812                import Nodes
2813                type_node = Nodes.TemplatedTypeNode(
2814                    pos = self.pos,
2815                    positional_args = template_values,
2816                    keyword_args = None)
2817                return type_node.analyse(env, base_type = base_type)
2818            else:
2819                index = self.index.compile_time_value(env)
2820                if index is not None:
2821                    return PyrexTypes.CArrayType(base_type, int(index))
2822                error(self.pos, "Array size must be a compile time constant")
2823        return None
2824
2825    def type_dependencies(self, env):
2826        return self.base.type_dependencies(env) + self.index.type_dependencies(env)
2827
2828    def infer_type(self, env):
2829        base_type = self.base.infer_type(env)
2830        if isinstance(self.index, SliceNode):
2831            # slicing!
2832            if base_type.is_string:
2833                # sliced C strings must coerce to Python
2834                return bytes_type
2835            elif base_type.is_pyunicode_ptr:
2836                # sliced Py_UNICODE* strings must coerce to Python
2837                return unicode_type
2838            elif base_type in (unicode_type, bytes_type, str_type,
2839                               bytearray_type, list_type, tuple_type):
2840                # slicing these returns the same type
2841                return base_type
2842            else:
2843                # TODO: Handle buffers (hopefully without too much redundancy).
2844                return py_object_type
2845
2846        index_type = self.index.infer_type(env)
2847        if index_type and index_type.is_int or isinstance(self.index, IntNode):
2848            # indexing!
2849            if base_type is unicode_type:
2850                # Py_UCS4 will automatically coerce to a unicode string
2851                # if required, so this is safe.  We only infer Py_UCS4
2852                # when the index is a C integer type.  Otherwise, we may
2853                # need to use normal Python item access, in which case
2854                # it's faster to return the one-char unicode string than
2855                # to receive it, throw it away, and potentially rebuild it
2856                # on a subsequent PyObject coercion.
2857                return PyrexTypes.c_py_ucs4_type
2858            elif base_type is str_type:
2859                # always returns str - Py2: bytes, Py3: unicode
2860                return base_type
2861            elif base_type is bytearray_type:
2862                return PyrexTypes.c_uchar_type
2863            elif isinstance(self.base, BytesNode):
2864                #if env.global_scope().context.language_level >= 3:
2865                #    # inferring 'char' can be made to work in Python 3 mode
2866                #    return PyrexTypes.c_char_type
2867                # Py2/3 return different types on indexing bytes objects
2868                return py_object_type
2869            elif base_type in (tuple_type, list_type):
2870                # if base is a literal, take a look at its values
2871                item_type = infer_sequence_item_type(
2872                    env, self.base, self.index, seq_type=base_type)
2873                if item_type is not None:
2874                    return item_type
2875            elif base_type.is_ptr or base_type.is_array:
2876                return base_type.base_type
2877
2878        if base_type.is_cpp_class:
2879            class FakeOperand:
2880                def __init__(self, **kwds):
2881                    self.__dict__.update(kwds)
2882            operands = [
2883                FakeOperand(pos=self.pos, type=base_type),
2884                FakeOperand(pos=self.pos, type=index_type),
2885            ]
2886            index_func = env.lookup_operator('[]', operands)
2887            if index_func is not None:
2888                return index_func.type.return_type
2889
2890        # may be slicing or indexing, we don't know
2891        if base_type in (unicode_type, str_type):
2892            # these types always returns their own type on Python indexing/slicing
2893            return base_type
2894        else:
2895            # TODO: Handle buffers (hopefully without too much redundancy).
2896            return py_object_type
2897
2898    def analyse_types(self, env):
2899        return self.analyse_base_and_index_types(env, getting=True)
2900
2901    def analyse_target_types(self, env):
2902        node = self.analyse_base_and_index_types(env, setting=True)
2903        if node.type.is_const:
2904            error(self.pos, "Assignment to const dereference")
2905        if not node.is_lvalue():
2906            error(self.pos, "Assignment to non-lvalue of type '%s'" % node.type)
2907        return node
2908
2909    def analyse_base_and_index_types(self, env, getting=False, setting=False,
2910                                     analyse_base=True):
2911        # Note: This might be cleaned up by having IndexNode
2912        # parsed in a saner way and only construct the tuple if
2913        # needed.
2914
2915        # Note that this function must leave IndexNode in a cloneable state.
2916        # For buffers, self.index is packed out on the initial analysis, and
2917        # when cloning self.indices is copied.
2918        self.is_buffer_access = False
2919
2920        # a[...] = b
2921        self.is_memslice_copy = False
2922        # incomplete indexing, Ellipsis indexing or slicing
2923        self.memslice_slice = False
2924        # integer indexing
2925        self.memslice_index = False
2926
2927        if analyse_base:
2928            self.base = self.base.analyse_types(env)
2929
2930        if self.base.type.is_error:
2931            # Do not visit child tree if base is undeclared to avoid confusing
2932            # error messages
2933            self.type = PyrexTypes.error_type
2934            return self
2935
2936        is_slice = isinstance(self.index, SliceNode)
2937
2938        if not env.directives['wraparound']:
2939            if is_slice:
2940                check_negative_indices(self.index.start, self.index.stop)
2941            else:
2942                check_negative_indices(self.index)
2943
2944        # Potentially overflowing index value.
2945        if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2946            self.index = self.index.coerce_to_pyobject(env)
2947
2948        is_memslice = self.base.type.is_memoryviewslice
2949
2950        # Handle the case where base is a literal char* (and we expect a string, not an int)
2951        if not is_memslice and (isinstance(self.base, BytesNode) or is_slice):
2952            if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2953                self.base = self.base.coerce_to_pyobject(env)
2954
2955        skip_child_analysis = False
2956        buffer_access = False
2957
2958        if self.indices:
2959            indices = self.indices
2960        elif isinstance(self.index, TupleNode):
2961            indices = self.index.args
2962        else:
2963            indices = [self.index]
2964
2965        if (is_memslice and not self.indices and
2966                isinstance(self.index, EllipsisNode)):
2967            # Memoryviewslice copying
2968            self.is_memslice_copy = True
2969
2970        elif is_memslice:
2971            # memoryviewslice indexing or slicing
2972            import MemoryView
2973
2974            skip_child_analysis = True
2975            newaxes = [newaxis for newaxis in indices if newaxis.is_none]
2976            have_slices, indices = MemoryView.unellipsify(indices,
2977                                                          newaxes,
2978                                                          self.base.type.ndim)
2979
2980            self.memslice_index = (not newaxes and
2981                                   len(indices) == self.base.type.ndim)
2982            axes = []
2983
2984            index_type = PyrexTypes.c_py_ssize_t_type
2985            new_indices = []
2986
2987            if len(indices) - len(newaxes) > self.base.type.ndim:
2988                self.type = error_type
2989                error(indices[self.base.type.ndim].pos,
2990                      "Too many indices specified for type %s" %
2991                      self.base.type)
2992                return self
2993
2994            axis_idx = 0
2995            for i, index in enumerate(indices[:]):
2996                index = index.analyse_types(env)
2997                if not index.is_none:
2998                    access, packing = self.base.type.axes[axis_idx]
2999                    axis_idx += 1
3000
3001                if isinstance(index, SliceNode):
3002                    self.memslice_slice = True
3003                    if index.step.is_none:
3004                        axes.append((access, packing))
3005                    else:
3006                        axes.append((access, 'strided'))
3007
3008                    # Coerce start, stop and step to temps of the right type
3009                    for attr in ('start', 'stop', 'step'):
3010                        value = getattr(index, attr)
3011                        if not value.is_none:
3012                            value = value.coerce_to(index_type, env)
3013                            #value = value.coerce_to_temp(env)
3014                            setattr(index, attr, value)
3015                            new_indices.append(value)
3016
3017                elif index.is_none:
3018                    self.memslice_slice = True
3019                    new_indices.append(index)
3020                    axes.append(('direct', 'strided'))
3021
3022                elif index.type.is_int or index.type.is_pyobject:
3023                    if index.type.is_pyobject and not self.warned_untyped_idx:
3024                        warning(index.pos, "Index should be typed for more "
3025                                           "efficient access", level=2)
3026                        IndexNode.warned_untyped_idx = True
3027
3028                    self.memslice_index = True
3029                    index = index.coerce_to(index_type, env)
3030                    indices[i] = index
3031                    new_indices.append(index)
3032
3033                else:
3034                    self.type = error_type
3035                    error(index.pos, "Invalid index for memoryview specified")
3036                    return self
3037
3038            self.memslice_index = self.memslice_index and not self.memslice_slice
3039            self.original_indices = indices
3040            # All indices with all start/stop/step for slices.
3041            # We need to keep this around
3042            self.indices = new_indices
3043            self.env = env
3044
3045        elif self.base.type.is_buffer:
3046            # Buffer indexing
3047            if len(indices) == self.base.type.ndim:
3048                buffer_access = True
3049                skip_child_analysis = True
3050                for x in indices:
3051                    x = x.analyse_types(env)
3052                    if not x.type.is_int:
3053                        buffer_access = False
3054
3055            if buffer_access and not self.base.type.is_memoryviewslice:
3056                assert hasattr(self.base, "entry") # Must be a NameNode-like node
3057
3058        # On cloning, indices is cloned. Otherwise, unpack index into indices
3059        assert not (buffer_access and isinstance(self.index, CloneNode))
3060
3061        self.nogil = env.nogil
3062
3063        if buffer_access or self.memslice_index:
3064            #if self.base.type.is_memoryviewslice and not self.base.is_name:
3065            #    self.base = self.base.coerce_to_temp(env)
3066            self.base = self.base.coerce_to_simple(env)
3067
3068            self.indices = indices
3069            self.index = None
3070            self.type = self.base.type.dtype
3071            self.is_buffer_access = True
3072            self.buffer_type = self.base.type #self.base.entry.type
3073
3074            if getting and self.type.is_pyobject:
3075                self.is_temp = True
3076
3077            if setting and self.base.type.is_memoryviewslice:
3078                self.base.type.writable_needed = True
3079            elif setting:
3080                if not self.base.entry.type.writable:
3081                    error(self.pos, "Writing to readonly buffer")
3082                else:
3083                    self.writable_needed = True
3084                    if self.base.type.is_buffer:
3085                        self.base.entry.buffer_aux.writable_needed = True
3086
3087        elif self.is_memslice_copy:
3088            self.type = self.base.type
3089            if getting:
3090                self.memslice_ellipsis_noop = True
3091            else:
3092                self.memslice_broadcast = True
3093
3094        elif self.memslice_slice:
3095            self.index = None
3096            self.is_temp = True
3097            self.use_managed_ref = True
3098
3099            if not MemoryView.validate_axes(self.pos, axes):
3100                self.type = error_type
3101                return self
3102
3103            self.type = PyrexTypes.MemoryViewSliceType(
3104                            self.base.type.dtype, axes)
3105
3106            if (self.base.type.is_memoryviewslice and not
3107                    self.base.is_name and not
3108                    self.base.result_in_temp()):
3109                self.base = self.base.coerce_to_temp(env)
3110
3111            if setting:
3112                self.memslice_broadcast = True
3113
3114        else:
3115            base_type = self.base.type
3116
3117            if not base_type.is_cfunction:
3118                if isinstance(self.index, TupleNode):
3119                    self.index = self.index.analyse_types(
3120                        env, skip_children=skip_child_analysis)
3121                elif not skip_child_analysis:
3122                    self.index = self.index.analyse_types(env)
3123                self.original_index_type = self.index.type
3124
3125            if base_type.is_unicode_char:
3126                # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
3127                # cases, but indexing must still work for them
3128                if setting:
3129                    warning(self.pos, "cannot assign to Unicode string index", level=1)
3130                elif self.index.constant_result in (0, -1):
3131                    # uchar[0] => uchar
3132                    return self.base
3133                self.base = self.base.coerce_to_pyobject(env)
3134                base_type = self.base.type
3135            if base_type.is_pyobject:
3136                if self.index.type.is_int and base_type is not dict_type:
3137                    if (getting
3138                        and (base_type in (list_type, tuple_type, bytearray_type))
3139                        and (not self.index.type.signed
3140                             or not env.directives['wraparound']
3141                             or (isinstance(self.index, IntNode) and
3142                                 self.index.has_constant_result() and self.index.constant_result >= 0))
3143                        and not env.directives['boundscheck']):
3144                        self.is_temp = 0
3145                    else:
3146                        self.is_temp = 1
3147                    self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
3148                    self.original_index_type.create_to_py_utility_code(env)
3149                else:
3150                    self.index = self.index.coerce_to_pyobject(env)
3151                    self.is_temp = 1
3152                if self.index.type.is_int and base_type is unicode_type:
3153                    # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
3154                    # if required, so this is fast and safe
3155                    self.type = PyrexTypes.c_py_ucs4_type
3156                elif self.index.type.is_int and base_type is bytearray_type:
3157                    if setting:
3158                        self.type = PyrexTypes.c_uchar_type
3159                    else:
3160                        # not using 'uchar' to enable fast and safe error reporting as '-1'
3161                        self.type = PyrexTypes.c_int_type
3162                elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
3163                    self.type = base_type
3164                else:
3165                    item_type = None
3166                    if base_type in (list_type, tuple_type) and self.index.type.is_int:
3167                        item_type = infer_sequence_item_type(
3168                            env, self.base, self.index, seq_type=base_type)
3169                    if item_type is None:
3170                        item_type = py_object_type
3171                    self.type = item_type
3172                    if base_type in (list_type, tuple_type, dict_type):
3173                        # do the None check explicitly (not in a helper) to allow optimising it away
3174                        self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
3175            else:
3176                if base_type.is_ptr or base_type.is_array:
3177                    self.type = base_type.base_type
3178                    if is_slice:
3179                        self.type = base_type
3180                    elif self.index.type.is_pyobject:
3181                        self.index = self.index.coerce_to(
3182                            PyrexTypes.c_py_ssize_t_type, env)
3183                    elif not self.index.type.is_int:
3184                        error(self.pos,
3185                              "Invalid index type '%s'" %
3186                              self.index.type)
3187                elif base_type.is_cpp_class:
3188                    function = env.lookup_operator("[]", [self.base, self.index])
3189                    if function is None:
3190                        error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
3191                        self.type = PyrexTypes.error_type
3192                        self.result_code = "<error>"
3193                        return self
3194                    func_type = function.type
3195                    if func_type.is_ptr:
3196                        func_type = func_type.base_type
3197                    self.index = self.index.coerce_to(func_type.args[0].type, env)
3198                    self.type = func_type.return_type
3199                    if setting and not func_type.return_type.is_reference:
3200                        error(self.pos, "Can't set non-reference result '%s'" % self.type)
3201                elif base_type.is_cfunction:
3202                    if base_type.is_fused:
3203                        self.parse_indexed_fused_cdef(env)
3204                    else:
3205                        self.type_indices = self.parse_index_as_types(env)
3206                        if base_type.templates is None:
3207                            error(self.pos, "Can only parameterize template functions.")
3208                        elif len(base_type.templates) != len(self.type_indices):
3209                            error(self.pos, "Wrong number of template arguments: expected %s, got %s" % (
3210                                    (len(base_type.templates), len(self.type_indices))))
3211                        self.type = base_type.specialize(dict(zip(base_type.templates, self.type_indices)))
3212                else:
3213                    error(self.pos,
3214                          "Attempting to index non-array type '%s'" %
3215                          base_type)
3216                    self.type = PyrexTypes.error_type
3217
3218        self.wrap_in_nonecheck_node(env, getting)
3219        return self
3220
3221    def wrap_in_nonecheck_node(self, env, getting):
3222        if not env.directives['nonecheck'] or not self.base.may_be_none():
3223            return
3224
3225        if self.base.type.is_memoryviewslice:
3226            if self.is_memslice_copy and not getting:
3227                msg = "Cannot assign to None memoryview slice"
3228            elif self.memslice_slice:
3229                msg = "Cannot slice None memoryview slice"
3230            else:
3231                msg = "Cannot index None memoryview slice"
3232        else:
3233            msg = "'NoneType' object is not subscriptable"
3234
3235        self.base = self.base.as_none_safe_node(msg)
3236
3237    def parse_index_as_types(self, env, required=True):
3238        if isinstance(self.index, TupleNode):
3239            indices = self.index.args
3240        else:
3241            indices = [self.index]
3242        type_indices = []
3243        for index in indices:
3244            type_indices.append(index.analyse_as_type(env))
3245            if type_indices[-1] is None:
3246                if required:
3247                    error(index.pos, "not parsable as a type")
3248                return None
3249        return type_indices
3250
3251    def parse_indexed_fused_cdef(self, env):
3252        """
3253        Interpret fused_cdef_func[specific_type1, ...]
3254
3255        Note that if this method is called, we are an indexed cdef function
3256        with fused argument types, and this IndexNode will be replaced by the
3257        NameNode with specific entry just after analysis of expressions by
3258        AnalyseExpressionsTransform.
3259        """
3260        self.type = PyrexTypes.error_type
3261
3262        self.is_fused_index = True
3263
3264        base_type = self.base.type
3265        specific_types = []
3266        positions = []
3267
3268        if self.index.is_name or self.index.is_attribute:
3269            positions.append(self.index.pos)
3270        elif isinstance(self.index, TupleNode):
3271            for arg in self.index.args:
3272                positions.append(arg.pos)
3273        specific_types = self.parse_index_as_types(env, required=False)
3274
3275        if specific_types is None:
3276            self.index = self.index.analyse_types(env)
3277
3278            if not self.base.entry.as_variable:
3279                error(self.pos, "Can only index fused functions with types")
3280            else:
3281                # A cpdef function indexed with Python objects
3282                self.base.entry = self.entry = self.base.entry.as_variable
3283                self.base.type = self.type = self.entry.type
3284
3285                self.base.is_temp = True
3286                self.is_temp = True
3287
3288                self.entry.used = True
3289
3290            self.is_fused_index = False
3291            return
3292
3293        for i, type in enumerate(specific_types):
3294            specific_types[i] = type.specialize_fused(env)
3295
3296        fused_types = base_type.get_fused_types()
3297        if len(specific_types) > len(fused_types):
3298            return error(self.pos, "Too many types specified")
3299        elif len(specific_types) < len(fused_types):
3300            t = fused_types[len(specific_types)]
3301            return error(self.pos, "Not enough types specified to specialize "
3302                                   "the function, %s is still fused" % t)
3303
3304        # See if our index types form valid specializations
3305        for pos, specific_type, fused_type in zip(positions,
3306                                                  specific_types,
3307                                                  fused_types):
3308            if not Utils.any([specific_type.same_as(t)
3309                                  for t in fused_type.types]):
3310                return error(pos, "Type not in fused type")
3311
3312            if specific_type is None or specific_type.is_error:
3313                return
3314
3315        fused_to_specific = dict(zip(fused_types, specific_types))
3316        type = base_type.specialize(fused_to_specific)
3317
3318        if type.is_fused:
3319            # Only partially specific, this is invalid
3320            error(self.pos,
3321                  "Index operation makes function only partially specific")
3322        else:
3323            # Fully specific, find the signature with the specialized entry
3324            for signature in self.base.type.get_all_specialized_function_types():
3325                if type.same_as(signature):
3326                    self.type = signature
3327
3328                    if self.base.is_attribute:
3329                        # Pretend to be a normal attribute, for cdef extension
3330                        # methods
3331                        self.entry = signature.entry
3332                        self.is_attribute = True
3333                        self.obj = self.base.obj
3334
3335                    self.type.entry.used = True
3336                    self.base.type = signature
3337                    self.base.entry = signature.entry
3338
3339                    break
3340            else:
3341                # This is a bug
3342                raise InternalError("Couldn't find the right signature")
3343
3344    gil_message = "Indexing Python object"
3345
3346    def nogil_check(self, env):
3347        if self.is_buffer_access or self.memslice_index or self.memslice_slice:
3348            if not self.memslice_slice and env.directives['boundscheck']:
3349                # error(self.pos, "Cannot check buffer index bounds without gil; "
3350                #                 "use boundscheck(False) directive")
3351                warning(self.pos, "Use boundscheck(False) for faster access",
3352                        level=1)
3353            if self.type.is_pyobject:
3354                error(self.pos, "Cannot access buffer with object dtype without gil")
3355                return
3356        super(IndexNode, self).nogil_check(env)
3357
3358
3359    def check_const_addr(self):
3360        return self.base.check_const_addr() and self.index.check_const()
3361
3362    def is_lvalue(self):
3363        # NOTE: references currently have both is_reference and is_ptr
3364        # set.  Since pointers and references have different lvalue
3365        # rules, we must be careful to separate the two.
3366        if self.type.is_reference:
3367            if self.type.ref_base_type.is_array:
3368                # fixed-sized arrays aren't l-values
3369                return False
3370        elif self.type.is_ptr:
3371            # non-const pointers can always be reassigned
3372            return True
3373        elif self.type.is_array:
3374            # fixed-sized arrays aren't l-values
3375            return False
3376        # Just about everything else returned by the index operator
3377        # can be an lvalue.
3378        return True
3379
3380    def calculate_result_code(self):
3381        if self.is_buffer_access:
3382            return "(*%s)" % self.buffer_ptr_code
3383        elif self.is_memslice_copy:
3384            return self.base.result()
3385        elif self.base.type in (list_type, tuple_type, bytearray_type):
3386            if self.base.type is list_type:
3387                index_code = "PyList_GET_ITEM(%s, %s)"
3388            elif self.base.type is tuple_type:
3389                index_code = "PyTuple_GET_ITEM(%s, %s)"
3390            elif self.base.type is bytearray_type:
3391                index_code = "((unsigned char)(PyByteArray_AS_STRING(%s)[%s]))"
3392            else:
3393                assert False, "unexpected base type in indexing: %s" % self.base.type
3394        elif self.base.type.is_cfunction:
3395            return "%s<%s>" % (
3396                self.base.result(),
3397                ",".join([param.declaration_code("") for param in self.type_indices]))
3398        else:
3399            if (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
3400                error(self.pos, "Invalid use of pointer slice")
3401                return
3402            index_code = "(%s[%s])"
3403        return index_code % (self.base.result(), self.index.result())
3404
3405    def extra_index_params(self, code):
3406        if self.index.type.is_int:
3407            is_list = self.base.type is list_type
3408            wraparound = (
3409                bool(code.globalstate.directives['wraparound']) and
3410                self.original_index_type.signed and
3411                not (isinstance(self.index.constant_result, (int, long))
3412                     and self.index.constant_result >= 0))
3413            boundscheck = bool(code.globalstate.directives['boundscheck'])
3414            return ", %s, %d, %s, %d, %d, %d" % (
3415                self.original_index_type.declaration_code(""),
3416                self.original_index_type.signed and 1 or 0,
3417                self.original_index_type.to_py_function,
3418                is_list, wraparound, boundscheck)
3419        else:
3420            return ""
3421
3422    def generate_subexpr_evaluation_code(self, code):
3423        self.base.generate_evaluation_code(code)
3424        if self.type_indices is not None:
3425            pass
3426        elif self.indices is None:
3427            self.index.generate_evaluation_code(code)
3428        else:
3429            for i in self.indices:
3430                i.generate_evaluation_code(code)
3431
3432    def generate_subexpr_disposal_code(self, code):
3433        self.base.generate_disposal_code(code)
3434        if self.type_indices is not None:
3435            pass
3436        elif self.indices is None:
3437            self.index.generate_disposal_code(code)
3438        else:
3439            for i in self.indices:
3440                i.generate_disposal_code(code)
3441
3442    def free_subexpr_temps(self, code):
3443        self.base.free_temps(code)
3444        if self.indices is None:
3445            self.index.free_temps(code)
3446        else:
3447            for i in self.indices:
3448                i.free_temps(code)
3449
3450    def generate_result_code(self, code):
3451        if self.is_buffer_access or self.memslice_index:
3452            buffer_entry, self.buffer_ptr_code = self.buffer_lookup_code(code)
3453            if self.type.is_pyobject:
3454                # is_temp is True, so must pull out value and incref it.
3455                # NOTE: object temporary results for nodes are declared
3456                #       as PyObject *, so we need a cast
3457                code.putln("%s = (PyObject *) *%s;" % (self.temp_code,
3458                                                       self.buffer_ptr_code))
3459                code.putln("__Pyx_INCREF((PyObject*)%s);" % self.temp_code)
3460
3461        elif self.memslice_slice:
3462            self.put_memoryviewslice_slice_code(code)
3463
3464        elif self.is_temp:
3465            if self.type.is_pyobject:
3466                error_value = 'NULL'
3467                if self.index.type.is_int:
3468                    if self.base.type is list_type:
3469                        function = "__Pyx_GetItemInt_List"
3470                    elif self.base.type is tuple_type:
3471                        function = "__Pyx_GetItemInt_Tuple"
3472                    else:
3473                        function = "__Pyx_GetItemInt"
3474                    code.globalstate.use_utility_code(
3475                        TempitaUtilityCode.load_cached("GetItemInt", "ObjectHandling.c"))
3476                else:
3477                    if self.base.type is dict_type:
3478                        function = "__Pyx_PyDict_GetItem"
3479                        code.globalstate.use_utility_code(
3480                            UtilityCode.load_cached("DictGetItem", "ObjectHandling.c"))
3481                    else:
3482                        function = "PyObject_GetItem"
3483            elif self.type.is_unicode_char and self.base.type is unicode_type:
3484                assert self.index.type.is_int
3485                function = "__Pyx_GetItemInt_Unicode"
3486                error_value = '(Py_UCS4)-1'
3487                code.globalstate.use_utility_code(
3488                    UtilityCode.load_cached("GetItemIntUnicode", "StringTools.c"))
3489            elif self.base.type is bytearray_type:
3490                assert self.index.type.is_int
3491                assert self.type.is_int
3492                function = "__Pyx_GetItemInt_ByteArray"
3493                error_value = '-1'
3494                code.globalstate.use_utility_code(
3495                    UtilityCode.load_cached("GetItemIntByteArray", "StringTools.c"))
3496            else:
3497                assert False, "unexpected type %s and base type %s for indexing" % (
3498                    self.type, self.base.type)
3499
3500            if self.index.type.is_int:
3501                index_code = self.index.result()
3502            else:
3503                index_code = self.index.py_result()
3504
3505            code.putln(
3506                "%s = %s(%s, %s%s); if (unlikely(%s == %s)) %s;" % (
3507                    self.result(),
3508                    function,
3509                    self.base.py_result(),
3510                    index_code,
3511                    self.extra_index_params(code),
3512                    self.result(),
3513                    error_value,
3514                    code.error_goto(self.pos)))
3515            if self.type.is_pyobject:
3516                code.put_gotref(self.py_result())
3517
3518    def generate_setitem_code(self, value_code, code):
3519        if self.index.type.is_int:
3520            if self.base.type is bytearray_type:
3521                code.globalstate.use_utility_code(
3522                    UtilityCode.load_cached("SetItemIntByteArray", "StringTools.c"))
3523                function = "__Pyx_SetItemInt_ByteArray"
3524            else:
3525                code.globalstate.use_utility_code(
3526                    UtilityCode.load_cached("SetItemInt", "ObjectHandling.c"))
3527                function = "__Pyx_SetItemInt"
3528            index_code = self.index.result()
3529        else:
3530            index_code = self.index.py_result()
3531            if self.base.type is dict_type:
3532                function = "PyDict_SetItem"
3533            # It would seem that we could specialized lists/tuples, but that
3534            # shouldn't happen here.
3535            # Both PyList_SetItem() and PyTuple_SetItem() take a Py_ssize_t as
3536            # index instead of an object, and bad conversion here would give
3537            # the wrong exception. Also, tuples are supposed to be immutable,
3538            # and raise a TypeError when trying to set their entries
3539            # (PyTuple_SetItem() is for creating new tuples from scratch).
3540            else:
3541                function = "PyObject_SetItem"
3542        code.putln(
3543            "if (unlikely(%s(%s, %s, %s%s) < 0)) %s" % (
3544                function,
3545                self.base.py_result(),
3546                index_code,
3547                value_code,
3548                self.extra_index_params(code),
3549                code.error_goto(self.pos)))
3550
3551    def generate_buffer_setitem_code(self, rhs, code, op=""):
3552        # Used from generate_assignment_code and InPlaceAssignmentNode
3553        buffer_entry, ptrexpr = self.buffer_lookup_code(code)
3554
3555        if self.buffer_type.dtype.is_pyobject:
3556            # Must manage refcounts. Decref what is already there
3557            # and incref what we put in.
3558            ptr = code.funcstate.allocate_temp(buffer_entry.buf_ptr_type,
3559                                               manage_ref=False)
3560            rhs_code = rhs.result()
3561            code.putln("%s = %s;" % (ptr, ptrexpr))
3562            code.put_gotref("*%s" % ptr)
3563            code.putln("__Pyx_INCREF(%s); __Pyx_DECREF(*%s);" % (
3564                rhs_code, ptr))
3565            code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
3566            code.put_giveref("*%s" % ptr)
3567            code.funcstate.release_temp(ptr)
3568        else:
3569            # Simple case
3570            code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
3571
3572    def generate_assignment_code(self, rhs, code):
3573        generate_evaluation_code = (self.is_memslice_scalar_assignment or
3574                                    self.memslice_slice)
3575        if generate_evaluation_code:
3576            self.generate_evaluation_code(code)
3577        else:
3578            self.generate_subexpr_evaluation_code(code)
3579
3580        if self.is_buffer_access or self.memslice_index:
3581            self.generate_buffer_setitem_code(rhs, code)
3582        elif self.is_memslice_scalar_assignment:
3583            self.generate_memoryviewslice_assign_scalar_code(rhs, code)
3584        elif self.memslice_slice or self.is_memslice_copy:
3585            self.generate_memoryviewslice_setslice_code(rhs, code)
3586        elif self.type.is_pyobject:
3587            self.generate_setitem_code(rhs.py_result(), code)
3588        elif self.base.type is bytearray_type:
3589            value_code = self._check_byte_value(code, rhs)
3590            self.generate_setitem_code(value_code, code)
3591        else:
3592            code.putln(
3593                "%s = %s;" % (
3594                    self.result(), rhs.result()))
3595
3596        if generate_evaluation_code:
3597            self.generate_disposal_code(code)
3598        else:
3599            self.generate_subexpr_disposal_code(code)
3600            self.free_subexpr_temps(code)
3601
3602        rhs.generate_disposal_code(code)
3603        rhs.free_temps(code)
3604
3605    def _check_byte_value(self, code, rhs):
3606        # TODO: should we do this generally on downcasts, or just here?
3607        assert rhs.type.is_int, repr(rhs.type)
3608        value_code = rhs.result()
3609        if rhs.has_constant_result():
3610            if 0 <= rhs.constant_result < 256:
3611                return value_code
3612            needs_cast = True  # make at least the C compiler happy
3613            warning(rhs.pos,
3614                    "value outside of range(0, 256)"
3615                    " when assigning to byte: %s" % rhs.constant_result,
3616                    level=1)
3617        else:
3618            needs_cast = rhs.type != PyrexTypes.c_uchar_type
3619
3620        if not self.nogil:
3621            conditions = []
3622            if rhs.is_literal or rhs.type.signed:
3623                conditions.append('%s < 0' % value_code)
3624            if (rhs.is_literal or not
3625                    (rhs.is_temp and rhs.type in (
3626                        PyrexTypes.c_uchar_type, PyrexTypes.c_char_type,
3627                        PyrexTypes.c_schar_type))):
3628                conditions.append('%s > 255' % value_code)
3629            if conditions:
3630                code.putln("if (unlikely(%s)) {" % ' || '.join(conditions))
3631                code.putln(
3632                    'PyErr_SetString(PyExc_ValueError,'
3633                    ' "byte must be in range(0, 256)"); %s' %
3634                    code.error_goto(self.pos))
3635                code.putln("}")
3636
3637        if needs_cast:
3638            value_code = '((unsigned char)%s)' % value_code
3639        return value_code
3640
3641    def generate_deletion_code(self, code, ignore_nonexisting=False):
3642        self.generate_subexpr_evaluation_code(code)
3643        #if self.type.is_pyobject:
3644        if self.index.type.is_int:
3645            function = "__Pyx_DelItemInt"
3646            index_code = self.index.result()
3647            code.globalstate.use_utility_code(
3648                UtilityCode.load_cached("DelItemInt", "ObjectHandling.c"))
3649        else:
3650            index_code = self.index.py_result()
3651            if self.base.type is dict_type:
3652                function = "PyDict_DelItem"
3653            else:
3654                function = "PyObject_DelItem"
3655        code.putln(
3656            "if (%s(%s, %s%s) < 0) %s" % (
3657                function,
3658                self.base.py_result(),
3659                index_code,
3660                self.extra_index_params(code),
3661                code.error_goto(self.pos)))
3662        self.generate_subexpr_disposal_code(code)
3663        self.free_subexpr_temps(code)
3664
3665    def buffer_entry(self):
3666        import Buffer, MemoryView
3667
3668        base = self.base
3669        if self.base.is_nonecheck:
3670            base = base.arg
3671
3672        if base.is_name:
3673            entry = base.entry
3674        else:
3675            # SimpleCallNode is_simple is not consistent with coerce_to_simple
3676            assert base.is_simple() or base.is_temp
3677            cname = base.result()
3678            entry = Symtab.Entry(cname, cname, self.base.type, self.base.pos)
3679
3680        if entry.type.is_buffer:
3681            buffer_entry = Buffer.BufferEntry(entry)
3682        else:
3683            buffer_entry = MemoryView.MemoryViewSliceBufferEntry(entry)
3684
3685        return buffer_entry
3686
3687    def buffer_lookup_code(self, code):
3688        "ndarray[1, 2, 3] and memslice[1, 2, 3]"
3689        # Assign indices to temps
3690        index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False)
3691                           for i in self.indices]
3692
3693        for temp, index in zip(index_temps, self.indices):
3694            code.putln("%s = %s;" % (temp, index.result()))
3695
3696        # Generate buffer access code using these temps
3697        import Buffer
3698        buffer_entry = self.buffer_entry()
3699        if buffer_entry.type.is_buffer:
3700            negative_indices = buffer_entry.type.negative_indices
3701        else:
3702            negative_indices = Buffer.buffer_defaults['negative_indices']
3703
3704        return buffer_entry, Buffer.put_buffer_lookup_code(
3705               entry=buffer_entry,
3706               index_signeds=[i.type.signed for i in self.indices],
3707               index_cnames=index_temps,
3708               directives=code.globalstate.directives,
3709               pos=self.pos, code=code,
3710               negative_indices=negative_indices,
3711               in_nogil_context=self.in_nogil_context)
3712
3713    def put_memoryviewslice_slice_code(self, code):
3714        "memslice[:]"
3715        buffer_entry = self.buffer_entry()
3716        have_gil = not self.in_nogil_context
3717
3718        if sys.version_info < (3,):
3719            def next_(it):
3720                return it.next()
3721        else:
3722            next_ = next
3723
3724        have_slices = False
3725        it = iter(self.indices)
3726        for index in self.original_indices:
3727            is_slice = isinstance(index, SliceNode)
3728            have_slices = have_slices or is_slice
3729            if is_slice:
3730                if not index.start.is_none:
3731                    index.start = next_(it)
3732                if not index.stop.is_none:
3733                    index.stop = next_(it)
3734                if not index.step.is_none:
3735                    index.step = next_(it)
3736            else:
3737                next_(it)
3738
3739        assert not list(it)
3740
3741        buffer_entry.generate_buffer_slice_code(code, self.original_indices,
3742                                                self.result(),
3743                                                have_gil=have_gil,
3744                                                have_slices=have_slices,
3745                                                directives=code.globalstate.directives)
3746
3747    def generate_memoryviewslice_setslice_code(self, rhs, code):
3748        "memslice1[...] = memslice2 or memslice1[:] = memslice2"
3749        import MemoryView
3750        MemoryView.copy_broadcast_memview_src_to_dst(rhs, self, code)
3751
3752    def generate_memoryviewslice_assign_scalar_code(self, rhs, code):
3753        "memslice1[...] = 0.0 or memslice1[:] = 0.0"
3754        import MemoryView
3755        MemoryView.assign_scalar(self, rhs, code)
3756
3757
3758class SliceIndexNode(ExprNode):
3759    #  2-element slice indexing
3760    #
3761    #  base      ExprNode
3762    #  start     ExprNode or None
3763    #  stop      ExprNode or None
3764    #  slice     ExprNode or None   constant slice object
3765
3766    subexprs = ['base', 'start', 'stop', 'slice']
3767
3768    slice = None
3769
3770    def infer_type(self, env):
3771        base_type = self.base.infer_type(env)
3772        if base_type.is_string or base_type.is_cpp_class:
3773            return bytes_type
3774        elif base_type.is_pyunicode_ptr:
3775            return unicode_type
3776        elif base_type in (bytes_type, str_type, unicode_type,
3777                           basestring_type, list_type, tuple_type):
3778            return base_type
3779        elif base_type.is_ptr or base_type.is_array:
3780            return PyrexTypes.c_array_type(base_type.base_type, None)
3781        return py_object_type
3782
3783    def may_be_none(self):
3784        base_type = self.base.type
3785        if base_type:
3786            if base_type.is_string:
3787                return False
3788            if base_type in (bytes_type, str_type, unicode_type,
3789                             basestring_type, list_type, tuple_type):
3790                return False
3791        return ExprNode.may_be_none(self)
3792
3793    def calculate_constant_result(self):
3794        if self.start is None:
3795            start = None
3796        else:
3797            start = self.start.constant_result
3798        if self.stop is None:
3799            stop = None
3800        else:
3801            stop = self.stop.constant_result
3802        self.constant_result = self.base.constant_result[start:stop]
3803
3804    def compile_time_value(self, denv):
3805        base = self.base.compile_time_value(denv)
3806        if self.start is None:
3807            start = 0
3808        else:
3809            start = self.start.compile_time_value(denv)
3810        if self.stop is None:
3811            stop = None
3812        else:
3813            stop = self.stop.compile_time_value(denv)
3814        try:
3815            return base[start:stop]
3816        except Exception, e:
3817            self.compile_time_value_error(e)
3818
3819    def analyse_target_declaration(self, env):
3820        pass
3821
3822    def analyse_target_types(self, env):
3823        node = self.analyse_types(env, getting=False)
3824        # when assigning, we must accept any Python type
3825        if node.type.is_pyobject:
3826            node.type = py_object_type
3827        return node
3828
3829    def analyse_types(self, env, getting=True):
3830        self.base = self.base.analyse_types(env)
3831
3832        if self.base.type.is_memoryviewslice:
3833            none_node = NoneNode(self.pos)
3834            index = SliceNode(self.pos,
3835                              start=self.start or none_node,
3836                              stop=self.stop or none_node,
3837                              step=none_node)
3838            index_node = IndexNode(self.pos, index, base=self.base)
3839            return index_node.analyse_base_and_index_types(
3840                env, getting=getting, setting=not getting,
3841                analyse_base=False)
3842
3843        if self.start:
3844            self.start = self.start.analyse_types(env)
3845        if self.stop:
3846            self.stop = self.stop.analyse_types(env)
3847
3848        if not env.directives['wraparound']:
3849            check_negative_indices(self.start, self.stop)
3850
3851        base_type = self.base.type
3852        if base_type.is_string or base_type.is_cpp_string:
3853            self.type = default_str_type(env)
3854        elif base_type.is_pyunicode_ptr:
3855            self.type = unicode_type
3856        elif base_type.is_ptr:
3857            self.type = base_type
3858        elif base_type.is_array:
3859            # we need a ptr type here instead of an array type, as
3860            # array types can result in invalid type casts in the C
3861            # code
3862            self.type = PyrexTypes.CPtrType(base_type.base_type)
3863        else:
3864            self.base = self.base.coerce_to_pyobject(env)
3865            self.type = py_object_type
3866        if base_type.is_builtin_type:
3867            # slicing builtin types returns something of the same type
3868            self.type = base_type
3869            self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
3870
3871        if self.type is py_object_type:
3872            if (not self.start or self.start.is_literal) and \
3873                    (not self.stop or self.stop.is_literal):
3874                # cache the constant slice object, in case we need it
3875                none_node = NoneNode(self.pos)
3876                self.slice = SliceNode(
3877                    self.pos,
3878                    start=copy.deepcopy(self.start or none_node),
3879                    stop=copy.deepcopy(self.stop or none_node),
3880                    step=none_node
3881                ).analyse_types(env)
3882        else:
3883            c_int = PyrexTypes.c_py_ssize_t_type
3884            if self.start:
3885                self.start = self.start.coerce_to(c_int, env)
3886            if self.stop:
3887                self.stop = self.stop.coerce_to(c_int, env)
3888        self.is_temp = 1
3889        return self
3890
3891    nogil_check = Node.gil_error
3892    gil_message = "Slicing Python object"
3893
3894    get_slice_utility_code = TempitaUtilityCode.load(
3895        "SliceObject", "ObjectHandling.c", context={'access': 'Get'})
3896
3897    set_slice_utility_code = TempitaUtilityCode.load(
3898        "SliceObject", "ObjectHandling.c", context={'access': 'Set'})
3899
3900    def coerce_to(self, dst_type, env):
3901        if ((self.base.type.is_string or self.base.type.is_cpp_string)
3902                and dst_type in (bytes_type, bytearray_type, str_type, unicode_type)):
3903            if (dst_type not in (bytes_type, bytearray_type)
3904                    and not env.directives['c_string_encoding']):
3905                error(self.pos,
3906                    "default encoding required for conversion from '%s' to '%s'" %
3907                    (self.base.type, dst_type))
3908            self.type = dst_type
3909        return super(SliceIndexNode, self).coerce_to(dst_type, env)
3910
3911    def generate_result_code(self, code):
3912        if not self.type.is_pyobject:
3913            error(self.pos,
3914                  "Slicing is not currently supported for '%s'." % self.type)
3915            return
3916
3917        base_result = self.base.result()
3918        result = self.result()
3919        start_code = self.start_code()
3920        stop_code = self.stop_code()
3921        if self.base.type.is_string:
3922            base_result = self.base.result()
3923            if self.base.type != PyrexTypes.c_char_ptr_type:
3924                base_result = '((const char*)%s)' % base_result
3925            if self.type is bytearray_type:
3926                type_name = 'ByteArray'
3927            else:
3928                type_name = self.type.name.title()
3929            if self.stop is None:
3930                code.putln(
3931                    "%s = __Pyx_Py%s_FromString(%s + %s); %s" % (
3932                        result,
3933                        type_name,
3934                        base_result,
3935                        start_code,
3936                        code.error_goto_if_null(result, self.pos)))
3937            else:
3938                code.putln(
3939                    "%s = __Pyx_Py%s_FromStringAndSize(%s + %s, %s - %s); %s" % (
3940                        result,
3941                        type_name,
3942                        base_result,
3943                        start_code,
3944                        stop_code,
3945                        start_code,
3946                        code.error_goto_if_null(result, self.pos)))
3947        elif self.base.type.is_pyunicode_ptr:
3948            base_result = self.base.result()
3949            if self.base.type != PyrexTypes.c_py_unicode_ptr_type:
3950                base_result = '((const Py_UNICODE*)%s)' % base_result
3951            if self.stop is None:
3952                code.putln(
3953                    "%s = __Pyx_PyUnicode_FromUnicode(%s + %s); %s" % (
3954                        result,
3955                        base_result,
3956                        start_code,
3957                        code.error_goto_if_null(result, self.pos)))
3958            else:
3959                code.putln(
3960                    "%s = __Pyx_PyUnicode_FromUnicodeAndLength(%s + %s, %s - %s); %s" % (
3961                        result,
3962                        base_result,
3963                        start_code,
3964                        stop_code,
3965                        start_code,
3966                        code.error_goto_if_null(result, self.pos)))
3967
3968        elif self.base.type is unicode_type:
3969            code.globalstate.use_utility_code(
3970                          UtilityCode.load_cached("PyUnicode_Substring", "StringTools.c"))
3971            code.putln(
3972                "%s = __Pyx_PyUnicode_Substring(%s, %s, %s); %s" % (
3973                    result,
3974                    base_result,
3975                    start_code,
3976                    stop_code,
3977                    code.error_goto_if_null(result, self.pos)))
3978        elif self.type is py_object_type:
3979            code.globalstate.use_utility_code(self.get_slice_utility_code)
3980            (has_c_start, has_c_stop, c_start, c_stop,
3981             py_start, py_stop, py_slice) = self.get_slice_config()
3982            code.putln(
3983                "%s = __Pyx_PyObject_GetSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d); %s" % (
3984                    result,
3985                    self.base.py_result(),
3986                    c_start, c_stop,
3987                    py_start, py_stop, py_slice,
3988                    has_c_start, has_c_stop,
3989                    bool(code.globalstate.directives['wraparound']),
3990                    code.error_goto_if_null(result, self.pos)))
3991        else:
3992            if self.base.type is list_type:
3993                code.globalstate.use_utility_code(
3994                    TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
3995                cfunc = '__Pyx_PyList_GetSlice'
3996            elif self.base.type is tuple_type:
3997                code.globalstate.use_utility_code(
3998                    TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
3999                cfunc = '__Pyx_PyTuple_GetSlice'
4000            else:
4001                cfunc = '__Pyx_PySequence_GetSlice'
4002            code.putln(
4003                "%s = %s(%s, %s, %s); %s" % (
4004                    result,
4005                    cfunc,
4006                    self.base.py_result(),
4007                    start_code,
4008                    stop_code,
4009                    code.error_goto_if_null(result, self.pos)))
4010        code.put_gotref(self.py_result())
4011
4012    def generate_assignment_code(self, rhs, code):
4013        self.generate_subexpr_evaluation_code(code)
4014        if self.type.is_pyobject:
4015            code.globalstate.use_utility_code(self.set_slice_utility_code)
4016            (has_c_start, has_c_stop, c_start, c_stop,
4017             py_start, py_stop, py_slice) = self.get_slice_config()
4018            code.put_error_if_neg(self.pos,
4019                "__Pyx_PyObject_SetSlice(%s, %s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
4020                    self.base.py_result(),
4021                    rhs.py_result(),
4022                    c_start, c_stop,
4023                    py_start, py_stop, py_slice,
4024                    has_c_start, has_c_stop,
4025                    bool(code.globalstate.directives['wraparound'])))
4026        else:
4027            start_offset = ''
4028            if self.start:
4029                start_offset = self.start_code()
4030                if start_offset == '0':
4031                    start_offset = ''
4032                else:
4033                    start_offset += '+'
4034            if rhs.type.is_array:
4035                array_length = rhs.type.size
4036                self.generate_slice_guard_code(code, array_length)
4037            else:
4038                error(self.pos,
4039                      "Slice assignments from pointers are not yet supported.")
4040                # FIXME: fix the array size according to start/stop
4041                array_length = self.base.type.size
4042            for i in range(array_length):
4043                code.putln("%s[%s%s] = %s[%d];" % (
4044                        self.base.result(), start_offset, i,
4045                        rhs.result(), i))
4046        self.generate_subexpr_disposal_code(code)
4047        self.free_subexpr_temps(code)
4048        rhs.generate_disposal_code(code)
4049        rhs.free_temps(code)
4050
4051    def generate_deletion_code(self, code, ignore_nonexisting=False):
4052        if not self.base.type.is_pyobject:
4053            error(self.pos,
4054                  "Deleting slices is only supported for Python types, not '%s'." % self.type)
4055            return
4056        self.generate_subexpr_evaluation_code(code)
4057        code.globalstate.use_utility_code(self.set_slice_utility_code)
4058        (has_c_start, has_c_stop, c_start, c_stop,
4059         py_start, py_stop, py_slice) = self.get_slice_config()
4060        code.put_error_if_neg(self.pos,
4061            "__Pyx_PyObject_DelSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
4062                self.base.py_result(),
4063                c_start, c_stop,
4064                py_start, py_stop, py_slice,
4065                has_c_start, has_c_stop,
4066                bool(code.globalstate.directives['wraparound'])))
4067        self.generate_subexpr_disposal_code(code)
4068        self.free_subexpr_temps(code)
4069
4070    def get_slice_config(self):
4071        has_c_start, c_start, py_start = False, '0', 'NULL'
4072        if self.start:
4073            has_c_start = not self.start.type.is_pyobject
4074            if has_c_start:
4075                c_start = self.start.result()
4076            else:
4077                py_start = '&%s' % self.start.py_result()
4078        has_c_stop, c_stop, py_stop = False, '0', 'NULL'
4079        if self.stop:
4080            has_c_stop = not self.stop.type.is_pyobject
4081            if has_c_stop:
4082                c_stop = self.stop.result()
4083            else:
4084                py_stop = '&%s' % self.stop.py_result()
4085        py_slice = self.slice and '&%s' % self.slice.py_result() or 'NULL'
4086        return (has_c_start, has_c_stop, c_start, c_stop,
4087                py_start, py_stop, py_slice)
4088
4089    def generate_slice_guard_code(self, code, target_size):
4090        if not self.base.type.is_array:
4091            return
4092        slice_size = self.base.type.size
4093        start = stop = None
4094        if self.stop:
4095            stop = self.stop.result()
4096            try:
4097                stop = int(stop)
4098                if stop < 0:
4099                    slice_size = self.base.type.size + stop
4100                else:
4101                    slice_size = stop
4102                stop = None
4103            except ValueError:
4104                pass
4105        if self.start:
4106            start = self.start.result()
4107            try:
4108                start = int(start)
4109                if start < 0:
4110                    start = self.base.type.size + start
4111                slice_size -= start
4112                start = None
4113            except ValueError:
4114                pass
4115        check = None
4116        if slice_size < 0:
4117            if target_size > 0:
4118                error(self.pos, "Assignment to empty slice.")
4119        elif start is None and stop is None:
4120            # we know the exact slice length
4121            if target_size != slice_size:
4122                error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
4123                        slice_size, target_size))
4124        elif start is not None:
4125            if stop is None:
4126                stop = slice_size
4127            check = "(%s)-(%s)" % (stop, start)
4128        else: # stop is not None:
4129            check = stop
4130        if check:
4131            code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
4132            code.putln('PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length, expected %%" CYTHON_FORMAT_SSIZE_T "d, got %%" CYTHON_FORMAT_SSIZE_T "d", (Py_ssize_t)%d, (Py_ssize_t)(%s));' % (
4133                        target_size, check))
4134            code.putln(code.error_goto(self.pos))
4135            code.putln("}")
4136
4137    def start_code(self):
4138        if self.start:
4139            return self.start.result()
4140        else:
4141            return "0"
4142
4143    def stop_code(self):
4144        if self.stop:
4145            return self.stop.result()
4146        elif self.base.type.is_array:
4147            return self.base.type.size
4148        else:
4149            return "PY_SSIZE_T_MAX"
4150
4151    def calculate_result_code(self):
4152        # self.result() is not used, but this method must exist
4153        return "<unused>"
4154
4155
4156class SliceNode(ExprNode):
4157    #  start:stop:step in subscript list
4158    #
4159    #  start     ExprNode
4160    #  stop      ExprNode
4161    #  step      ExprNode
4162
4163    subexprs = ['start', 'stop', 'step']
4164
4165    type = slice_type
4166    is_temp = 1
4167
4168    def calculate_constant_result(self):
4169        self.constant_result = slice(
4170            self.start.constant_result,
4171            self.stop.constant_result,
4172            self.step.constant_result)
4173
4174    def compile_time_value(self, denv):
4175        start = self.start.compile_time_value(denv)
4176        stop = self.stop.compile_time_value(denv)
4177        step = self.step.compile_time_value(denv)
4178        try:
4179            return slice(start, stop, step)
4180        except Exception, e:
4181            self.compile_time_value_error(e)
4182
4183    def may_be_none(self):
4184        return False
4185
4186    def analyse_types(self, env):
4187        start = self.start.analyse_types(env)
4188        stop = self.stop.analyse_types(env)
4189        step = self.step.analyse_types(env)
4190        self.start = start.coerce_to_pyobject(env)
4191        self.stop = stop.coerce_to_pyobject(env)
4192        self.step = step.coerce_to_pyobject(env)
4193        if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
4194            self.is_literal = True
4195            self.is_temp = False
4196        return self
4197
4198    gil_message = "Constructing Python slice object"
4199
4200    def calculate_result_code(self):
4201        return self.result_code
4202
4203    def generate_result_code(self, code):
4204        if self.is_literal:
4205            self.result_code = code.get_py_const(py_object_type, 'slice', cleanup_level=2)
4206            code = code.get_cached_constants_writer()
4207            code.mark_pos(self.pos)
4208
4209        code.putln(
4210            "%s = PySlice_New(%s, %s, %s); %s" % (
4211                self.result(),
4212                self.start.py_result(),
4213                self.stop.py_result(),
4214                self.step.py_result(),
4215                code.error_goto_if_null(self.result(), self.pos)))
4216        code.put_gotref(self.py_result())
4217        if self.is_literal:
4218            code.put_giveref(self.py_result())
4219
4220    def __deepcopy__(self, memo):
4221        """
4222        There is a copy bug in python 2.4 for slice objects.
4223        """
4224        return SliceNode(
4225            self.pos,
4226            start=copy.deepcopy(self.start, memo),
4227            stop=copy.deepcopy(self.stop, memo),
4228            step=copy.deepcopy(self.step, memo),
4229            is_temp=self.is_temp,
4230            is_literal=self.is_literal,
4231            constant_result=self.constant_result)
4232
4233
4234class CallNode(ExprNode):
4235
4236    # allow overriding the default 'may_be_none' behaviour
4237    may_return_none = None
4238
4239    def infer_type(self, env):
4240        function = self.function
4241        func_type = function.infer_type(env)
4242        if isinstance(function, NewExprNode):
4243            # note: needs call to infer_type() above
4244            return PyrexTypes.CPtrType(function.class_type)
4245        if func_type is py_object_type:
4246            # function might have lied for safety => try to find better type
4247            entry = getattr(function, 'entry', None)
4248            if entry is not None:
4249                func_type = entry.type or func_type
4250        if func_type.is_ptr:
4251            func_type = func_type.base_type
4252        if func_type.is_cfunction:
4253            return func_type.return_type
4254        elif func_type is type_type:
4255            if function.is_name and function.entry and function.entry.type:
4256                result_type = function.entry.type
4257                if result_type.is_extension_type:
4258                    return result_type
4259                elif result_type.is_builtin_type:
4260                    if function.entry.name == 'float':
4261                        return PyrexTypes.c_double_type
4262                    elif function.entry.name in Builtin.types_that_construct_their_instance:
4263                        return result_type
4264        return py_object_type
4265
4266    def type_dependencies(self, env):
4267        # TODO: Update when Danilo's C++ code merged in to handle the
4268        # the case of function overloading.
4269        return self.function.type_dependencies(env)
4270
4271    def is_simple(self):
4272        # C function calls could be considered simple, but they may
4273        # have side-effects that may hit when multiple operations must
4274        # be effected in order, e.g. when constructing the argument
4275        # sequence for a function call or comparing values.
4276        return False
4277
4278    def may_be_none(self):
4279        if self.may_return_none is not None:
4280            return self.may_return_none
4281        func_type = self.function.type
4282        if func_type is type_type and self.function.is_name:
4283            entry = self.function.entry
4284            if entry.type.is_extension_type:
4285                return False
4286            if (entry.type.is_builtin_type and
4287                    entry.name in Builtin.types_that_construct_their_instance):
4288                return False
4289        return ExprNode.may_be_none(self)
4290
4291    def analyse_as_type_constructor(self, env):
4292        type = self.function.analyse_as_type(env)
4293        if type and type.is_struct_or_union:
4294            args, kwds = self.explicit_args_kwds()
4295            items = []
4296            for arg, member in zip(args, type.scope.var_entries):
4297                items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
4298            if kwds:
4299                items += kwds.key_value_pairs
4300            self.key_value_pairs = items
4301            self.__class__ = DictNode
4302            self.analyse_types(env)    # FIXME
4303            self.coerce_to(type, env)
4304            return True
4305        elif type and type.is_cpp_class:
4306            self.args = [ arg.analyse_types(env) for arg in self.args ]
4307            constructor = type.scope.lookup("<init>")
4308            self.function = RawCNameExprNode(self.function.pos, constructor.type)
4309            self.function.entry = constructor
4310            self.function.set_cname(type.declaration_code(""))
4311            self.analyse_c_function_call(env)
4312            self.type = type
4313            return True
4314
4315    def is_lvalue(self):
4316        return self.type.is_reference
4317
4318    def nogil_check(self, env):
4319        func_type = self.function_type()
4320        if func_type.is_pyobject:
4321            self.gil_error()
4322        elif not getattr(func_type, 'nogil', False):
4323            self.gil_error()
4324
4325    gil_message = "Calling gil-requiring function"
4326
4327
4328class SimpleCallNode(CallNode):
4329    #  Function call without keyword, * or ** args.
4330    #
4331    #  function       ExprNode
4332    #  args           [ExprNode]
4333    #  arg_tuple      ExprNode or None     used internally
4334    #  self           ExprNode or None     used internally
4335    #  coerced_self   ExprNode or None     used internally
4336    #  wrapper_call   bool                 used internally
4337    #  has_optional_args   bool            used internally
4338    #  nogil          bool                 used internally
4339
4340    subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
4341
4342    self = None
4343    coerced_self = None
4344    arg_tuple = None
4345    wrapper_call = False
4346    has_optional_args = False
4347    nogil = False
4348    analysed = False
4349
4350    def compile_time_value(self, denv):
4351        function = self.function.compile_time_value(denv)
4352        args = [arg.compile_time_value(denv) for arg in self.args]
4353        try:
4354            return function(*args)
4355        except Exception, e:
4356            self.compile_time_value_error(e)
4357
4358    def analyse_as_type(self, env):
4359        attr = self.function.as_cython_attribute()
4360        if attr == 'pointer':
4361            if len(self.args) != 1:
4362                error(self.args.pos, "only one type allowed.")
4363            else:
4364                type = self.args[0].analyse_as_type(env)
4365                if not type:
4366                    error(self.args[0].pos, "Unknown type")
4367                else:
4368                    return PyrexTypes.CPtrType(type)
4369
4370    def explicit_args_kwds(self):
4371        return self.args, None
4372
4373    def analyse_types(self, env):
4374        if self.analyse_as_type_constructor(env):
4375            return self
4376        if self.analysed:
4377            return self
4378        self.analysed = True
4379        self.function.is_called = 1
4380        self.function = self.function.analyse_types(env)
4381        function = self.function
4382
4383        if function.is_attribute and function.entry and function.entry.is_cmethod:
4384            # Take ownership of the object from which the attribute
4385            # was obtained, because we need to pass it as 'self'.
4386            self.self = function.obj
4387            function.obj = CloneNode(self.self)
4388
4389        func_type = self.function_type()
4390        if func_type.is_pyobject:
4391            self.arg_tuple = TupleNode(self.pos, args = self.args)
4392            self.arg_tuple = self.arg_tuple.analyse_types(env)
4393            self.args = None
4394            if func_type is Builtin.type_type and function.is_name and \
4395                   function.entry and \
4396                   function.entry.is_builtin and \
4397                   function.entry.name in Builtin.types_that_construct_their_instance:
4398                # calling a builtin type that returns a specific object type
4399                if function.entry.name == 'float':
4400                    # the following will come true later on in a transform
4401                    self.type = PyrexTypes.c_double_type
4402                    self.result_ctype = PyrexTypes.c_double_type
4403                else:
4404                    self.type = Builtin.builtin_types[function.entry.name]
4405                    self.result_ctype = py_object_type
4406                self.may_return_none = False
4407            elif function.is_name and function.type_entry:
4408                # We are calling an extension type constructor.  As
4409                # long as we do not support __new__(), the result type
4410                # is clear
4411                self.type = function.type_entry.type
4412                self.result_ctype = py_object_type
4413                self.may_return_none = False
4414            else:
4415                self.type = py_object_type
4416            self.is_temp = 1
4417        else:
4418            self.args = [ arg.analyse_types(env) for arg in self.args ]
4419            self.analyse_c_function_call(env)
4420        return self
4421
4422    def function_type(self):
4423        # Return the type of the function being called, coercing a function
4424        # pointer to a function if necessary. If the function has fused
4425        # arguments, return the specific type.
4426        func_type = self.function.type
4427
4428        if func_type.is_ptr:
4429            func_type = func_type.base_type
4430
4431        return func_type
4432
4433    def analyse_c_function_call(self, env):
4434        if self.function.type is error_type:
4435            self.type = error_type
4436            return
4437
4438        if self.self:
4439            args = [self.self] + self.args
4440        else:
4441            args = self.args
4442
4443        if self.function.type.is_cpp_class:
4444            overloaded_entry = self.function.type.scope.lookup("operator()")
4445            if overloaded_entry is None:
4446                self.type = PyrexTypes.error_type
4447                self.result_code = "<error>"
4448                return
4449        elif hasattr(self.function, 'entry'):
4450            overloaded_entry = self.function.entry
4451        elif (isinstance(self.function, IndexNode) and
4452              self.function.is_fused_index):
4453            overloaded_entry = self.function.type.entry
4454        else:
4455            overloaded_entry = None
4456
4457        if overloaded_entry:
4458            if self.function.type.is_fused:
4459                functypes = self.function.type.get_all_specialized_function_types()
4460                alternatives = [f.entry for f in functypes]
4461            else:
4462                alternatives = overloaded_entry.all_alternatives()
4463
4464            entry = PyrexTypes.best_match(args, alternatives, self.pos, env)
4465
4466            if not entry:
4467                self.type = PyrexTypes.error_type
4468                self.result_code = "<error>"
4469                return
4470
4471            entry.used = True
4472            self.function.entry = entry
4473            self.function.type = entry.type
4474            func_type = self.function_type()
4475        else:
4476            entry = None
4477            func_type = self.function_type()
4478            if not func_type.is_cfunction:
4479                error(self.pos, "Calling non-function type '%s'" % func_type)
4480                self.type = PyrexTypes.error_type
4481                self.result_code = "<error>"
4482                return
4483
4484        # Check no. of args
4485        max_nargs = len(func_type.args)
4486        expected_nargs = max_nargs - func_type.optional_arg_count
4487        actual_nargs = len(args)
4488        if func_type.optional_arg_count and expected_nargs != actual_nargs:
4489            self.has_optional_args = 1
4490            self.is_temp = 1
4491
4492        # check 'self' argument
4493        if entry and entry.is_cmethod and func_type.args:
4494            formal_arg = func_type.args[0]
4495            arg = args[0]
4496            if formal_arg.not_none:
4497                if self.self:
4498                    self.self = self.self.as_none_safe_node(
4499                        "'NoneType' object has no attribute '%s'",
4500                        error='PyExc_AttributeError',
4501                        format_args=[entry.name])
4502                else:
4503                    # unbound method
4504                    arg = arg.as_none_safe_node(
4505                        "descriptor '%s' requires a '%s' object but received a 'NoneType'",
4506                        format_args=[entry.name, formal_arg.type.name])
4507            if self.self:
4508                if formal_arg.accept_builtin_subtypes:
4509                    arg = CMethodSelfCloneNode(self.self)
4510                else:
4511                    arg = CloneNode(self.self)
4512                arg = self.coerced_self = arg.coerce_to(formal_arg.type, env)
4513            elif formal_arg.type.is_builtin_type:
4514                # special case: unbound methods of builtins accept subtypes
4515                arg = arg.coerce_to(formal_arg.type, env)
4516                if arg.type.is_builtin_type and isinstance(arg, PyTypeTestNode):
4517                    arg.exact_builtin_type = False
4518            args[0] = arg
4519
4520        # Coerce arguments
4521        some_args_in_temps = False
4522        for i in xrange(min(max_nargs, actual_nargs)):
4523            formal_arg = func_type.args[i]
4524            formal_type = formal_arg.type
4525            arg = args[i].coerce_to(formal_type, env)
4526            if formal_arg.not_none:
4527                # C methods must do the None checks at *call* time
4528                arg = arg.as_none_safe_node(
4529                    "cannot pass None into a C function argument that is declared 'not None'")
4530            if arg.is_temp:
4531                if i > 0:
4532                    # first argument in temp doesn't impact subsequent arguments
4533                    some_args_in_temps = True
4534            elif arg.type.is_pyobject and not env.nogil:
4535                if i == 0 and self.self is not None:
4536                    # a method's cloned "self" argument is ok
4537                    pass
4538                elif arg.nonlocally_immutable():
4539                    # plain local variables are ok
4540                    pass
4541                else:
4542                    # we do not safely own the argument's reference,
4543                    # but we must make sure it cannot be collected
4544                    # before we return from the function, so we create
4545                    # an owned temp reference to it
4546                    if i > 0: # first argument doesn't matter
4547                        some_args_in_temps = True
4548                    arg = arg.coerce_to_temp(env)
4549            args[i] = arg
4550
4551        # handle additional varargs parameters
4552        for i in xrange(max_nargs, actual_nargs):
4553            arg = args[i]
4554            if arg.type.is_pyobject:
4555                arg_ctype = arg.type.default_coerced_ctype()
4556                if arg_ctype is None:
4557                    error(self.args[i].pos,
4558                          "Python object cannot be passed as a varargs parameter")
4559                else:
4560                    args[i] = arg = arg.coerce_to(arg_ctype, env)
4561            if arg.is_temp and i > 0:
4562                some_args_in_temps = True
4563
4564        if some_args_in_temps:
4565            # if some args are temps and others are not, they may get
4566            # constructed in the wrong order (temps first) => make
4567            # sure they are either all temps or all not temps (except
4568            # for the last argument, which is evaluated last in any
4569            # case)
4570            for i in xrange(actual_nargs-1):
4571                if i == 0 and self.self is not None:
4572                    continue # self is ok
4573                arg = args[i]
4574                if arg.nonlocally_immutable():
4575                    # locals, C functions, unassignable types are safe.
4576                    pass
4577                elif arg.type.is_cpp_class:
4578                    # Assignment has side effects, avoid.
4579                    pass
4580                elif env.nogil and arg.type.is_pyobject:
4581                    # can't copy a Python reference into a temp in nogil
4582                    # env (this is safe: a construction would fail in
4583                    # nogil anyway)
4584                    pass
4585                else:
4586                    #self.args[i] = arg.coerce_to_temp(env)
4587                    # instead: issue a warning
4588                    if i > 0 or i == 1 and self.self is not None: # skip first arg
4589                        warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
4590                        break
4591
4592        self.args[:] = args
4593
4594        # Calc result type and code fragment
4595        if isinstance(self.function, NewExprNode):
4596            self.type = PyrexTypes.CPtrType(self.function.class_type)
4597        else:
4598            self.type = func_type.return_type
4599
4600        if self.function.is_name or self.function.is_attribute:
4601            if self.function.entry and self.function.entry.utility_code:
4602                self.is_temp = 1 # currently doesn't work for self.calculate_result_code()
4603
4604        if self.type.is_pyobject:
4605            self.result_ctype = py_object_type
4606            self.is_temp = 1
4607        elif func_type.exception_value is not None \
4608                 or func_type.exception_check:
4609            self.is_temp = 1
4610        elif self.type.is_memoryviewslice:
4611            self.is_temp = 1
4612            # func_type.exception_check = True
4613
4614        # Called in 'nogil' context?
4615        self.nogil = env.nogil
4616        if (self.nogil and
4617            func_type.exception_check and
4618            func_type.exception_check != '+'):
4619            env.use_utility_code(pyerr_occurred_withgil_utility_code)
4620        # C++ exception handler
4621        if func_type.exception_check == '+':
4622            if func_type.exception_value is None:
4623                env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
4624
4625    def calculate_result_code(self):
4626        return self.c_call_code()
4627
4628    def c_call_code(self):
4629        func_type = self.function_type()
4630        if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
4631            return "<error>"
4632        formal_args = func_type.args
4633        arg_list_code = []
4634        args = list(zip(formal_args, self.args))
4635        max_nargs = len(func_type.args)
4636        expected_nargs = max_nargs - func_type.optional_arg_count
4637        actual_nargs = len(self.args)
4638        for formal_arg, actual_arg in args[:expected_nargs]:
4639                arg_code = actual_arg.result_as(formal_arg.type)
4640                arg_list_code.append(arg_code)
4641
4642        if func_type.is_overridable:
4643            arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
4644
4645        if func_type.optional_arg_count:
4646            if expected_nargs == actual_nargs:
4647                optional_args = 'NULL'
4648            else:
4649                optional_args = "&%s" % self.opt_arg_struct
4650            arg_list_code.append(optional_args)
4651
4652        for actual_arg in self.args[len(formal_args):]:
4653            arg_list_code.append(actual_arg.result())
4654
4655        result = "%s(%s)" % (self.function.result(), ', '.join(arg_list_code))
4656        return result
4657
4658    def generate_result_code(self, code):
4659        func_type = self.function_type()
4660        if self.function.is_name or self.function.is_attribute:
4661            if self.function.entry and self.function.entry.utility_code:
4662                code.globalstate.use_utility_code(self.function.entry.utility_code)
4663        if func_type.is_pyobject:
4664            arg_code = self.arg_tuple.py_result()
4665            code.globalstate.use_utility_code(UtilityCode.load_cached(
4666                "PyObjectCall", "ObjectHandling.c"))
4667            code.putln(
4668                "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
4669                    self.result(),
4670                    self.function.py_result(),
4671                    arg_code,
4672                    code.error_goto_if_null(self.result(), self.pos)))
4673            code.put_gotref(self.py_result())
4674        elif func_type.is_cfunction:
4675            if self.has_optional_args:
4676                actual_nargs = len(self.args)
4677                expected_nargs = len(func_type.args) - func_type.optional_arg_count
4678                self.opt_arg_struct = code.funcstate.allocate_temp(
4679                    func_type.op_arg_struct.base_type, manage_ref=True)
4680                code.putln("%s.%s = %s;" % (
4681                        self.opt_arg_struct,
4682                        Naming.pyrex_prefix + "n",
4683                        len(self.args) - expected_nargs))
4684                args = list(zip(func_type.args, self.args))
4685                for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
4686                    code.putln("%s.%s = %s;" % (
4687                            self.opt_arg_struct,
4688                            func_type.opt_arg_cname(formal_arg.name),
4689                            actual_arg.result_as(formal_arg.type)))
4690            exc_checks = []
4691            if self.type.is_pyobject and self.is_temp:
4692                exc_checks.append("!%s" % self.result())
4693            elif self.type.is_memoryviewslice:
4694                assert self.is_temp
4695                exc_checks.append(self.type.error_condition(self.result()))
4696            else:
4697                exc_val = func_type.exception_value
4698                exc_check = func_type.exception_check
4699                if exc_val is not None:
4700                    exc_checks.append("%s == %s" % (self.result(), exc_val))
4701                if exc_check:
4702                    if self.nogil:
4703                        exc_checks.append("__Pyx_ErrOccurredWithGIL()")
4704                    else:
4705                        exc_checks.append("PyErr_Occurred()")
4706            if self.is_temp or exc_checks:
4707                rhs = self.c_call_code()
4708                if self.result():
4709                    lhs = "%s = " % self.result()
4710                    if self.is_temp and self.type.is_pyobject:
4711                        #return_type = self.type # func_type.return_type
4712                        #print "SimpleCallNode.generate_result_code: casting", rhs, \
4713                        #    "from", return_type, "to pyobject" ###
4714                        rhs = typecast(py_object_type, self.type, rhs)
4715                else:
4716                    lhs = ""
4717                if func_type.exception_check == '+':
4718                    if func_type.exception_value is None:
4719                        raise_py_exception = "__Pyx_CppExn2PyErr();"
4720                    elif func_type.exception_value.type.is_pyobject:
4721                        raise_py_exception = 'try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
4722                            func_type.exception_value.entry.cname,
4723                            func_type.exception_value.entry.cname)
4724                    else:
4725                        raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.");' % func_type.exception_value.entry.cname
4726                    code.putln("try {")
4727                    code.putln("%s%s;" % (lhs, rhs))
4728                    code.putln("} catch(...) {")
4729                    if self.nogil:
4730                        code.put_ensure_gil(declare_gilstate=True)
4731                    code.putln(raise_py_exception)
4732                    if self.nogil:
4733                        code.put_release_ensured_gil()
4734                    code.putln(code.error_goto(self.pos))
4735                    code.putln("}")
4736                else:
4737                    if exc_checks:
4738                        goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
4739                    else:
4740                        goto_error = ""
4741                    code.putln("%s%s; %s" % (lhs, rhs, goto_error))
4742                if self.type.is_pyobject and self.result():
4743                    code.put_gotref(self.py_result())
4744            if self.has_optional_args:
4745                code.funcstate.release_temp(self.opt_arg_struct)
4746
4747
4748class InlinedDefNodeCallNode(CallNode):
4749    #  Inline call to defnode
4750    #
4751    #  function       PyCFunctionNode
4752    #  function_name  NameNode
4753    #  args           [ExprNode]
4754
4755    subexprs = ['args', 'function_name']
4756    is_temp = 1
4757    type = py_object_type
4758    function = None
4759    function_name = None
4760
4761    def can_be_inlined(self):
4762        func_type= self.function.def_node
4763        if func_type.star_arg or func_type.starstar_arg:
4764            return False
4765        if len(func_type.args) != len(self.args):
4766            return False
4767        return True
4768
4769    def analyse_types(self, env):
4770        self.function_name = self.function_name.analyse_types(env)
4771
4772        self.args = [ arg.analyse_types(env) for arg in self.args ]
4773        func_type = self.function.def_node
4774        actual_nargs = len(self.args)
4775
4776        # Coerce arguments
4777        some_args_in_temps = False
4778        for i in xrange(actual_nargs):
4779            formal_type = func_type.args[i].type
4780            arg = self.args[i].coerce_to(formal_type, env)
4781            if arg.is_temp:
4782                if i > 0:
4783                    # first argument in temp doesn't impact subsequent arguments
4784                    some_args_in_temps = True
4785            elif arg.type.is_pyobject and not env.nogil:
4786                if arg.nonlocally_immutable():
4787                    # plain local variables are ok
4788                    pass
4789                else:
4790                    # we do not safely own the argument's reference,
4791                    # but we must make sure it cannot be collected
4792                    # before we return from the function, so we create
4793                    # an owned temp reference to it
4794                    if i > 0: # first argument doesn't matter
4795                        some_args_in_temps = True
4796                    arg = arg.coerce_to_temp(env)
4797            self.args[i] = arg
4798
4799        if some_args_in_temps:
4800            # if some args are temps and others are not, they may get
4801            # constructed in the wrong order (temps first) => make
4802            # sure they are either all temps or all not temps (except
4803            # for the last argument, which is evaluated last in any
4804            # case)
4805            for i in xrange(actual_nargs-1):
4806                arg = self.args[i]
4807                if arg.nonlocally_immutable():
4808                    # locals, C functions, unassignable types are safe.
4809                    pass
4810                elif arg.type.is_cpp_class:
4811                    # Assignment has side effects, avoid.
4812                    pass
4813                elif env.nogil and arg.type.is_pyobject:
4814                    # can't copy a Python reference into a temp in nogil
4815                    # env (this is safe: a construction would fail in
4816                    # nogil anyway)
4817                    pass
4818                else:
4819                    #self.args[i] = arg.coerce_to_temp(env)
4820                    # instead: issue a warning
4821                    if i > 0:
4822                        warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
4823                        break
4824        return self
4825
4826    def generate_result_code(self, code):
4827        arg_code = [self.function_name.py_result()]
4828        func_type = self.function.def_node
4829        for arg, proto_arg in zip(self.args, func_type.args):
4830            if arg.type.is_pyobject:
4831                arg_code.append(arg.result_as(proto_arg.type))
4832            else:
4833                arg_code.append(arg.result())
4834        arg_code = ', '.join(arg_code)
4835        code.putln(
4836            "%s = %s(%s); %s" % (
4837                self.result(),
4838                self.function.def_node.entry.pyfunc_cname,
4839                arg_code,
4840                code.error_goto_if_null(self.result(), self.pos)))
4841        code.put_gotref(self.py_result())
4842
4843
4844class PythonCapiFunctionNode(ExprNode):
4845    subexprs = []
4846
4847    def __init__(self, pos, py_name, cname, func_type, utility_code = None):
4848        ExprNode.__init__(self, pos, name=py_name, cname=cname,
4849                          type=func_type, utility_code=utility_code)
4850
4851    def analyse_types(self, env):
4852        return self
4853
4854    def generate_result_code(self, code):
4855        if self.utility_code:
4856            code.globalstate.use_utility_code(self.utility_code)
4857
4858    def calculate_result_code(self):
4859        return self.cname
4860
4861
4862class PythonCapiCallNode(SimpleCallNode):
4863    # Python C-API Function call (only created in transforms)
4864
4865    # By default, we assume that the call never returns None, as this
4866    # is true for most C-API functions in CPython.  If this does not
4867    # apply to a call, set the following to True (or None to inherit
4868    # the default behaviour).
4869    may_return_none = False
4870
4871    def __init__(self, pos, function_name, func_type,
4872                 utility_code = None, py_name=None, **kwargs):
4873        self.type = func_type.return_type
4874        self.result_ctype = self.type
4875        self.function = PythonCapiFunctionNode(
4876            pos, py_name, function_name, func_type,
4877            utility_code = utility_code)
4878        # call this last so that we can override the constructed
4879        # attributes above with explicit keyword arguments if required
4880        SimpleCallNode.__init__(self, pos, **kwargs)
4881
4882
4883class GeneralCallNode(CallNode):
4884    #  General Python function call, including keyword,
4885    #  * and ** arguments.
4886    #
4887    #  function         ExprNode
4888    #  positional_args  ExprNode          Tuple of positional arguments
4889    #  keyword_args     ExprNode or None  Dict of keyword arguments
4890
4891    type = py_object_type
4892
4893    subexprs = ['function', 'positional_args', 'keyword_args']
4894
4895    nogil_check = Node.gil_error
4896
4897    def compile_time_value(self, denv):
4898        function = self.function.compile_time_value(denv)
4899        positional_args = self.positional_args.compile_time_value(denv)
4900        keyword_args = self.keyword_args.compile_time_value(denv)
4901        try:
4902            return function(*positional_args, **keyword_args)
4903        except Exception, e:
4904            self.compile_time_value_error(e)
4905
4906    def explicit_args_kwds(self):
4907        if (self.keyword_args and not isinstance(self.keyword_args, DictNode) or
4908            not isinstance(self.positional_args, TupleNode)):
4909            raise CompileError(self.pos,
4910                'Compile-time keyword arguments must be explicit.')
4911        return self.positional_args.args, self.keyword_args
4912
4913    def analyse_types(self, env):
4914        if self.analyse_as_type_constructor(env):
4915            return self
4916        self.function = self.function.analyse_types(env)
4917        if not self.function.type.is_pyobject:
4918            if self.function.type.is_error:
4919                self.type = error_type
4920                return self
4921            if hasattr(self.function, 'entry'):
4922                node = self.map_to_simple_call_node()
4923                if node is not None and node is not self:
4924                    return node.analyse_types(env)
4925                elif self.function.entry.as_variable:
4926                    self.function = self.function.coerce_to_pyobject(env)
4927                elif node is self:
4928                    error(self.pos,
4929                          "Non-trivial keyword arguments and starred "
4930                          "arguments not allowed in cdef functions.")
4931                else:
4932                    # error was already reported
4933                    pass
4934            else:
4935                self.function = self.function.coerce_to_pyobject(env)
4936        if self.keyword_args:
4937            self.keyword_args = self.keyword_args.analyse_types(env)
4938        self.positional_args = self.positional_args.analyse_types(env)
4939        self.positional_args = \
4940            self.positional_args.coerce_to_pyobject(env)
4941        function = self.function
4942        if function.is_name and function.type_entry:
4943            # We are calling an extension type constructor.  As long
4944            # as we do not support __new__(), the result type is clear
4945            self.type = function.type_entry.type
4946            self.result_ctype = py_object_type
4947            self.may_return_none = False
4948        else:
4949            self.type = py_object_type
4950        self.is_temp = 1
4951        return self
4952
4953    def map_to_simple_call_node(self):
4954        """
4955        Tries to map keyword arguments to declared positional arguments.
4956        Returns self to try a Python call, None to report an error
4957        or a SimpleCallNode if the mapping succeeds.
4958        """
4959        if not isinstance(self.positional_args, TupleNode):
4960            # has starred argument
4961            return self
4962        if not isinstance(self.keyword_args, DictNode):
4963            # keywords come from arbitrary expression => nothing to do here
4964            return self
4965        function = self.function
4966        entry = getattr(function, 'entry', None)
4967        if not entry:
4968            return self
4969        function_type = entry.type
4970        if function_type.is_ptr:
4971            function_type = function_type.base_type
4972        if not function_type.is_cfunction:
4973            return self
4974
4975        pos_args = self.positional_args.args
4976        kwargs = self.keyword_args
4977        declared_args = function_type.args
4978        if entry.is_cmethod:
4979            declared_args = declared_args[1:] # skip 'self'
4980
4981        if len(pos_args) > len(declared_args):
4982            error(self.pos, "function call got too many positional arguments, "
4983                            "expected %d, got %s" % (len(declared_args),
4984                                                     len(pos_args)))
4985            return None
4986
4987        matched_args = set([ arg.name for arg in declared_args[:len(pos_args)]
4988                             if arg.name ])
4989        unmatched_args = declared_args[len(pos_args):]
4990        matched_kwargs_count = 0
4991        args = list(pos_args)
4992
4993        # check for duplicate keywords
4994        seen = set(matched_args)
4995        has_errors = False
4996        for arg in kwargs.key_value_pairs:
4997            name = arg.key.value
4998            if name in seen:
4999                error(arg.pos, "argument '%s' passed twice" % name)
5000                has_errors = True
5001                # continue to report more errors if there are any
5002            seen.add(name)
5003
5004        # match keywords that are passed in order
5005        for decl_arg, arg in zip(unmatched_args, kwargs.key_value_pairs):
5006            name = arg.key.value
5007            if decl_arg.name == name:
5008                matched_args.add(name)
5009                matched_kwargs_count += 1
5010                args.append(arg.value)
5011            else:
5012                break
5013
5014        # match keyword arguments that are passed out-of-order, but keep
5015        # the evaluation of non-simple arguments in order by moving them
5016        # into temps
5017        from Cython.Compiler.UtilNodes import EvalWithTempExprNode, LetRefNode
5018        temps = []
5019        if len(kwargs.key_value_pairs) > matched_kwargs_count:
5020            unmatched_args = declared_args[len(args):]
5021            keywords = dict([ (arg.key.value, (i+len(pos_args), arg))
5022                              for i, arg in enumerate(kwargs.key_value_pairs) ])
5023            first_missing_keyword = None
5024            for decl_arg in unmatched_args:
5025                name = decl_arg.name
5026                if name not in keywords:
5027                    # missing keyword argument => either done or error
5028                    if not first_missing_keyword:
5029                        first_missing_keyword = name
5030                    continue
5031                elif first_missing_keyword:
5032                    if entry.as_variable:
5033                        # we might be able to convert the function to a Python
5034                        # object, which then allows full calling semantics
5035                        # with default values in gaps - currently, we only
5036                        # support optional arguments at the end
5037                        return self
5038                    # wasn't the last keyword => gaps are not supported
5039                    error(self.pos, "C function call is missing "
5040                                    "argument '%s'" % first_missing_keyword)
5041                    return None
5042                pos, arg = keywords[name]
5043                matched_args.add(name)
5044                matched_kwargs_count += 1
5045                if arg.value.is_simple():
5046                    args.append(arg.value)
5047                else:
5048                    temp = LetRefNode(arg.value)
5049                    assert temp.is_simple()
5050                    args.append(temp)
5051                    temps.append((pos, temp))
5052
5053            if temps:
5054                # may have to move preceding non-simple args into temps
5055                final_args = []
5056                new_temps = []
5057                first_temp_arg = temps[0][-1]
5058                for arg_value in args:
5059                    if arg_value is first_temp_arg:
5060                        break  # done
5061                    if arg_value.is_simple():
5062                        final_args.append(arg_value)
5063                    else:
5064                        temp = LetRefNode(arg_value)
5065                        new_temps.append(temp)
5066                        final_args.append(temp)
5067                if new_temps:
5068                    args = final_args
5069                temps = new_temps + [ arg for i,arg in sorted(temps) ]
5070
5071        # check for unexpected keywords
5072        for arg in kwargs.key_value_pairs:
5073            name = arg.key.value
5074            if name not in matched_args:
5075                has_errors = True
5076                error(arg.pos,
5077                      "C function got unexpected keyword argument '%s'" %
5078                      name)
5079
5080        if has_errors:
5081            # error was reported already
5082            return None
5083
5084        # all keywords mapped to positional arguments
5085        # if we are missing arguments, SimpleCallNode will figure it out
5086        node = SimpleCallNode(self.pos, function=function, args=args)
5087        for temp in temps[::-1]:
5088            node = EvalWithTempExprNode(temp, node)
5089        return node
5090
5091    def generate_result_code(self, code):
5092        if self.type.is_error: return
5093        if self.keyword_args:
5094            kwargs = self.keyword_args.py_result()
5095        else:
5096            kwargs = 'NULL'
5097        code.globalstate.use_utility_code(UtilityCode.load_cached(
5098            "PyObjectCall", "ObjectHandling.c"))
5099        code.putln(
5100            "%s = __Pyx_PyObject_Call(%s, %s, %s); %s" % (
5101                self.result(),
5102                self.function.py_result(),
5103                self.positional_args.py_result(),
5104                kwargs,
5105                code.error_goto_if_null(self.result(), self.pos)))
5106        code.put_gotref(self.py_result())
5107
5108
5109class AsTupleNode(ExprNode):
5110    #  Convert argument to tuple. Used for normalising
5111    #  the * argument of a function call.
5112    #
5113    #  arg    ExprNode
5114
5115    subexprs = ['arg']
5116
5117    def calculate_constant_result(self):
5118        self.constant_result = tuple(self.arg.constant_result)
5119
5120    def compile_time_value(self, denv):
5121        arg = self.arg.compile_time_value(denv)
5122        try:
5123            return tuple(arg)
5124        except Exception, e:
5125            self.compile_time_value_error(e)
5126
5127    def analyse_types(self, env):
5128        self.arg = self.arg.analyse_types(env)
5129        self.arg = self.arg.coerce_to_pyobject(env)
5130        self.type = tuple_type
5131        self.is_temp = 1
5132        return self
5133
5134    def may_be_none(self):
5135        return False
5136
5137    nogil_check = Node.gil_error
5138    gil_message = "Constructing Python tuple"
5139
5140    def generate_result_code(self, code):
5141        code.putln(
5142            "%s = PySequence_Tuple(%s); %s" % (
5143                self.result(),
5144                self.arg.py_result(),
5145                code.error_goto_if_null(self.result(), self.pos)))
5146        code.put_gotref(self.py_result())
5147
5148
5149class AttributeNode(ExprNode):
5150    #  obj.attribute
5151    #
5152    #  obj          ExprNode
5153    #  attribute    string
5154    #  needs_none_check boolean        Used if obj is an extension type.
5155    #                                  If set to True, it is known that the type is not None.
5156    #
5157    #  Used internally:
5158    #
5159    #  is_py_attr           boolean   Is a Python getattr operation
5160    #  member               string    C name of struct member
5161    #  is_called            boolean   Function call is being done on result
5162    #  entry                Entry     Symbol table entry of attribute
5163
5164    is_attribute = 1
5165    subexprs = ['obj']
5166
5167    type = PyrexTypes.error_type
5168    entry = None
5169    is_called = 0
5170    needs_none_check = True
5171    is_memslice_transpose = False
5172    is_special_lookup = False
5173
5174    def as_cython_attribute(self):
5175        if (isinstance(self.obj, NameNode) and
5176                self.obj.is_cython_module and not
5177                self.attribute == u"parallel"):
5178            return self.attribute
5179
5180        cy = self.obj.as_cython_attribute()
5181        if cy:
5182            return "%s.%s" % (cy, self.attribute)
5183        return None
5184
5185    def coerce_to(self, dst_type, env):
5186        #  If coercing to a generic pyobject and this is a cpdef function
5187        #  we can create the corresponding attribute
5188        if dst_type is py_object_type:
5189            entry = self.entry
5190            if entry and entry.is_cfunction and entry.as_variable:
5191                # must be a cpdef function
5192                self.is_temp = 1
5193                self.entry = entry.as_variable
5194                self.analyse_as_python_attribute(env)
5195                return self
5196        return ExprNode.coerce_to(self, dst_type, env)
5197
5198    def calculate_constant_result(self):
5199        attr = self.attribute
5200        if attr.startswith("__") and attr.endswith("__"):
5201            return
5202        self.constant_result = getattr(self.obj.constant_result, attr)
5203
5204    def compile_time_value(self, denv):
5205        attr = self.attribute
5206        if attr.startswith("__") and attr.endswith("__"):
5207            error(self.pos,
5208                  "Invalid attribute name '%s' in compile-time expression" % attr)
5209            return None
5210        obj = self.obj.compile_time_value(denv)
5211        try:
5212            return getattr(obj, attr)
5213        except Exception, e:
5214            self.compile_time_value_error(e)
5215
5216    def type_dependencies(self, env):
5217        return self.obj.type_dependencies(env)
5218
5219    def infer_type(self, env):
5220        # FIXME: this is way too redundant with analyse_types()
5221        node = self.analyse_as_cimported_attribute_node(env, target=False)
5222        if node is not None:
5223            return node.entry.type
5224        node = self.analyse_as_unbound_cmethod_node(env)
5225        if node is not None:
5226            return node.entry.type
5227        obj_type = self.obj.infer_type(env)
5228        self.analyse_attribute(env, obj_type=obj_type)
5229        if obj_type.is_builtin_type and self.type.is_cfunction:
5230            # special case: C-API replacements for C methods of
5231            # builtin types cannot be inferred as C functions as
5232            # that would prevent their use as bound methods
5233            return py_object_type
5234        return self.type
5235
5236    def analyse_target_declaration(self, env):
5237        pass
5238
5239    def analyse_target_types(self, env):
5240        node = self.analyse_types(env, target = 1)
5241        if node.type.is_const:
5242            error(self.pos, "Assignment to const attribute '%s'" % self.attribute)
5243        if not node.is_lvalue():
5244            error(self.pos, "Assignment to non-lvalue of type '%s'" % self.type)
5245        return node
5246
5247    def analyse_types(self, env, target = 0):
5248        self.initialized_check = env.directives['initializedcheck']
5249        node = self.analyse_as_cimported_attribute_node(env, target)
5250        if node is None and not target:
5251            node = self.analyse_as_unbound_cmethod_node(env)
5252        if node is None:
5253            node = self.analyse_as_ordinary_attribute_node(env, target)
5254            assert node is not None
5255        if node.entry:
5256            node.entry.used = True
5257        if node.is_attribute:
5258            node.wrap_obj_in_nonecheck(env)
5259        return node
5260
5261    def analyse_as_cimported_attribute_node(self, env, target):
5262        # Try to interpret this as a reference to an imported
5263        # C const, type, var or function. If successful, mutates
5264        # this node into a NameNode and returns 1, otherwise
5265        # returns 0.
5266        module_scope = self.obj.analyse_as_module(env)
5267        if module_scope:
5268            entry = module_scope.lookup_here(self.attribute)
5269            if entry and (
5270                    entry.is_cglobal or entry.is_cfunction
5271                    or entry.is_type or entry.is_const):
5272                return self.as_name_node(env, entry, target)
5273        return None
5274
5275    def analyse_as_unbound_cmethod_node(self, env):
5276        # Try to interpret this as a reference to an unbound
5277        # C method of an extension type or builtin type.  If successful,
5278        # creates a corresponding NameNode and returns it, otherwise
5279        # returns None.
5280        type = self.obj.analyse_as_extension_type(env)
5281        if type:
5282            entry = type.scope.lookup_here(self.attribute)
5283            if entry and entry.is_cmethod:
5284                if type.is_builtin_type:
5285                    if not self.is_called:
5286                        # must handle this as Python object
5287                        return None
5288                    ubcm_entry = entry
5289                else:
5290                    # Create a temporary entry describing the C method
5291                    # as an ordinary function.
5292                    ubcm_entry = Symtab.Entry(entry.name,
5293                        "%s->%s" % (type.vtabptr_cname, entry.cname),
5294                        entry.type)
5295                    ubcm_entry.is_cfunction = 1
5296                    ubcm_entry.func_cname = entry.func_cname
5297                    ubcm_entry.is_unbound_cmethod = 1
5298                return self.as_name_node(env, ubcm_entry, target=False)
5299        return None
5300
5301    def analyse_as_type(self, env):
5302        module_scope = self.obj.analyse_as_module(env)
5303        if module_scope:
5304            return module_scope.lookup_type(self.attribute)
5305        if not self.obj.is_string_literal:
5306            base_type = self.obj.analyse_as_type(env)
5307            if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
5308                return base_type.scope.lookup_type(self.attribute)
5309        return None
5310
5311    def analyse_as_extension_type(self, env):
5312        # Try to interpret this as a reference to an extension type
5313        # in a cimported module. Returns the extension type, or None.
5314        module_scope = self.obj.analyse_as_module(env)
5315        if module_scope:
5316            entry = module_scope.lookup_here(self.attribute)
5317            if entry and entry.is_type:
5318                if entry.type.is_extension_type or entry.type.is_builtin_type:
5319                    return entry.type
5320        return None
5321
5322    def analyse_as_module(self, env):
5323        # Try to interpret this as a reference to a cimported module
5324        # in another cimported module. Returns the module scope, or None.
5325        module_scope = self.obj.analyse_as_module(env)
5326        if module_scope:
5327            entry = module_scope.lookup_here(self.attribute)
5328            if entry and entry.as_module:
5329                return entry.as_module
5330        return None
5331
5332    def as_name_node(self, env, entry, target):
5333        # Create a corresponding NameNode from this node and complete the
5334        # analyse_types phase.
5335        node = NameNode.from_node(self, name=self.attribute, entry=entry)
5336        if target:
5337            node = node.analyse_target_types(env)
5338        else:
5339            node = node.analyse_rvalue_entry(env)
5340        node.entry.used = 1
5341        return node
5342
5343    def analyse_as_ordinary_attribute_node(self, env, target):
5344        self.obj = self.obj.analyse_types(env)
5345        self.analyse_attribute(env)
5346        if self.entry and self.entry.is_cmethod and not self.is_called:
5347#            error(self.pos, "C method can only be called")
5348            pass
5349        ## Reference to C array turns into pointer to first element.
5350        #while self.type.is_array:
5351        #    self.type = self.type.element_ptr_type()
5352        if self.is_py_attr:
5353            if not target:
5354                self.is_temp = 1
5355                self.result_ctype = py_object_type
5356        elif target and self.obj.type.is_builtin_type:
5357            error(self.pos, "Assignment to an immutable object field")
5358        #elif self.type.is_memoryviewslice and not target:
5359        #    self.is_temp = True
5360        return self
5361
5362    def analyse_attribute(self, env, obj_type = None):
5363        # Look up attribute and set self.type and self.member.
5364        immutable_obj = obj_type is not None # used during type inference
5365        self.is_py_attr = 0
5366        self.member = self.attribute
5367        if obj_type is None:
5368            if self.obj.type.is_string or self.obj.type.is_pyunicode_ptr:
5369                self.obj = self.obj.coerce_to_pyobject(env)
5370            obj_type = self.obj.type
5371        else:
5372            if obj_type.is_string or obj_type.is_pyunicode_ptr:
5373                obj_type = py_object_type
5374        if obj_type.is_ptr or obj_type.is_array:
5375            obj_type = obj_type.base_type
5376            self.op = "->"
5377        elif obj_type.is_extension_type or obj_type.is_builtin_type:
5378            self.op = "->"
5379        else:
5380            self.op = "."
5381        if obj_type.has_attributes:
5382            if obj_type.attributes_known():
5383                if (obj_type.is_memoryviewslice and not
5384                        obj_type.scope.lookup_here(self.attribute)):
5385                    if self.attribute == 'T':
5386                        self.is_memslice_transpose = True
5387                        self.is_temp = True
5388                        self.use_managed_ref = True
5389                        self.type = self.obj.type
5390                        return
5391                    else:
5392                        obj_type.declare_attribute(self.attribute, env, self.pos)
5393                entry = obj_type.scope.lookup_here(self.attribute)
5394                if entry and entry.is_member:
5395                    entry = None
5396            else:
5397                error(self.pos,
5398                    "Cannot select attribute of incomplete type '%s'"
5399                    % obj_type)
5400                self.type = PyrexTypes.error_type
5401                return
5402            self.entry = entry
5403            if entry:
5404                if obj_type.is_extension_type and entry.name == "__weakref__":
5405                    error(self.pos, "Illegal use of special attribute __weakref__")
5406
5407                # def methods need the normal attribute lookup
5408                # because they do not have struct entries
5409                # fused function go through assignment synthesis
5410                # (foo = pycfunction(foo_func_obj)) and need to go through
5411                # regular Python lookup as well
5412                if (entry.is_variable and not entry.fused_cfunction) or entry.is_cmethod:
5413                    self.type = entry.type
5414                    self.member = entry.cname
5415                    return
5416                else:
5417                    # If it's not a variable or C method, it must be a Python
5418                    # method of an extension type, so we treat it like a Python
5419                    # attribute.
5420                    pass
5421        # If we get here, the base object is not a struct/union/extension
5422        # type, or it is an extension type and the attribute is either not
5423        # declared or is declared as a Python method. Treat it as a Python
5424        # attribute reference.
5425        self.analyse_as_python_attribute(env, obj_type, immutable_obj)
5426
5427    def analyse_as_python_attribute(self, env, obj_type=None, immutable_obj=False):
5428        if obj_type is None:
5429            obj_type = self.obj.type
5430        # mangle private '__*' Python attributes used inside of a class
5431        self.attribute = env.mangle_class_private_name(self.attribute)
5432        self.member = self.attribute
5433        self.type = py_object_type
5434        self.is_py_attr = 1
5435        if not obj_type.is_pyobject and not obj_type.is_error:
5436            if obj_type.can_coerce_to_pyobject(env):
5437                if not immutable_obj:
5438                    self.obj = self.obj.coerce_to_pyobject(env)
5439            elif (obj_type.is_cfunction and (self.obj.is_name or self.obj.is_attribute)
5440                  and self.obj.entry.as_variable
5441                  and self.obj.entry.as_variable.type.is_pyobject):
5442                # might be an optimised builtin function => unpack it
5443                if not immutable_obj:
5444                    self.obj = self.obj.coerce_to_pyobject(env)
5445            else:
5446                error(self.pos,
5447                      "Object of type '%s' has no attribute '%s'" %
5448                      (obj_type, self.attribute))
5449
5450    def wrap_obj_in_nonecheck(self, env):
5451        if not env.directives['nonecheck']:
5452            return
5453
5454        msg = None
5455        format_args = ()
5456        if (self.obj.type.is_extension_type and self.needs_none_check and not
5457                self.is_py_attr):
5458            msg = "'NoneType' object has no attribute '%s'"
5459            format_args = (self.attribute,)
5460        elif self.obj.type.is_memoryviewslice:
5461            if self.is_memslice_transpose:
5462                msg = "Cannot transpose None memoryview slice"
5463            else:
5464                entry = self.obj.type.scope.lookup_here(self.attribute)
5465                if entry:
5466                    # copy/is_c_contig/shape/strides etc
5467                    msg = "Cannot access '%s' attribute of None memoryview slice"
5468                    format_args = (entry.name,)
5469
5470        if msg:
5471            self.obj = self.obj.as_none_safe_node(msg, 'PyExc_AttributeError',
5472                                                  format_args=format_args)
5473
5474
5475    def nogil_check(self, env):
5476        if self.is_py_attr:
5477            self.gil_error()
5478        elif self.type.is_memoryviewslice:
5479            import MemoryView
5480            MemoryView.err_if_nogil_initialized_check(self.pos, env, 'attribute')
5481
5482    gil_message = "Accessing Python attribute"
5483
5484    def is_simple(self):
5485        if self.obj:
5486            return self.result_in_temp() or self.obj.is_simple()
5487        else:
5488            return NameNode.is_simple(self)
5489
5490    def is_lvalue(self):
5491        if self.obj:
5492            return not self.type.is_array
5493        else:
5494            return NameNode.is_lvalue(self)
5495
5496    def is_ephemeral(self):
5497        if self.obj:
5498            return self.obj.is_ephemeral()
5499        else:
5500            return NameNode.is_ephemeral(self)
5501
5502    def calculate_result_code(self):
5503        #print "AttributeNode.calculate_result_code:", self.member ###
5504        #print "...obj node =", self.obj, "code", self.obj.result() ###
5505        #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
5506        obj = self.obj
5507        obj_code = obj.result_as(obj.type)
5508        #print "...obj_code =", obj_code ###
5509        if self.entry and self.entry.is_cmethod:
5510            if obj.type.is_extension_type and not self.entry.is_builtin_cmethod:
5511                if self.entry.final_func_cname:
5512                    return self.entry.final_func_cname
5513
5514                if self.type.from_fused:
5515                    # If the attribute was specialized through indexing, make
5516                    # sure to get the right fused name, as our entry was
5517                    # replaced by our parent index node
5518                    # (AnalyseExpressionsTransform)
5519                    self.member = self.entry.cname
5520
5521                return "((struct %s *)%s%s%s)->%s" % (
5522                    obj.type.vtabstruct_cname, obj_code, self.op,
5523                    obj.type.vtabslot_cname, self.member)
5524            elif self.result_is_used:
5525                return self.member
5526            # Generating no code at all for unused access to optimised builtin
5527            # methods fixes the problem that some optimisations only exist as
5528            # macros, i.e. there is no function pointer to them, so we would
5529            # generate invalid C code here.
5530            return
5531        elif obj.type.is_complex:
5532            return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
5533        else:
5534            if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
5535                # accessing a field of a builtin type, need to cast better than result_as() does
5536                obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
5537            return "%s%s%s" % (obj_code, self.op, self.member)
5538
5539    def generate_result_code(self, code):
5540        if self.is_py_attr:
5541            if self.is_special_lookup:
5542                code.globalstate.use_utility_code(
5543                    UtilityCode.load_cached("PyObjectLookupSpecial", "ObjectHandling.c"))
5544                lookup_func_name = '__Pyx_PyObject_LookupSpecial'
5545            else:
5546                code.globalstate.use_utility_code(
5547                    UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c"))
5548                lookup_func_name = '__Pyx_PyObject_GetAttrStr'
5549            code.putln(
5550                '%s = %s(%s, %s); %s' % (
5551                    self.result(),
5552                    lookup_func_name,
5553                    self.obj.py_result(),
5554                    code.intern_identifier(self.attribute),
5555                    code.error_goto_if_null(self.result(), self.pos)))
5556            code.put_gotref(self.py_result())
5557        elif self.type.is_memoryviewslice:
5558            if self.is_memslice_transpose:
5559                # transpose the slice
5560                for access, packing in self.type.axes:
5561                    if access == 'ptr':
5562                        error(self.pos, "Transposing not supported for slices "
5563                                        "with indirect dimensions")
5564                        return
5565
5566                code.putln("%s = %s;" % (self.result(), self.obj.result()))
5567                if self.obj.is_name or (self.obj.is_attribute and
5568                                        self.obj.is_memslice_transpose):
5569                    code.put_incref_memoryviewslice(self.result(), have_gil=True)
5570
5571                T = "__pyx_memslice_transpose(&%s) == 0"
5572                code.putln(code.error_goto_if(T % self.result(), self.pos))
5573            elif self.initialized_check:
5574                code.putln(
5575                    'if (unlikely(!%s.memview)) {'
5576                        'PyErr_SetString(PyExc_AttributeError,'
5577                                        '"Memoryview is not initialized");'
5578                        '%s'
5579                    '}' % (self.result(), code.error_goto(self.pos)))
5580        else:
5581            # result_code contains what is needed, but we may need to insert
5582            # a check and raise an exception
5583            if self.obj.type.is_extension_type:
5584                pass
5585            elif self.entry and self.entry.is_cmethod and self.entry.utility_code:
5586                # C method implemented as function call with utility code
5587                code.globalstate.use_utility_code(self.entry.utility_code)
5588
5589    def generate_disposal_code(self, code):
5590        if self.is_temp and self.type.is_memoryviewslice and self.is_memslice_transpose:
5591            # mirror condition for putting the memview incref here:
5592            if self.obj.is_name or (self.obj.is_attribute and
5593                                    self.obj.is_memslice_transpose):
5594                code.put_xdecref_memoryviewslice(
5595                        self.result(), have_gil=True)
5596        else:
5597            ExprNode.generate_disposal_code(self, code)
5598
5599    def generate_assignment_code(self, rhs, code):
5600        self.obj.generate_evaluation_code(code)
5601        if self.is_py_attr:
5602            code.globalstate.use_utility_code(
5603                UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
5604            code.put_error_if_neg(self.pos,
5605                '__Pyx_PyObject_SetAttrStr(%s, %s, %s)' % (
5606                    self.obj.py_result(),
5607                    code.intern_identifier(self.attribute),
5608                    rhs.py_result()))
5609            rhs.generate_disposal_code(code)
5610            rhs.free_temps(code)
5611        elif self.obj.type.is_complex:
5612            code.putln("__Pyx_SET_C%s(%s, %s);" % (
5613                self.member.upper(),
5614                self.obj.result_as(self.obj.type),
5615                rhs.result_as(self.ctype())))
5616        else:
5617            select_code = self.result()
5618            if self.type.is_pyobject and self.use_managed_ref:
5619                rhs.make_owned_reference(code)
5620                code.put_giveref(rhs.py_result())
5621                code.put_gotref(select_code)
5622                code.put_decref(select_code, self.ctype())
5623            elif self.type.is_memoryviewslice:
5624                import MemoryView
5625                MemoryView.put_assign_to_memviewslice(
5626                        select_code, rhs, rhs.result(), self.type, code)
5627
5628            if not self.type.is_memoryviewslice:
5629                code.putln(
5630                    "%s = %s;" % (
5631                        select_code,
5632                        rhs.result_as(self.ctype())))
5633                        #rhs.result()))
5634            rhs.generate_post_assignment_code(code)
5635            rhs.free_temps(code)
5636        self.obj.generate_disposal_code(code)
5637        self.obj.free_temps(code)
5638
5639    def generate_deletion_code(self, code, ignore_nonexisting=False):
5640        self.obj.generate_evaluation_code(code)
5641        if self.is_py_attr or (self.entry.scope.is_property_scope
5642                               and u'__del__' in self.entry.scope.entries):
5643            code.globalstate.use_utility_code(
5644                UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
5645            code.put_error_if_neg(self.pos,
5646                '__Pyx_PyObject_DelAttrStr(%s, %s)' % (
5647                    self.obj.py_result(),
5648                    code.intern_identifier(self.attribute)))
5649        else:
5650            error(self.pos, "Cannot delete C attribute of extension type")
5651        self.obj.generate_disposal_code(code)
5652        self.obj.free_temps(code)
5653
5654    def annotate(self, code):
5655        if self.is_py_attr:
5656            style, text = 'py_attr', 'python attribute (%s)'
5657        else:
5658            style, text = 'c_attr', 'c attribute (%s)'
5659        code.annotate(self.pos, AnnotationItem(style, text % self.type, size=len(self.attribute)))
5660
5661
5662#-------------------------------------------------------------------
5663#
5664#  Constructor nodes
5665#
5666#-------------------------------------------------------------------
5667
5668class StarredTargetNode(ExprNode):
5669    #  A starred expression like "*a"
5670    #
5671    #  This is only allowed in sequence assignment targets such as
5672    #
5673    #      a, *b = (1,2,3,4)    =>     a = 1 ; b = [2,3,4]
5674    #
5675    #  and will be removed during type analysis (or generate an error
5676    #  if it's found at unexpected places).
5677    #
5678    #  target          ExprNode
5679
5680    subexprs = ['target']
5681    is_starred = 1
5682    type = py_object_type
5683    is_temp = 1
5684
5685    def __init__(self, pos, target):
5686        ExprNode.__init__(self, pos)
5687        self.target = target
5688
5689    def analyse_declarations(self, env):
5690        error(self.pos, "can use starred expression only as assignment target")
5691        self.target.analyse_declarations(env)
5692
5693    def analyse_types(self, env):
5694        error(self.pos, "can use starred expression only as assignment target")
5695        self.target = self.target.analyse_types(env)
5696        self.type = self.target.type
5697        return self
5698
5699    def analyse_target_declaration(self, env):
5700        self.target.analyse_target_declaration(env)
5701
5702    def analyse_target_types(self, env):
5703        self.target = self.target.analyse_target_types(env)
5704        self.type = self.target.type
5705        return self
5706
5707    def calculate_result_code(self):
5708        return ""
5709
5710    def generate_result_code(self, code):
5711        pass
5712
5713
5714class SequenceNode(ExprNode):
5715    #  Base class for list and tuple constructor nodes.
5716    #  Contains common code for performing sequence unpacking.
5717    #
5718    #  args                    [ExprNode]
5719    #  unpacked_items          [ExprNode] or None
5720    #  coerced_unpacked_items  [ExprNode] or None
5721    # mult_factor              ExprNode     the integer number of content repetitions ([1,2]*3)
5722
5723    subexprs = ['args', 'mult_factor']
5724
5725    is_sequence_constructor = 1
5726    unpacked_items = None
5727    mult_factor = None
5728    slow = False  # trade speed for code size (e.g. use PyTuple_Pack())
5729
5730    def compile_time_value_list(self, denv):
5731        return [arg.compile_time_value(denv) for arg in self.args]
5732
5733    def replace_starred_target_node(self):
5734        # replace a starred node in the targets by the contained expression
5735        self.starred_assignment = False
5736        args = []
5737        for arg in self.args:
5738            if arg.is_starred:
5739                if self.starred_assignment:
5740                    error(arg.pos, "more than 1 starred expression in assignment")
5741                self.starred_assignment = True
5742                arg = arg.target
5743                arg.is_starred = True
5744            args.append(arg)
5745        self.args = args
5746
5747    def analyse_target_declaration(self, env):
5748        self.replace_starred_target_node()
5749        for arg in self.args:
5750            arg.analyse_target_declaration(env)
5751
5752    def analyse_types(self, env, skip_children=False):
5753        for i in range(len(self.args)):
5754            arg = self.args[i]
5755            if not skip_children: arg = arg.analyse_types(env)
5756            self.args[i] = arg.coerce_to_pyobject(env)
5757        if self.mult_factor:
5758            self.mult_factor = self.mult_factor.analyse_types(env)
5759            if not self.mult_factor.type.is_int:
5760                self.mult_factor = self.mult_factor.coerce_to_pyobject(env)
5761        self.is_temp = 1
5762        # not setting self.type here, subtypes do this
5763        return self
5764
5765    def may_be_none(self):
5766        return False
5767
5768    def analyse_target_types(self, env):
5769        if self.mult_factor:
5770            error(self.pos, "can't assign to multiplied sequence")
5771        self.unpacked_items = []
5772        self.coerced_unpacked_items = []
5773        self.any_coerced_items = False
5774        for i, arg in enumerate(self.args):
5775            arg = self.args[i] = arg.analyse_target_types(env)
5776            if arg.is_starred:
5777                if not arg.type.assignable_from(Builtin.list_type):
5778                    error(arg.pos,
5779                          "starred target must have Python object (list) type")
5780                if arg.type is py_object_type:
5781                    arg.type = Builtin.list_type
5782            unpacked_item = PyTempNode(self.pos, env)
5783            coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
5784            if unpacked_item is not coerced_unpacked_item:
5785                self.any_coerced_items = True
5786            self.unpacked_items.append(unpacked_item)
5787            self.coerced_unpacked_items.append(coerced_unpacked_item)
5788        self.type = py_object_type
5789        return self
5790
5791    def generate_result_code(self, code):
5792        self.generate_operation_code(code)
5793
5794    def generate_sequence_packing_code(self, code, target=None, plain=False):
5795        if target is None:
5796            target = self.result()
5797        size_factor = c_mult = ''
5798        mult_factor = None
5799
5800        if self.mult_factor and not plain:
5801            mult_factor = self.mult_factor
5802            if mult_factor.type.is_int:
5803                c_mult = mult_factor.result()
5804                if isinstance(mult_factor.constant_result, (int,long)) \
5805                       and mult_factor.constant_result > 0:
5806                    size_factor = ' * %s' % mult_factor.constant_result
5807                else:
5808                    size_factor = ' * ((%s<0) ? 0:%s)' % (c_mult, c_mult)
5809
5810        if self.type is Builtin.tuple_type and (self.is_literal or self.slow) and not c_mult:
5811            # use PyTuple_Pack() to avoid generating huge amounts of one-time code
5812            code.putln('%s = PyTuple_Pack(%d, %s); %s' % (
5813                target,
5814                len(self.args),
5815                ', '.join([ arg.py_result() for arg in self.args ]),
5816                code.error_goto_if_null(target, self.pos)))
5817            code.put_gotref(target)
5818        else:
5819            # build the tuple/list step by step, potentially multiplying it as we go
5820            if self.type is Builtin.list_type:
5821                create_func, set_item_func = 'PyList_New', 'PyList_SET_ITEM'
5822            elif self.type is Builtin.tuple_type:
5823                create_func, set_item_func = 'PyTuple_New', 'PyTuple_SET_ITEM'
5824            else:
5825                raise InternalError("sequence packing for unexpected type %s" % self.type)
5826            arg_count = len(self.args)
5827            code.putln("%s = %s(%s%s); %s" % (
5828                target, create_func, arg_count, size_factor,
5829                code.error_goto_if_null(target, self.pos)))
5830            code.put_gotref(target)
5831
5832            if c_mult:
5833                # FIXME: can't use a temp variable here as the code may
5834                # end up in the constant building function.  Temps
5835                # currently don't work there.
5836
5837                #counter = code.funcstate.allocate_temp(mult_factor.type, manage_ref=False)
5838                counter = Naming.quick_temp_cname
5839                code.putln('{ Py_ssize_t %s;' % counter)
5840                if arg_count == 1:
5841                    offset = counter
5842                else:
5843                    offset = '%s * %s' % (counter, arg_count)
5844                code.putln('for (%s=0; %s < %s; %s++) {' % (
5845                    counter, counter, c_mult, counter
5846                    ))
5847            else:
5848                offset = ''
5849
5850            for i in xrange(arg_count):
5851                arg = self.args[i]
5852                if c_mult or not arg.result_in_temp():
5853                    code.put_incref(arg.result(), arg.ctype())
5854                code.putln("%s(%s, %s, %s);" % (
5855                    set_item_func,
5856                    target,
5857                    (offset and i) and ('%s + %s' % (offset, i)) or (offset or i),
5858                    arg.py_result()))
5859                code.put_giveref(arg.py_result())
5860
5861            if c_mult:
5862                code.putln('}')
5863                #code.funcstate.release_temp(counter)
5864                code.putln('}')
5865
5866        if mult_factor is not None and mult_factor.type.is_pyobject:
5867            code.putln('{ PyObject* %s = PyNumber_InPlaceMultiply(%s, %s); %s' % (
5868                Naming.quick_temp_cname, target, mult_factor.py_result(),
5869                code.error_goto_if_null(Naming.quick_temp_cname, self.pos)
5870                ))
5871            code.put_gotref(Naming.quick_temp_cname)
5872            code.put_decref(target, py_object_type)
5873            code.putln('%s = %s;' % (target, Naming.quick_temp_cname))
5874            code.putln('}')
5875
5876    def generate_subexpr_disposal_code(self, code):
5877        if self.mult_factor and self.mult_factor.type.is_int:
5878            super(SequenceNode, self).generate_subexpr_disposal_code(code)
5879        elif self.type is Builtin.tuple_type and (self.is_literal or self.slow):
5880            super(SequenceNode, self).generate_subexpr_disposal_code(code)
5881        else:
5882            # We call generate_post_assignment_code here instead
5883            # of generate_disposal_code, because values were stored
5884            # in the tuple using a reference-stealing operation.
5885            for arg in self.args:
5886                arg.generate_post_assignment_code(code)
5887                # Should NOT call free_temps -- this is invoked by the default
5888                # generate_evaluation_code which will do that.
5889            if self.mult_factor:
5890                self.mult_factor.generate_disposal_code(code)
5891
5892    def generate_assignment_code(self, rhs, code):
5893        if self.starred_assignment:
5894            self.generate_starred_assignment_code(rhs, code)
5895        else:
5896            self.generate_parallel_assignment_code(rhs, code)
5897
5898        for item in self.unpacked_items:
5899            item.release(code)
5900        rhs.free_temps(code)
5901
5902    _func_iternext_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
5903        PyrexTypes.py_object_type, [
5904            PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None),
5905            ]))
5906
5907    def generate_parallel_assignment_code(self, rhs, code):
5908        # Need to work around the fact that generate_evaluation_code
5909        # allocates the temps in a rather hacky way -- the assignment
5910        # is evaluated twice, within each if-block.
5911        for item in self.unpacked_items:
5912            item.allocate(code)
5913        special_unpack = (rhs.type is py_object_type
5914                          or rhs.type in (tuple_type, list_type)
5915                          or not rhs.type.is_builtin_type)
5916        long_enough_for_a_loop = len(self.unpacked_items) > 3
5917
5918        if special_unpack:
5919            self.generate_special_parallel_unpacking_code(
5920                code, rhs, use_loop=long_enough_for_a_loop)
5921        else:
5922            code.putln("{")
5923            self.generate_generic_parallel_unpacking_code(
5924                code, rhs, self.unpacked_items, use_loop=long_enough_for_a_loop)
5925            code.putln("}")
5926
5927        for value_node in self.coerced_unpacked_items:
5928            value_node.generate_evaluation_code(code)
5929        for i in range(len(self.args)):
5930            self.args[i].generate_assignment_code(
5931                self.coerced_unpacked_items[i], code)
5932
5933    def generate_special_parallel_unpacking_code(self, code, rhs, use_loop):
5934        sequence_type_test = '1'
5935        none_check = "likely(%s != Py_None)" % rhs.py_result()
5936        if rhs.type is list_type:
5937            sequence_types = ['List']
5938            if rhs.may_be_none():
5939                sequence_type_test = none_check
5940        elif rhs.type is tuple_type:
5941            sequence_types = ['Tuple']
5942            if rhs.may_be_none():
5943                sequence_type_test = none_check
5944        else:
5945            sequence_types = ['Tuple', 'List']
5946            tuple_check = 'likely(PyTuple_CheckExact(%s))' % rhs.py_result()
5947            list_check  = 'PyList_CheckExact(%s)' % rhs.py_result()
5948            sequence_type_test = "(%s) || (%s)" % (tuple_check, list_check)
5949
5950        code.putln("if (%s) {" % sequence_type_test)
5951        code.putln("PyObject* sequence = %s;" % rhs.py_result())
5952
5953        # list/tuple => check size
5954        code.putln("#if CYTHON_COMPILING_IN_CPYTHON")
5955        code.putln("Py_ssize_t size = Py_SIZE(sequence);")
5956        code.putln("#else")
5957        code.putln("Py_ssize_t size = PySequence_Size(sequence);")  # < 0 => exception
5958        code.putln("#endif")
5959        code.putln("if (unlikely(size != %d)) {" % len(self.args))
5960        code.globalstate.use_utility_code(raise_too_many_values_to_unpack)
5961        code.putln("if (size > %d) __Pyx_RaiseTooManyValuesError(%d);" % (
5962            len(self.args), len(self.args)))
5963        code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
5964        code.putln("else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);")
5965        code.putln(code.error_goto(self.pos))
5966        code.putln("}")
5967
5968        code.putln("#if CYTHON_COMPILING_IN_CPYTHON")
5969        # unpack items from list/tuple in unrolled loop (can't fail)
5970        if len(sequence_types) == 2:
5971            code.putln("if (likely(Py%s_CheckExact(sequence))) {" % sequence_types[0])
5972        for i, item in enumerate(self.unpacked_items):
5973            code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
5974                item.result(), sequence_types[0], i))
5975        if len(sequence_types) == 2:
5976            code.putln("} else {")
5977            for i, item in enumerate(self.unpacked_items):
5978                code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
5979                    item.result(), sequence_types[1], i))
5980            code.putln("}")
5981        for item in self.unpacked_items:
5982            code.put_incref(item.result(), item.ctype())
5983
5984        code.putln("#else")
5985        # in non-CPython, use the PySequence protocol (which can fail)
5986        if not use_loop:
5987            for i, item in enumerate(self.unpacked_items):
5988                code.putln("%s = PySequence_ITEM(sequence, %d); %s" % (
5989                    item.result(), i,
5990                    code.error_goto_if_null(item.result(), self.pos)))
5991                code.put_gotref(item.result())
5992        else:
5993            code.putln("{")
5994            code.putln("Py_ssize_t i;")
5995            code.putln("PyObject** temps[%s] = {%s};" % (
5996                len(self.unpacked_items),
5997                ','.join(['&%s' % item.result() for item in self.unpacked_items])))
5998            code.putln("for (i=0; i < %s; i++) {" % len(self.unpacked_items))
5999            code.putln("PyObject* item = PySequence_ITEM(sequence, i); %s" % (
6000                code.error_goto_if_null('item', self.pos)))
6001            code.put_gotref('item')
6002            code.putln("*(temps[i]) = item;")
6003            code.putln("}")
6004            code.putln("}")
6005
6006        code.putln("#endif")
6007        rhs.generate_disposal_code(code)
6008
6009        if sequence_type_test == '1':
6010            code.putln("}")  # all done
6011        elif sequence_type_test == none_check:
6012            # either tuple/list or None => save some code by generating the error directly
6013            code.putln("} else {")
6014            code.globalstate.use_utility_code(
6015                UtilityCode.load_cached("RaiseNoneIterError", "ObjectHandling.c"))
6016            code.putln("__Pyx_RaiseNoneNotIterableError(); %s" % code.error_goto(self.pos))
6017            code.putln("}")  # all done
6018        else:
6019            code.putln("} else {")  # needs iteration fallback code
6020            self.generate_generic_parallel_unpacking_code(
6021                code, rhs, self.unpacked_items, use_loop=use_loop)
6022            code.putln("}")
6023
6024    def generate_generic_parallel_unpacking_code(self, code, rhs, unpacked_items, use_loop, terminate=True):
6025        code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
6026        code.globalstate.use_utility_code(UtilityCode.load_cached("IterFinish", "ObjectHandling.c"))
6027        code.putln("Py_ssize_t index = -1;") # must be at the start of a C block!
6028
6029        if use_loop:
6030            code.putln("PyObject** temps[%s] = {%s};" % (
6031                len(self.unpacked_items),
6032                ','.join(['&%s' % item.result() for item in unpacked_items])))
6033
6034        iterator_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
6035        code.putln(
6036            "%s = PyObject_GetIter(%s); %s" % (
6037                iterator_temp,
6038                rhs.py_result(),
6039                code.error_goto_if_null(iterator_temp, self.pos)))
6040        code.put_gotref(iterator_temp)
6041        rhs.generate_disposal_code(code)
6042
6043        iternext_func = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
6044        code.putln("%s = Py_TYPE(%s)->tp_iternext;" % (
6045            iternext_func, iterator_temp))
6046
6047        unpacking_error_label = code.new_label('unpacking_failed')
6048        unpack_code = "%s(%s)" % (iternext_func, iterator_temp)
6049        if use_loop:
6050            code.putln("for (index=0; index < %s; index++) {" % len(unpacked_items))
6051            code.put("PyObject* item = %s; if (unlikely(!item)) " % unpack_code)
6052            code.put_goto(unpacking_error_label)
6053            code.put_gotref("item")
6054            code.putln("*(temps[index]) = item;")
6055            code.putln("}")
6056        else:
6057            for i, item in enumerate(unpacked_items):
6058                code.put(
6059                    "index = %d; %s = %s; if (unlikely(!%s)) " % (
6060                        i,
6061                        item.result(),
6062                        unpack_code,
6063                        item.result()))
6064                code.put_goto(unpacking_error_label)
6065                code.put_gotref(item.py_result())
6066
6067        if terminate:
6068            code.globalstate.use_utility_code(
6069                UtilityCode.load_cached("UnpackItemEndCheck", "ObjectHandling.c"))
6070            code.put_error_if_neg(self.pos, "__Pyx_IternextUnpackEndCheck(%s, %d)" % (
6071                unpack_code,
6072                len(unpacked_items)))
6073            code.putln("%s = NULL;" % iternext_func)
6074            code.put_decref_clear(iterator_temp, py_object_type)
6075
6076        unpacking_done_label = code.new_label('unpacking_done')
6077        code.put_goto(unpacking_done_label)
6078
6079        code.put_label(unpacking_error_label)
6080        code.put_decref_clear(iterator_temp, py_object_type)
6081        code.putln("%s = NULL;" % iternext_func)
6082        code.putln("if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);")
6083        code.putln(code.error_goto(self.pos))
6084        code.put_label(unpacking_done_label)
6085
6086        code.funcstate.release_temp(iternext_func)
6087        if terminate:
6088            code.funcstate.release_temp(iterator_temp)
6089            iterator_temp = None
6090
6091        return iterator_temp
6092
6093    def generate_starred_assignment_code(self, rhs, code):
6094        for i, arg in enumerate(self.args):
6095            if arg.is_starred:
6096                starred_target = self.unpacked_items[i]
6097                unpacked_fixed_items_left  = self.unpacked_items[:i]
6098                unpacked_fixed_items_right = self.unpacked_items[i+1:]
6099                break
6100        else:
6101            assert False
6102
6103        iterator_temp = None
6104        if unpacked_fixed_items_left:
6105            for item in unpacked_fixed_items_left:
6106                item.allocate(code)
6107            code.putln('{')
6108            iterator_temp = self.generate_generic_parallel_unpacking_code(
6109                code, rhs, unpacked_fixed_items_left,
6110                use_loop=True, terminate=False)
6111            for i, item in enumerate(unpacked_fixed_items_left):
6112                value_node = self.coerced_unpacked_items[i]
6113                value_node.generate_evaluation_code(code)
6114            code.putln('}')
6115
6116        starred_target.allocate(code)
6117        target_list = starred_target.result()
6118        code.putln("%s = PySequence_List(%s); %s" % (
6119            target_list,
6120            iterator_temp or rhs.py_result(),
6121            code.error_goto_if_null(target_list, self.pos)))
6122        code.put_gotref(target_list)
6123
6124        if iterator_temp:
6125            code.put_decref_clear(iterator_temp, py_object_type)
6126            code.funcstate.release_temp(iterator_temp)
6127        else:
6128            rhs.generate_disposal_code(code)
6129
6130        if unpacked_fixed_items_right:
6131            code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
6132            length_temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
6133            code.putln('%s = PyList_GET_SIZE(%s);' % (length_temp, target_list))
6134            code.putln("if (unlikely(%s < %d)) {" % (length_temp, len(unpacked_fixed_items_right)))
6135            code.putln("__Pyx_RaiseNeedMoreValuesError(%d+%s); %s" % (
6136                 len(unpacked_fixed_items_left), length_temp,
6137                 code.error_goto(self.pos)))
6138            code.putln('}')
6139
6140            for item in unpacked_fixed_items_right[::-1]:
6141                item.allocate(code)
6142            for i, (item, coerced_arg) in enumerate(zip(unpacked_fixed_items_right[::-1],
6143                                                        self.coerced_unpacked_items[::-1])):
6144                code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
6145                code.putln("%s = PyList_GET_ITEM(%s, %s-%d); " % (
6146                    item.py_result(), target_list, length_temp, i+1))
6147                # resize the list the hard way
6148                code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
6149                code.putln('#else')
6150                code.putln("%s = PySequence_ITEM(%s, %s-%d); " % (
6151                    item.py_result(), target_list, length_temp, i+1))
6152                code.putln('#endif')
6153                code.put_gotref(item.py_result())
6154                coerced_arg.generate_evaluation_code(code)
6155
6156            code.putln('#if !CYTHON_COMPILING_IN_CPYTHON')
6157            sublist_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
6158            code.putln('%s = PySequence_GetSlice(%s, 0, %s-%d); %s' % (
6159                sublist_temp, target_list, length_temp, len(unpacked_fixed_items_right),
6160                code.error_goto_if_null(sublist_temp, self.pos)))
6161            code.put_gotref(sublist_temp)
6162            code.funcstate.release_temp(length_temp)
6163            code.put_decref(target_list, py_object_type)
6164            code.putln('%s = %s; %s = NULL;' % (target_list, sublist_temp, sublist_temp))
6165            code.putln('#else')
6166            code.putln('%s = %s;' % (sublist_temp, sublist_temp)) # avoid warning about unused variable
6167            code.funcstate.release_temp(sublist_temp)
6168            code.putln('#endif')
6169
6170        for i, arg in enumerate(self.args):
6171            arg.generate_assignment_code(self.coerced_unpacked_items[i], code)
6172
6173    def annotate(self, code):
6174        for arg in self.args:
6175            arg.annotate(code)
6176        if self.unpacked_items:
6177            for arg in self.unpacked_items:
6178                arg.annotate(code)
6179            for arg in self.coerced_unpacked_items:
6180                arg.annotate(code)
6181
6182
6183class TupleNode(SequenceNode):
6184    #  Tuple constructor.
6185
6186    type = tuple_type
6187    is_partly_literal = False
6188
6189    gil_message = "Constructing Python tuple"
6190
6191    def analyse_types(self, env, skip_children=False):
6192        if len(self.args) == 0:
6193            node = self
6194            node.is_temp = False
6195            node.is_literal = True
6196        else:
6197            node = SequenceNode.analyse_types(self, env, skip_children)
6198            for child in node.args:
6199                if not child.is_literal:
6200                    break
6201            else:
6202                if not node.mult_factor or node.mult_factor.is_literal and \
6203                       isinstance(node.mult_factor.constant_result, (int, long)):
6204                    node.is_temp = False
6205                    node.is_literal = True
6206                else:
6207                    if not node.mult_factor.type.is_pyobject:
6208                        node.mult_factor = node.mult_factor.coerce_to_pyobject(env)
6209                    node.is_temp = True
6210                    node.is_partly_literal = True
6211        return node
6212
6213    def is_simple(self):
6214        # either temp or constant => always simple
6215        return True
6216
6217    def nonlocally_immutable(self):
6218        # either temp or constant => always safe
6219        return True
6220
6221    def calculate_result_code(self):
6222        if len(self.args) > 0:
6223            return self.result_code
6224        else:
6225            return Naming.empty_tuple
6226
6227    def calculate_constant_result(self):
6228        self.constant_result = tuple([
6229                arg.constant_result for arg in self.args])
6230
6231    def compile_time_value(self, denv):
6232        values = self.compile_time_value_list(denv)
6233        try:
6234            return tuple(values)
6235        except Exception, e:
6236            self.compile_time_value_error(e)
6237
6238    def generate_operation_code(self, code):
6239        if len(self.args) == 0:
6240            # result_code is Naming.empty_tuple
6241            return
6242        if self.is_partly_literal:
6243            # underlying tuple is const, but factor is not
6244            tuple_target = code.get_py_const(py_object_type, 'tuple', cleanup_level=2)
6245            const_code = code.get_cached_constants_writer()
6246            const_code.mark_pos(self.pos)
6247            self.generate_sequence_packing_code(const_code, tuple_target, plain=True)
6248            const_code.put_giveref(tuple_target)
6249            code.putln('%s = PyNumber_Multiply(%s, %s); %s' % (
6250                self.result(), tuple_target, self.mult_factor.py_result(),
6251                code.error_goto_if_null(self.result(), self.pos)
6252                ))
6253            code.put_gotref(self.py_result())
6254        elif self.is_literal:
6255            # non-empty cached tuple => result is global constant,
6256            # creation code goes into separate code writer
6257            self.result_code = code.get_py_const(py_object_type, 'tuple', cleanup_level=2)
6258            code = code.get_cached_constants_writer()
6259            code.mark_pos(self.pos)
6260            self.generate_sequence_packing_code(code)
6261            code.put_giveref(self.py_result())
6262        else:
6263            self.generate_sequence_packing_code(code)
6264
6265
6266class ListNode(SequenceNode):
6267    #  List constructor.
6268
6269    # obj_conversion_errors    [PyrexError]   used internally
6270    # orignial_args            [ExprNode]     used internally
6271
6272    obj_conversion_errors = []
6273    type = list_type
6274    in_module_scope = False
6275
6276    gil_message = "Constructing Python list"
6277
6278    def type_dependencies(self, env):
6279        return ()
6280
6281    def infer_type(self, env):
6282        # TOOD: Infer non-object list arrays.
6283        return list_type
6284
6285    def analyse_expressions(self, env):
6286        node = SequenceNode.analyse_expressions(self, env)
6287        return node.coerce_to_pyobject(env)
6288
6289    def analyse_types(self, env):
6290        hold_errors()
6291        self.original_args = list(self.args)
6292        node = SequenceNode.analyse_types(self, env)
6293        node.obj_conversion_errors = held_errors()
6294        release_errors(ignore=True)
6295        if env.is_module_scope:
6296            self.in_module_scope = True
6297        return node
6298
6299    def coerce_to(self, dst_type, env):
6300        if dst_type.is_pyobject:
6301            for err in self.obj_conversion_errors:
6302                report_error(err)
6303            self.obj_conversion_errors = []
6304            if not self.type.subtype_of(dst_type):
6305                error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
6306        elif self.mult_factor:
6307            error(self.pos, "Cannot coerce multiplied list to '%s'" % dst_type)
6308        elif dst_type.is_ptr and dst_type.base_type is not PyrexTypes.c_void_type:
6309            base_type = dst_type.base_type
6310            self.type = PyrexTypes.CArrayType(base_type, len(self.args))
6311            for i in range(len(self.original_args)):
6312                arg = self.args[i]
6313                if isinstance(arg, CoerceToPyTypeNode):
6314                    arg = arg.arg
6315                self.args[i] = arg.coerce_to(base_type, env)
6316        elif dst_type.is_struct:
6317            if len(self.args) > len(dst_type.scope.var_entries):
6318                error(self.pos, "Too may members for '%s'" % dst_type)
6319            else:
6320                if len(self.args) < len(dst_type.scope.var_entries):
6321                    warning(self.pos, "Too few members for '%s'" % dst_type, 1)
6322                for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
6323                    if isinstance(arg, CoerceToPyTypeNode):
6324                        arg = arg.arg
6325                    self.args[i] = arg.coerce_to(member.type, env)
6326            self.type = dst_type
6327        else:
6328            self.type = error_type
6329            error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
6330        return self
6331
6332    def as_tuple(self):
6333        t = TupleNode(self.pos, args=self.args, mult_factor=self.mult_factor)
6334        if isinstance(self.constant_result, list):
6335            t.constant_result = tuple(self.constant_result)
6336        return t
6337
6338    def allocate_temp_result(self, code):
6339        if self.type.is_array and self.in_module_scope:
6340            self.temp_code = code.funcstate.allocate_temp(
6341                self.type, manage_ref=False, static=True)
6342        else:
6343            SequenceNode.allocate_temp_result(self, code)
6344
6345    def release_temp_result(self, env):
6346        if self.type.is_array:
6347            # To be valid C++, we must allocate the memory on the stack
6348            # manually and be sure not to reuse it for something else.
6349            pass
6350        else:
6351            SequenceNode.release_temp_result(self, env)
6352
6353    def calculate_constant_result(self):
6354        if self.mult_factor:
6355            raise ValueError() # may exceed the compile time memory
6356        self.constant_result = [
6357            arg.constant_result for arg in self.args]
6358
6359    def compile_time_value(self, denv):
6360        l = self.compile_time_value_list(denv)
6361        if self.mult_factor:
6362            l *= self.mult_factor.compile_time_value(denv)
6363        return l
6364
6365    def generate_operation_code(self, code):
6366        if self.type.is_pyobject:
6367            for err in self.obj_conversion_errors:
6368                report_error(err)
6369            self.generate_sequence_packing_code(code)
6370        elif self.type.is_array:
6371            for i, arg in enumerate(self.args):
6372                code.putln("%s[%s] = %s;" % (
6373                                self.result(),
6374                                i,
6375                                arg.result()))
6376        elif self.type.is_struct:
6377            for arg, member in zip(self.args, self.type.scope.var_entries):
6378                code.putln("%s.%s = %s;" % (
6379                        self.result(),
6380                        member.cname,
6381                        arg.result()))
6382        else:
6383            raise InternalError("List type never specified")
6384
6385
6386class ScopedExprNode(ExprNode):
6387    # Abstract base class for ExprNodes that have their own local
6388    # scope, such as generator expressions.
6389    #
6390    # expr_scope    Scope  the inner scope of the expression
6391
6392    subexprs = []
6393    expr_scope = None
6394
6395    # does this node really have a local scope, e.g. does it leak loop
6396    # variables or not?  non-leaking Py3 behaviour is default, except
6397    # for list comprehensions where the behaviour differs in Py2 and
6398    # Py3 (set in Parsing.py based on parser context)
6399    has_local_scope = True
6400
6401    def init_scope(self, outer_scope, expr_scope=None):
6402        if expr_scope is not None:
6403            self.expr_scope = expr_scope
6404        elif self.has_local_scope:
6405            self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
6406        else:
6407            self.expr_scope = None
6408
6409    def analyse_declarations(self, env):
6410        self.init_scope(env)
6411
6412    def analyse_scoped_declarations(self, env):
6413        # this is called with the expr_scope as env
6414        pass
6415
6416    def analyse_types(self, env):
6417        # no recursion here, the children will be analysed separately below
6418        return self
6419
6420    def analyse_scoped_expressions(self, env):
6421        # this is called with the expr_scope as env
6422        return self
6423
6424    def generate_evaluation_code(self, code):
6425        # set up local variables and free their references on exit
6426        generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
6427        if not self.has_local_scope or not self.expr_scope.var_entries:
6428            # no local variables => delegate, done
6429            generate_inner_evaluation_code(code)
6430            return
6431
6432        code.putln('{ /* enter inner scope */')
6433        py_entries = []
6434        for entry in self.expr_scope.var_entries:
6435            if not entry.in_closure:
6436                code.put_var_declaration(entry)
6437                if entry.type.is_pyobject and entry.used:
6438                    py_entries.append(entry)
6439        if not py_entries:
6440            # no local Python references => no cleanup required
6441            generate_inner_evaluation_code(code)
6442            code.putln('} /* exit inner scope */')
6443            return
6444
6445        # must free all local Python references at each exit point
6446        old_loop_labels = tuple(code.new_loop_labels())
6447        old_error_label = code.new_error_label()
6448
6449        generate_inner_evaluation_code(code)
6450
6451        # normal (non-error) exit
6452        for entry in py_entries:
6453            code.put_var_decref(entry)
6454
6455        # error/loop body exit points
6456        exit_scope = code.new_label('exit_scope')
6457        code.put_goto(exit_scope)
6458        for label, old_label in ([(code.error_label, old_error_label)] +
6459                                 list(zip(code.get_loop_labels(), old_loop_labels))):
6460            if code.label_used(label):
6461                code.put_label(label)
6462                for entry in py_entries:
6463                    code.put_var_decref(entry)
6464                code.put_goto(old_label)
6465        code.put_label(exit_scope)
6466        code.putln('} /* exit inner scope */')
6467
6468        code.set_loop_labels(old_loop_labels)
6469        code.error_label = old_error_label
6470
6471
6472class ComprehensionNode(ScopedExprNode):
6473    # A list/set/dict comprehension
6474
6475    child_attrs = ["loop"]
6476
6477    is_temp = True
6478
6479    def infer_type(self, env):
6480        return self.type
6481
6482    def analyse_declarations(self, env):
6483        self.append.target = self # this is used in the PyList_Append of the inner loop
6484        self.init_scope(env)
6485
6486    def analyse_scoped_declarations(self, env):
6487        self.loop.analyse_declarations(env)
6488
6489    def analyse_types(self, env):
6490        if not self.has_local_scope:
6491            self.loop = self.loop.analyse_expressions(env)
6492        return self
6493
6494    def analyse_scoped_expressions(self, env):
6495        if self.has_local_scope:
6496            self.loop = self.loop.analyse_expressions(env)
6497        return self
6498
6499    def may_be_none(self):
6500        return False
6501
6502    def generate_result_code(self, code):
6503        self.generate_operation_code(code)
6504
6505    def generate_operation_code(self, code):
6506        if self.type is Builtin.list_type:
6507            create_code = 'PyList_New(0)'
6508        elif self.type is Builtin.set_type:
6509            create_code = 'PySet_New(NULL)'
6510        elif self.type is Builtin.dict_type:
6511            create_code = 'PyDict_New()'
6512        else:
6513            raise InternalError("illegal type for comprehension: %s" % self.type)
6514        code.putln('%s = %s; %s' % (
6515            self.result(), create_code,
6516            code.error_goto_if_null(self.result(), self.pos)))
6517
6518        code.put_gotref(self.result())
6519        self.loop.generate_execution_code(code)
6520
6521    def annotate(self, code):
6522        self.loop.annotate(code)
6523
6524
6525class ComprehensionAppendNode(Node):
6526    # Need to be careful to avoid infinite recursion:
6527    # target must not be in child_attrs/subexprs
6528
6529    child_attrs = ['expr']
6530    target = None
6531
6532    type = PyrexTypes.c_int_type
6533
6534    def analyse_expressions(self, env):
6535        self.expr = self.expr.analyse_expressions(env)
6536        if not self.expr.type.is_pyobject:
6537            self.expr = self.expr.coerce_to_pyobject(env)
6538        return self
6539
6540    def generate_execution_code(self, code):
6541        if self.target.type is list_type:
6542            code.globalstate.use_utility_code(
6543                UtilityCode.load_cached("ListCompAppend", "Optimize.c"))
6544            function = "__Pyx_ListComp_Append"
6545        elif self.target.type is set_type:
6546            function = "PySet_Add"
6547        else:
6548            raise InternalError(
6549                "Invalid type for comprehension node: %s" % self.target.type)
6550
6551        self.expr.generate_evaluation_code(code)
6552        code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
6553            function,
6554            self.target.result(),
6555            self.expr.result()
6556            ), self.pos))
6557        self.expr.generate_disposal_code(code)
6558        self.expr.free_temps(code)
6559
6560    def generate_function_definitions(self, env, code):
6561        self.expr.generate_function_definitions(env, code)
6562
6563    def annotate(self, code):
6564        self.expr.annotate(code)
6565
6566class DictComprehensionAppendNode(ComprehensionAppendNode):
6567    child_attrs = ['key_expr', 'value_expr']
6568
6569    def analyse_expressions(self, env):
6570        self.key_expr = self.key_expr.analyse_expressions(env)
6571        if not self.key_expr.type.is_pyobject:
6572            self.key_expr = self.key_expr.coerce_to_pyobject(env)
6573        self.value_expr = self.value_expr.analyse_expressions(env)
6574        if not self.value_expr.type.is_pyobject:
6575            self.value_expr = self.value_expr.coerce_to_pyobject(env)
6576        return self
6577
6578    def generate_execution_code(self, code):
6579        self.key_expr.generate_evaluation_code(code)
6580        self.value_expr.generate_evaluation_code(code)
6581        code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
6582            self.target.result(),
6583            self.key_expr.result(),
6584            self.value_expr.result()
6585            ), self.pos))
6586        self.key_expr.generate_disposal_code(code)
6587        self.key_expr.free_temps(code)
6588        self.value_expr.generate_disposal_code(code)
6589        self.value_expr.free_temps(code)
6590
6591    def generate_function_definitions(self, env, code):
6592        self.key_expr.generate_function_definitions(env, code)
6593        self.value_expr.generate_function_definitions(env, code)
6594
6595    def annotate(self, code):
6596        self.key_expr.annotate(code)
6597        self.value_expr.annotate(code)
6598
6599
6600class InlinedGeneratorExpressionNode(ScopedExprNode):
6601    # An inlined generator expression for which the result is
6602    # calculated inside of the loop.  This will only be created by
6603    # transforms when replacing builtin calls on generator
6604    # expressions.
6605    #
6606    # loop           ForStatNode      the for-loop, not containing any YieldExprNodes
6607    # result_node    ResultRefNode    the reference to the result value temp
6608    # orig_func      String           the name of the builtin function this node replaces
6609
6610    child_attrs = ["loop"]
6611    loop_analysed = False
6612    type = py_object_type
6613
6614    def analyse_scoped_declarations(self, env):
6615        self.loop.analyse_declarations(env)
6616
6617    def may_be_none(self):
6618        return False
6619
6620    def annotate(self, code):
6621        self.loop.annotate(code)
6622
6623    def infer_type(self, env):
6624        return self.result_node.infer_type(env)
6625
6626    def analyse_types(self, env):
6627        if not self.has_local_scope:
6628            self.loop_analysed = True
6629            self.loop = self.loop.analyse_expressions(env)
6630        self.type = self.result_node.type
6631        self.is_temp = True
6632        return self
6633
6634    def analyse_scoped_expressions(self, env):
6635        self.loop_analysed = True
6636        if self.has_local_scope:
6637            self.loop = self.loop.analyse_expressions(env)
6638        return self
6639
6640    def coerce_to(self, dst_type, env):
6641        if self.orig_func == 'sum' and dst_type.is_numeric and not self.loop_analysed:
6642            # We can optimise by dropping the aggregation variable and
6643            # the add operations into C.  This can only be done safely
6644            # before analysing the loop body, after that, the result
6645            # reference type will have infected expressions and
6646            # assignments.
6647            self.result_node.type = self.type = dst_type
6648            return self
6649        return super(InlinedGeneratorExpressionNode, self).coerce_to(dst_type, env)
6650
6651    def generate_result_code(self, code):
6652        self.result_node.result_code = self.result()
6653        self.loop.generate_execution_code(code)
6654
6655
6656class SetNode(ExprNode):
6657    #  Set constructor.
6658
6659    type = set_type
6660
6661    subexprs = ['args']
6662
6663    gil_message = "Constructing Python set"
6664
6665    def analyse_types(self, env):
6666        for i in range(len(self.args)):
6667            arg = self.args[i]
6668            arg = arg.analyse_types(env)
6669            self.args[i] = arg.coerce_to_pyobject(env)
6670        self.type = set_type
6671        self.is_temp = 1
6672        return self
6673
6674    def may_be_none(self):
6675        return False
6676
6677    def calculate_constant_result(self):
6678        self.constant_result = set([
6679                arg.constant_result for arg in self.args])
6680
6681    def compile_time_value(self, denv):
6682        values = [arg.compile_time_value(denv) for arg in self.args]
6683        try:
6684            return set(values)
6685        except Exception, e:
6686            self.compile_time_value_error(e)
6687
6688    def generate_evaluation_code(self, code):
6689        code.globalstate.use_utility_code(Builtin.py_set_utility_code)
6690        self.allocate_temp_result(code)
6691        code.putln(
6692            "%s = PySet_New(0); %s" % (
6693                self.result(),
6694                code.error_goto_if_null(self.result(), self.pos)))
6695        code.put_gotref(self.py_result())
6696        for arg in self.args:
6697            arg.generate_evaluation_code(code)
6698            code.put_error_if_neg(
6699                self.pos,
6700                "PySet_Add(%s, %s)" % (self.result(), arg.py_result()))
6701            arg.generate_disposal_code(code)
6702            arg.free_temps(code)
6703
6704
6705class DictNode(ExprNode):
6706    #  Dictionary constructor.
6707    #
6708    #  key_value_pairs     [DictItemNode]
6709    #  exclude_null_values [boolean]          Do not add NULL values to dict
6710    #
6711    # obj_conversion_errors    [PyrexError]   used internally
6712
6713    subexprs = ['key_value_pairs']
6714    is_temp = 1
6715    exclude_null_values = False
6716    type = dict_type
6717
6718    obj_conversion_errors = []
6719
6720    @classmethod
6721    def from_pairs(cls, pos, pairs):
6722        return cls(pos, key_value_pairs=[
6723                DictItemNode(pos, key=k, value=v) for k, v in pairs])
6724
6725    def calculate_constant_result(self):
6726        self.constant_result = dict([
6727                item.constant_result for item in self.key_value_pairs])
6728
6729    def compile_time_value(self, denv):
6730        pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
6731            for item in self.key_value_pairs]
6732        try:
6733            return dict(pairs)
6734        except Exception, e:
6735            self.compile_time_value_error(e)
6736
6737    def type_dependencies(self, env):
6738        return ()
6739
6740    def infer_type(self, env):
6741        # TOOD: Infer struct constructors.
6742        return dict_type
6743
6744    def analyse_types(self, env):
6745        hold_errors()
6746        self.key_value_pairs = [ item.analyse_types(env)
6747                                 for item in self.key_value_pairs ]
6748        self.obj_conversion_errors = held_errors()
6749        release_errors(ignore=True)
6750        return self
6751
6752    def may_be_none(self):
6753        return False
6754
6755    def coerce_to(self, dst_type, env):
6756        if dst_type.is_pyobject:
6757            self.release_errors()
6758            if not self.type.subtype_of(dst_type):
6759                error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
6760        elif dst_type.is_struct_or_union:
6761            self.type = dst_type
6762            if not dst_type.is_struct and len(self.key_value_pairs) != 1:
6763                error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
6764            elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
6765                warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
6766            for item in self.key_value_pairs:
6767                if isinstance(item.key, CoerceToPyTypeNode):
6768                    item.key = item.key.arg
6769                if not item.key.is_string_literal:
6770                    error(item.key.pos, "Invalid struct field identifier")
6771                    item.key = StringNode(item.key.pos, value="<error>")
6772                else:
6773                    key = str(item.key.value) # converts string literals to unicode in Py3
6774                    member = dst_type.scope.lookup_here(key)
6775                    if not member:
6776                        error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
6777                    else:
6778                        value = item.value
6779                        if isinstance(value, CoerceToPyTypeNode):
6780                            value = value.arg
6781                        item.value = value.coerce_to(member.type, env)
6782        else:
6783            self.type = error_type
6784            error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
6785        return self
6786
6787    def release_errors(self):
6788        for err in self.obj_conversion_errors:
6789            report_error(err)
6790        self.obj_conversion_errors = []
6791
6792    gil_message = "Constructing Python dict"
6793
6794    def generate_evaluation_code(self, code):
6795        #  Custom method used here because key-value
6796        #  pairs are evaluated and used one at a time.
6797        code.mark_pos(self.pos)
6798        self.allocate_temp_result(code)
6799        if self.type.is_pyobject:
6800            self.release_errors()
6801            code.putln(
6802                "%s = PyDict_New(); %s" % (
6803                    self.result(),
6804                    code.error_goto_if_null(self.result(), self.pos)))
6805            code.put_gotref(self.py_result())
6806        for item in self.key_value_pairs:
6807            item.generate_evaluation_code(code)
6808            if self.type.is_pyobject:
6809                if self.exclude_null_values:
6810                    code.putln('if (%s) {' % item.value.py_result())
6811                code.put_error_if_neg(self.pos,
6812                    "PyDict_SetItem(%s, %s, %s)" % (
6813                        self.result(),
6814                        item.key.py_result(),
6815                        item.value.py_result()))
6816                if self.exclude_null_values:
6817                    code.putln('}')
6818            else:
6819                code.putln("%s.%s = %s;" % (
6820                        self.result(),
6821                        item.key.value,
6822                        item.value.result()))
6823            item.generate_disposal_code(code)
6824            item.free_temps(code)
6825
6826    def annotate(self, code):
6827        for item in self.key_value_pairs:
6828            item.annotate(code)
6829
6830class DictItemNode(ExprNode):
6831    # Represents a single item in a DictNode
6832    #
6833    # key          ExprNode
6834    # value        ExprNode
6835    subexprs = ['key', 'value']
6836
6837    nogil_check = None # Parent DictNode takes care of it
6838
6839    def calculate_constant_result(self):
6840        self.constant_result = (
6841            self.key.constant_result, self.value.constant_result)
6842
6843    def analyse_types(self, env):
6844        self.key = self.key.analyse_types(env)
6845        self.value = self.value.analyse_types(env)
6846        self.key = self.key.coerce_to_pyobject(env)
6847        self.value = self.value.coerce_to_pyobject(env)
6848        return self
6849
6850    def generate_evaluation_code(self, code):
6851        self.key.generate_evaluation_code(code)
6852        self.value.generate_evaluation_code(code)
6853
6854    def generate_disposal_code(self, code):
6855        self.key.generate_disposal_code(code)
6856        self.value.generate_disposal_code(code)
6857
6858    def free_temps(self, code):
6859        self.key.free_temps(code)
6860        self.value.free_temps(code)
6861
6862    def __iter__(self):
6863        return iter([self.key, self.value])
6864
6865
6866class SortedDictKeysNode(ExprNode):
6867    # build sorted list of dict keys, e.g. for dir()
6868    subexprs = ['arg']
6869
6870    is_temp = True
6871
6872    def __init__(self, arg):
6873        ExprNode.__init__(self, arg.pos, arg=arg)
6874        self.type = Builtin.list_type
6875
6876    def analyse_types(self, env):
6877        arg = self.arg.analyse_types(env)
6878        if arg.type is Builtin.dict_type:
6879            arg = arg.as_none_safe_node(
6880                "'NoneType' object is not iterable")
6881        self.arg = arg
6882        return self
6883
6884    def may_be_none(self):
6885        return False
6886
6887    def generate_result_code(self, code):
6888        dict_result = self.arg.py_result()
6889        if self.arg.type is Builtin.dict_type:
6890            function = 'PyDict_Keys'
6891        else:
6892            function = 'PyMapping_Keys'
6893        code.putln('%s = %s(%s); %s' % (
6894            self.result(), function, dict_result,
6895            code.error_goto_if_null(self.result(), self.pos)))
6896        code.put_gotref(self.py_result())
6897        code.put_error_if_neg(
6898            self.pos, 'PyList_Sort(%s)' % self.py_result())
6899
6900
6901class ModuleNameMixin(object):
6902    def get_py_mod_name(self, code):
6903        return code.get_py_string_const(
6904            self.module_name, identifier=True)
6905
6906    def get_py_qualified_name(self, code):
6907        return code.get_py_string_const(
6908            self.qualname, identifier=True)
6909
6910
6911class ClassNode(ExprNode, ModuleNameMixin):
6912    #  Helper class used in the implementation of Python
6913    #  class definitions. Constructs a class object given
6914    #  a name, tuple of bases and class dictionary.
6915    #
6916    #  name         EncodedString      Name of the class
6917    #  bases        ExprNode           Base class tuple
6918    #  dict         ExprNode           Class dict (not owned by this node)
6919    #  doc          ExprNode or None   Doc string
6920    #  module_name  EncodedString      Name of defining module
6921
6922    subexprs = ['bases', 'doc']
6923
6924    def analyse_types(self, env):
6925        self.bases = self.bases.analyse_types(env)
6926        if self.doc:
6927            self.doc = self.doc.analyse_types(env)
6928            self.doc = self.doc.coerce_to_pyobject(env)
6929        self.type = py_object_type
6930        self.is_temp = 1
6931        env.use_utility_code(UtilityCode.load_cached("CreateClass", "ObjectHandling.c"))
6932        return self
6933
6934    def may_be_none(self):
6935        return True
6936
6937    gil_message = "Constructing Python class"
6938
6939    def generate_result_code(self, code):
6940        cname = code.intern_identifier(self.name)
6941
6942        if self.doc:
6943            code.put_error_if_neg(self.pos,
6944                'PyDict_SetItem(%s, %s, %s)' % (
6945                    self.dict.py_result(),
6946                    code.intern_identifier(
6947                        StringEncoding.EncodedString("__doc__")),
6948                    self.doc.py_result()))
6949        py_mod_name = self.get_py_mod_name(code)
6950        qualname = self.get_py_qualified_name(code)
6951        code.putln(
6952            '%s = __Pyx_CreateClass(%s, %s, %s, %s, %s); %s' % (
6953                self.result(),
6954                self.bases.py_result(),
6955                self.dict.py_result(),
6956                cname,
6957                qualname,
6958                py_mod_name,
6959                code.error_goto_if_null(self.result(), self.pos)))
6960        code.put_gotref(self.py_result())
6961
6962
6963class Py3ClassNode(ExprNode):
6964    #  Helper class used in the implementation of Python3+
6965    #  class definitions. Constructs a class object given
6966    #  a name, tuple of bases and class dictionary.
6967    #
6968    #  name         EncodedString      Name of the class
6969    #  dict         ExprNode           Class dict (not owned by this node)
6970    #  module_name  EncodedString      Name of defining module
6971    #  calculate_metaclass  bool       should call CalculateMetaclass()
6972    #  allow_py2_metaclass  bool       should look for Py2 metaclass
6973
6974    subexprs = []
6975
6976    def analyse_types(self, env):
6977        self.type = py_object_type
6978        self.is_temp = 1
6979        return self
6980
6981    def may_be_none(self):
6982        return True
6983
6984    gil_message = "Constructing Python class"
6985
6986    def generate_result_code(self, code):
6987        code.globalstate.use_utility_code(UtilityCode.load_cached("Py3ClassCreate", "ObjectHandling.c"))
6988        cname = code.intern_identifier(self.name)
6989        if self.mkw:
6990            mkw = self.mkw.py_result()
6991        else:
6992            mkw = 'NULL'
6993        if self.metaclass:
6994            metaclass = self.metaclass.result()
6995        else:
6996            metaclass = "((PyObject*)&__Pyx_DefaultClassType)"
6997        code.putln(
6998            '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s, %d, %d); %s' % (
6999                self.result(),
7000                metaclass,
7001                cname,
7002                self.bases.py_result(),
7003                self.dict.py_result(),
7004                mkw,
7005                self.calculate_metaclass,
7006                self.allow_py2_metaclass,
7007                code.error_goto_if_null(self.result(), self.pos)))
7008        code.put_gotref(self.py_result())
7009
7010class KeywordArgsNode(ExprNode):
7011    #  Helper class for keyword arguments.
7012    #
7013    #  starstar_arg      DictNode
7014    #  keyword_args      [DictItemNode]
7015
7016    subexprs = ['starstar_arg', 'keyword_args']
7017    is_temp = 1
7018    type = dict_type
7019
7020    def calculate_constant_result(self):
7021        result = dict(self.starstar_arg.constant_result)
7022        for item in self.keyword_args:
7023            key, value = item.constant_result
7024            if key in result:
7025                raise ValueError("duplicate keyword argument found: %s" % key)
7026            result[key] = value
7027        self.constant_result = result
7028
7029    def compile_time_value(self, denv):
7030        result = self.starstar_arg.compile_time_value(denv)
7031        pairs = [ (item.key.compile_time_value(denv), item.value.compile_time_value(denv))
7032                  for item in self.keyword_args ]
7033        try:
7034            result = dict(result)
7035            for key, value in pairs:
7036                if key in result:
7037                    raise ValueError("duplicate keyword argument found: %s" % key)
7038                result[key] = value
7039        except Exception, e:
7040            self.compile_time_value_error(e)
7041        return result
7042
7043    def type_dependencies(self, env):
7044        return ()
7045
7046    def infer_type(self, env):
7047        return dict_type
7048
7049    def analyse_types(self, env):
7050        arg = self.starstar_arg.analyse_types(env)
7051        arg = arg.coerce_to_pyobject(env)
7052        self.starstar_arg = arg.as_none_safe_node(
7053            # FIXME: CPython's error message starts with the runtime function name
7054            'argument after ** must be a mapping, not NoneType')
7055        self.keyword_args = [ item.analyse_types(env)
7056                              for item in self.keyword_args ]
7057        return self
7058
7059    def may_be_none(self):
7060        return False
7061
7062    gil_message = "Constructing Python dict"
7063
7064    def generate_evaluation_code(self, code):
7065        code.mark_pos(self.pos)
7066        self.allocate_temp_result(code)
7067        self.starstar_arg.generate_evaluation_code(code)
7068        if self.starstar_arg.type is not Builtin.dict_type:
7069            # CPython supports calling functions with non-dicts, so do we
7070            code.putln('if (likely(PyDict_Check(%s))) {' %
7071                       self.starstar_arg.py_result())
7072        if self.keyword_args:
7073            code.putln(
7074                "%s = PyDict_Copy(%s); %s" % (
7075                    self.result(),
7076                    self.starstar_arg.py_result(),
7077                    code.error_goto_if_null(self.result(), self.pos)))
7078            code.put_gotref(self.py_result())
7079        else:
7080            code.putln("%s = %s;" % (
7081                self.result(),
7082                self.starstar_arg.py_result()))
7083            code.put_incref(self.result(), py_object_type)
7084        if self.starstar_arg.type is not Builtin.dict_type:
7085            code.putln('} else {')
7086            code.putln(
7087                "%s = PyObject_CallFunctionObjArgs("
7088                "(PyObject*)&PyDict_Type, %s, NULL); %s" % (
7089                    self.result(),
7090                    self.starstar_arg.py_result(),
7091                    code.error_goto_if_null(self.result(), self.pos)))
7092            code.put_gotref(self.py_result())
7093            code.putln('}')
7094        self.starstar_arg.generate_disposal_code(code)
7095        self.starstar_arg.free_temps(code)
7096
7097        if not self.keyword_args:
7098            return
7099
7100        code.globalstate.use_utility_code(
7101            UtilityCode.load_cached("RaiseDoubleKeywords", "FunctionArguments.c"))
7102        for item in self.keyword_args:
7103            item.generate_evaluation_code(code)
7104            code.putln("if (unlikely(PyDict_GetItem(%s, %s))) {" % (
7105                    self.result(),
7106                    item.key.py_result()))
7107            # FIXME: find out function name at runtime!
7108            code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
7109                item.key.py_result(),
7110                code.error_goto(self.pos)))
7111            code.putln("}")
7112            code.put_error_if_neg(self.pos,
7113                "PyDict_SetItem(%s, %s, %s)" % (
7114                    self.result(),
7115                    item.key.py_result(),
7116                    item.value.py_result()))
7117            item.generate_disposal_code(code)
7118            item.free_temps(code)
7119
7120    def annotate(self, code):
7121        self.starstar_arg.annotate(code)
7122        for item in self.keyword_args:
7123            item.annotate(code)
7124
7125class PyClassMetaclassNode(ExprNode):
7126    # Helper class holds Python3 metaclass object
7127    #
7128    #  bases        ExprNode           Base class tuple (not owned by this node)
7129    #  mkw          ExprNode           Class keyword arguments (not owned by this node)
7130
7131    subexprs = []
7132
7133    def analyse_types(self, env):
7134        self.type = py_object_type
7135        self.is_temp = True
7136        return self
7137
7138    def may_be_none(self):
7139        return True
7140
7141    def generate_result_code(self, code):
7142        if self.mkw:
7143            code.globalstate.use_utility_code(
7144                UtilityCode.load_cached("Py3MetaclassGet", "ObjectHandling.c"))
7145            call = "__Pyx_Py3MetaclassGet(%s, %s)" % (
7146                self.bases.result(),
7147                self.mkw.result())
7148        else:
7149            code.globalstate.use_utility_code(
7150                UtilityCode.load_cached("CalculateMetaclass", "ObjectHandling.c"))
7151            call = "__Pyx_CalculateMetaclass(NULL, %s)" % (
7152                self.bases.result())
7153        code.putln(
7154            "%s = %s; %s" % (
7155                self.result(), call,
7156                code.error_goto_if_null(self.result(), self.pos)))
7157        code.put_gotref(self.py_result())
7158
7159class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
7160    # Helper class holds Python3 namespace object
7161    #
7162    # All this are not owned by this node
7163    #  metaclass    ExprNode           Metaclass object
7164    #  bases        ExprNode           Base class tuple
7165    #  mkw          ExprNode           Class keyword arguments
7166    #  doc          ExprNode or None   Doc string (owned)
7167
7168    subexprs = ['doc']
7169
7170    def analyse_types(self, env):
7171        if self.doc:
7172            self.doc = self.doc.analyse_types(env)
7173            self.doc = self.doc.coerce_to_pyobject(env)
7174        self.type = py_object_type
7175        self.is_temp = 1
7176        return self
7177
7178    def may_be_none(self):
7179        return True
7180
7181    def generate_result_code(self, code):
7182        cname = code.intern_identifier(self.name)
7183        py_mod_name = self.get_py_mod_name(code)
7184        qualname = self.get_py_qualified_name(code)
7185        if self.doc:
7186            doc_code = self.doc.result()
7187        else:
7188            doc_code = '(PyObject *) NULL'
7189        if self.mkw:
7190            mkw = self.mkw.py_result()
7191        else:
7192            mkw = '(PyObject *) NULL'
7193        if self.metaclass:
7194            metaclass = self.metaclass.result()
7195        else:
7196            metaclass = "(PyObject *) NULL"
7197        code.putln(
7198            "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s, %s); %s" % (
7199                self.result(),
7200                metaclass,
7201                self.bases.result(),
7202                cname,
7203                qualname,
7204                mkw,
7205                py_mod_name,
7206                doc_code,
7207                code.error_goto_if_null(self.result(), self.pos)))
7208        code.put_gotref(self.py_result())
7209
7210
7211class ClassCellInjectorNode(ExprNode):
7212    # Initialize CyFunction.func_classobj
7213    is_temp = True
7214    type = py_object_type
7215    subexprs = []
7216    is_active = False
7217
7218    def analyse_expressions(self, env):
7219        if self.is_active:
7220            env.use_utility_code(
7221                UtilityCode.load_cached("CyFunctionClassCell", "CythonFunction.c"))
7222        return self
7223
7224    def generate_evaluation_code(self, code):
7225        if self.is_active:
7226            self.allocate_temp_result(code)
7227            code.putln(
7228                '%s = PyList_New(0); %s' % (
7229                    self.result(),
7230                    code.error_goto_if_null(self.result(), self.pos)))
7231            code.put_gotref(self.result())
7232
7233    def generate_injection_code(self, code, classobj_cname):
7234        if self.is_active:
7235            code.putln('__Pyx_CyFunction_InitClassCell(%s, %s);' % (
7236                self.result(), classobj_cname))
7237
7238
7239class ClassCellNode(ExprNode):
7240    # Class Cell for noargs super()
7241    subexprs = []
7242    is_temp = True
7243    is_generator = False
7244    type = py_object_type
7245
7246    def analyse_types(self, env):
7247        return self
7248
7249    def generate_result_code(self, code):
7250        if not self.is_generator:
7251            code.putln('%s = __Pyx_CyFunction_GetClassObj(%s);' % (
7252                self.result(),
7253                Naming.self_cname))
7254        else:
7255            code.putln('%s =  %s->classobj;' % (
7256                self.result(), Naming.generator_cname))
7257        code.putln(
7258            'if (!%s) { PyErr_SetString(PyExc_SystemError, '
7259            '"super(): empty __class__ cell"); %s }' % (
7260                self.result(),
7261                code.error_goto(self.pos)))
7262        code.put_incref(self.result(), py_object_type)
7263
7264
7265class BoundMethodNode(ExprNode):
7266    #  Helper class used in the implementation of Python
7267    #  class definitions. Constructs an bound method
7268    #  object from a class and a function.
7269    #
7270    #  function      ExprNode   Function object
7271    #  self_object   ExprNode   self object
7272
7273    subexprs = ['function']
7274
7275    def analyse_types(self, env):
7276        self.function = self.function.analyse_types(env)
7277        self.type = py_object_type
7278        self.is_temp = 1
7279        return self
7280
7281    gil_message = "Constructing a bound method"
7282
7283    def generate_result_code(self, code):
7284        code.putln(
7285            "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
7286                self.result(),
7287                self.function.py_result(),
7288                self.self_object.py_result(),
7289                self.self_object.py_result(),
7290                code.error_goto_if_null(self.result(), self.pos)))
7291        code.put_gotref(self.py_result())
7292
7293class UnboundMethodNode(ExprNode):
7294    #  Helper class used in the implementation of Python
7295    #  class definitions. Constructs an unbound method
7296    #  object from a class and a function.
7297    #
7298    #  function      ExprNode   Function object
7299
7300    type = py_object_type
7301    is_temp = 1
7302
7303    subexprs = ['function']
7304
7305    def analyse_types(self, env):
7306        self.function = self.function.analyse_types(env)
7307        return self
7308
7309    def may_be_none(self):
7310        return False
7311
7312    gil_message = "Constructing an unbound method"
7313
7314    def generate_result_code(self, code):
7315        class_cname = code.pyclass_stack[-1].classobj.result()
7316        code.putln(
7317            "%s = PyMethod_New(%s, 0, %s); %s" % (
7318                self.result(),
7319                self.function.py_result(),
7320                class_cname,
7321                code.error_goto_if_null(self.result(), self.pos)))
7322        code.put_gotref(self.py_result())
7323
7324
7325class PyCFunctionNode(ExprNode, ModuleNameMixin):
7326    #  Helper class used in the implementation of Python
7327    #  functions.  Constructs a PyCFunction object
7328    #  from a PyMethodDef struct.
7329    #
7330    #  pymethdef_cname   string             PyMethodDef structure
7331    #  self_object       ExprNode or None
7332    #  binding           bool
7333    #  def_node          DefNode            the Python function node
7334    #  module_name       EncodedString      Name of defining module
7335    #  code_object       CodeObjectNode     the PyCodeObject creator node
7336
7337    subexprs = ['code_object', 'defaults_tuple', 'defaults_kwdict',
7338                'annotations_dict']
7339
7340    self_object = None
7341    code_object = None
7342    binding = False
7343    def_node = None
7344    defaults = None
7345    defaults_struct = None
7346    defaults_pyobjects = 0
7347    defaults_tuple = None
7348    defaults_kwdict = None
7349    annotations_dict = None
7350
7351    type = py_object_type
7352    is_temp = 1
7353
7354    specialized_cpdefs = None
7355    is_specialization = False
7356
7357    @classmethod
7358    def from_defnode(cls, node, binding):
7359        return cls(node.pos,
7360                   def_node=node,
7361                   pymethdef_cname=node.entry.pymethdef_cname,
7362                   binding=binding or node.specialized_cpdefs,
7363                   specialized_cpdefs=node.specialized_cpdefs,
7364                   code_object=CodeObjectNode(node))
7365
7366    def analyse_types(self, env):
7367        if self.binding:
7368            self.analyse_default_args(env)
7369        return self
7370
7371    def analyse_default_args(self, env):
7372        """
7373        Handle non-literal function's default arguments.
7374        """
7375        nonliteral_objects = []
7376        nonliteral_other = []
7377        default_args = []
7378        default_kwargs = []
7379        annotations = []
7380        for arg in self.def_node.args:
7381            if arg.default:
7382                if not arg.default.is_literal:
7383                    arg.is_dynamic = True
7384                    if arg.type.is_pyobject:
7385                        nonliteral_objects.append(arg)
7386                    else:
7387                        nonliteral_other.append(arg)
7388                else:
7389                    arg.default = DefaultLiteralArgNode(arg.pos, arg.default)
7390                if arg.kw_only:
7391                    default_kwargs.append(arg)
7392                else:
7393                    default_args.append(arg)
7394            if arg.annotation:
7395                arg.annotation = arg.annotation.analyse_types(env)
7396                if not arg.annotation.type.is_pyobject:
7397                    arg.annotation = arg.annotation.coerce_to_pyobject(env)
7398                annotations.append((arg.pos, arg.name, arg.annotation))
7399        if self.def_node.return_type_annotation:
7400            annotations.append((self.def_node.return_type_annotation.pos,
7401                                StringEncoding.EncodedString("return"),
7402                                self.def_node.return_type_annotation))
7403
7404        if nonliteral_objects or nonliteral_other:
7405            module_scope = env.global_scope()
7406            cname = module_scope.next_id(Naming.defaults_struct_prefix)
7407            scope = Symtab.StructOrUnionScope(cname)
7408            self.defaults = []
7409            for arg in nonliteral_objects:
7410                entry = scope.declare_var(arg.name, arg.type, None,
7411                                          Naming.arg_prefix + arg.name,
7412                                          allow_pyobject=True)
7413                self.defaults.append((arg, entry))
7414            for arg in nonliteral_other:
7415                entry = scope.declare_var(arg.name, arg.type, None,
7416                                          Naming.arg_prefix + arg.name,
7417                                          allow_pyobject=False)
7418                self.defaults.append((arg, entry))
7419            entry = module_scope.declare_struct_or_union(
7420                None, 'struct', scope, 1, None, cname=cname)
7421            self.defaults_struct = scope
7422            self.defaults_pyobjects = len(nonliteral_objects)
7423            for arg, entry in self.defaults:
7424                arg.default_value = '%s->%s' % (
7425                    Naming.dynamic_args_cname, entry.cname)
7426            self.def_node.defaults_struct = self.defaults_struct.name
7427
7428        if default_args or default_kwargs:
7429            if self.defaults_struct is None:
7430                if default_args:
7431                    defaults_tuple = TupleNode(self.pos, args=[
7432                        arg.default for arg in default_args])
7433                    self.defaults_tuple = defaults_tuple.analyse_types(env)
7434                if default_kwargs:
7435                    defaults_kwdict = DictNode(self.pos, key_value_pairs=[
7436                        DictItemNode(
7437                            arg.pos,
7438                            key=IdentifierStringNode(arg.pos, value=arg.name),
7439                            value=arg.default)
7440                        for arg in default_kwargs])
7441                    self.defaults_kwdict = defaults_kwdict.analyse_types(env)
7442            else:
7443                if default_args:
7444                    defaults_tuple = DefaultsTupleNode(
7445                        self.pos, default_args, self.defaults_struct)
7446                else:
7447                    defaults_tuple = NoneNode(self.pos)
7448                if default_kwargs:
7449                    defaults_kwdict = DefaultsKwDictNode(
7450                        self.pos, default_kwargs, self.defaults_struct)
7451                else:
7452                    defaults_kwdict = NoneNode(self.pos)
7453
7454                defaults_getter = Nodes.DefNode(
7455                    self.pos, args=[], star_arg=None, starstar_arg=None,
7456                    body=Nodes.ReturnStatNode(
7457                        self.pos, return_type=py_object_type,
7458                        value=TupleNode(
7459                            self.pos, args=[defaults_tuple, defaults_kwdict])),
7460                    decorators=None,
7461                    name=StringEncoding.EncodedString("__defaults__"))
7462                defaults_getter.analyse_declarations(env)
7463                defaults_getter = defaults_getter.analyse_expressions(env)
7464                defaults_getter.body = defaults_getter.body.analyse_expressions(
7465                    defaults_getter.local_scope)
7466                defaults_getter.py_wrapper_required = False
7467                defaults_getter.pymethdef_required = False
7468                self.def_node.defaults_getter = defaults_getter
7469        if annotations:
7470            annotations_dict = DictNode(self.pos, key_value_pairs=[
7471                DictItemNode(
7472                    pos, key=IdentifierStringNode(pos, value=name),
7473                    value=value)
7474                for pos, name, value in annotations])
7475            self.annotations_dict = annotations_dict.analyse_types(env)
7476
7477    def may_be_none(self):
7478        return False
7479
7480    gil_message = "Constructing Python function"
7481
7482    def self_result_code(self):
7483        if self.self_object is None:
7484            self_result = "NULL"
7485        else:
7486            self_result = self.self_object.py_result()
7487        return self_result
7488
7489    def generate_result_code(self, code):
7490        if self.binding:
7491            self.generate_cyfunction_code(code)
7492        else:
7493            self.generate_pycfunction_code(code)
7494
7495    def generate_pycfunction_code(self, code):
7496        py_mod_name = self.get_py_mod_name(code)
7497        code.putln(
7498            '%s = PyCFunction_NewEx(&%s, %s, %s); %s' % (
7499                self.result(),
7500                self.pymethdef_cname,
7501                self.self_result_code(),
7502                py_mod_name,
7503                code.error_goto_if_null(self.result(), self.pos)))
7504
7505        code.put_gotref(self.py_result())
7506
7507    def generate_cyfunction_code(self, code):
7508        if self.specialized_cpdefs:
7509            def_node = self.specialized_cpdefs[0]
7510        else:
7511            def_node = self.def_node
7512
7513        if self.specialized_cpdefs or self.is_specialization:
7514            code.globalstate.use_utility_code(
7515                UtilityCode.load_cached("FusedFunction", "CythonFunction.c"))
7516            constructor = "__pyx_FusedFunction_NewEx"
7517        else:
7518            code.globalstate.use_utility_code(
7519                UtilityCode.load_cached("CythonFunction", "CythonFunction.c"))
7520            constructor = "__Pyx_CyFunction_NewEx"
7521
7522        if self.code_object:
7523            code_object_result = self.code_object.py_result()
7524        else:
7525            code_object_result = 'NULL'
7526
7527        flags = []
7528        if def_node.is_staticmethod:
7529            flags.append('__Pyx_CYFUNCTION_STATICMETHOD')
7530        elif def_node.is_classmethod:
7531            flags.append('__Pyx_CYFUNCTION_CLASSMETHOD')
7532
7533        if def_node.local_scope.parent_scope.is_c_class_scope:
7534            flags.append('__Pyx_CYFUNCTION_CCLASS')
7535
7536        if flags:
7537            flags = ' | '.join(flags)
7538        else:
7539            flags = '0'
7540
7541        code.putln(
7542            '%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s' % (
7543                self.result(),
7544                constructor,
7545                self.pymethdef_cname,
7546                flags,
7547                self.get_py_qualified_name(code),
7548                self.self_result_code(),
7549                self.get_py_mod_name(code),
7550                "PyModule_GetDict(%s)" % Naming.module_cname,
7551                code_object_result,
7552                code.error_goto_if_null(self.result(), self.pos)))
7553
7554        code.put_gotref(self.py_result())
7555
7556        if def_node.requires_classobj:
7557            assert code.pyclass_stack, "pyclass_stack is empty"
7558            class_node = code.pyclass_stack[-1]
7559            code.put_incref(self.py_result(), py_object_type)
7560            code.putln(
7561                'PyList_Append(%s, %s);' % (
7562                    class_node.class_cell.result(),
7563                    self.result()))
7564            code.put_giveref(self.py_result())
7565
7566        if self.defaults:
7567            code.putln(
7568                'if (!__Pyx_CyFunction_InitDefaults(%s, sizeof(%s), %d)) %s' % (
7569                    self.result(), self.defaults_struct.name,
7570                    self.defaults_pyobjects, code.error_goto(self.pos)))
7571            defaults = '__Pyx_CyFunction_Defaults(%s, %s)' % (
7572                self.defaults_struct.name, self.result())
7573            for arg, entry in self.defaults:
7574                arg.generate_assignment_code(code, target='%s->%s' % (
7575                    defaults, entry.cname))
7576
7577        if self.defaults_tuple:
7578            code.putln('__Pyx_CyFunction_SetDefaultsTuple(%s, %s);' % (
7579                self.result(), self.defaults_tuple.py_result()))
7580        if self.defaults_kwdict:
7581            code.putln('__Pyx_CyFunction_SetDefaultsKwDict(%s, %s);' % (
7582                self.result(), self.defaults_kwdict.py_result()))
7583        if def_node.defaults_getter:
7584            code.putln('__Pyx_CyFunction_SetDefaultsGetter(%s, %s);' % (
7585                self.result(), def_node.defaults_getter.entry.pyfunc_cname))
7586        if self.annotations_dict:
7587            code.putln('__Pyx_CyFunction_SetAnnotationsDict(%s, %s);' % (
7588                self.result(), self.annotations_dict.py_result()))
7589
7590
7591class InnerFunctionNode(PyCFunctionNode):
7592    # Special PyCFunctionNode that depends on a closure class
7593    #
7594
7595    binding = True
7596    needs_self_code = True
7597
7598    def self_result_code(self):
7599        if self.needs_self_code:
7600            return "((PyObject*)%s)" % Naming.cur_scope_cname
7601        return "NULL"
7602
7603
7604class CodeObjectNode(ExprNode):
7605    # Create a PyCodeObject for a CyFunction instance.
7606    #
7607    # def_node   DefNode    the Python function node
7608    # varnames   TupleNode  a tuple with all local variable names
7609
7610    subexprs = ['varnames']
7611    is_temp = False
7612
7613    def __init__(self, def_node):
7614        ExprNode.__init__(self, def_node.pos, def_node=def_node)
7615        args = list(def_node.args)
7616        # if we have args/kwargs, then the first two in var_entries are those
7617        local_vars = [arg for arg in def_node.local_scope.var_entries if arg.name]
7618        self.varnames = TupleNode(
7619            def_node.pos,
7620            args=[IdentifierStringNode(arg.pos, value=arg.name)
7621                  for arg in args + local_vars],
7622            is_temp=0,
7623            is_literal=1)
7624
7625    def may_be_none(self):
7626        return False
7627
7628    def calculate_result_code(self):
7629        return self.result_code
7630
7631    def generate_result_code(self, code):
7632        self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
7633
7634        code = code.get_cached_constants_writer()
7635        code.mark_pos(self.pos)
7636        func = self.def_node
7637        func_name = code.get_py_string_const(
7638            func.name, identifier=True, is_str=False, unicode_value=func.name)
7639        # FIXME: better way to get the module file path at module init time? Encoding to use?
7640        file_path = StringEncoding.BytesLiteral(func.pos[0].get_filenametable_entry().encode('utf8'))
7641        file_path_const = code.get_py_string_const(file_path, identifier=False, is_str=True)
7642
7643        flags = []
7644        if self.def_node.star_arg:
7645            flags.append('CO_VARARGS')
7646        if self.def_node.starstar_arg:
7647            flags.append('CO_VARKEYWORDS')
7648
7649        code.putln("%s = (PyObject*)__Pyx_PyCode_New(%d, %d, %d, 0, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s); %s" % (
7650            self.result_code,
7651            len(func.args) - func.num_kwonly_args,  # argcount
7652            func.num_kwonly_args,      # kwonlyargcount (Py3 only)
7653            len(self.varnames.args),   # nlocals
7654            '|'.join(flags) or '0',    # flags
7655            Naming.empty_bytes,        # code
7656            Naming.empty_tuple,        # consts
7657            Naming.empty_tuple,        # names (FIXME)
7658            self.varnames.result(),    # varnames
7659            Naming.empty_tuple,        # freevars (FIXME)
7660            Naming.empty_tuple,        # cellvars (FIXME)
7661            file_path_const,           # filename
7662            func_name,                 # name
7663            self.pos[1],               # firstlineno
7664            Naming.empty_bytes,        # lnotab
7665            code.error_goto_if_null(self.result_code, self.pos),
7666            ))
7667
7668
7669class DefaultLiteralArgNode(ExprNode):
7670    # CyFunction's literal argument default value
7671    #
7672    # Evaluate literal only once.
7673
7674    subexprs = []
7675    is_literal = True
7676    is_temp = False
7677
7678    def __init__(self, pos, arg):
7679        super(DefaultLiteralArgNode, self).__init__(pos)
7680        self.arg = arg
7681        self.type = self.arg.type
7682        self.evaluated = False
7683
7684    def analyse_types(self, env):
7685        return self
7686
7687    def generate_result_code(self, code):
7688        pass
7689
7690    def generate_evaluation_code(self, code):
7691        if not self.evaluated:
7692            self.arg.generate_evaluation_code(code)
7693            self.evaluated = True
7694
7695    def result(self):
7696        return self.type.cast_code(self.arg.result())
7697
7698
7699class DefaultNonLiteralArgNode(ExprNode):
7700    # CyFunction's non-literal argument default value
7701
7702    subexprs = []
7703
7704    def __init__(self, pos, arg, defaults_struct):
7705        super(DefaultNonLiteralArgNode, self).__init__(pos)
7706        self.arg = arg
7707        self.defaults_struct = defaults_struct
7708
7709    def analyse_types(self, env):
7710        self.type = self.arg.type
7711        self.is_temp = False
7712        return self
7713
7714    def generate_result_code(self, code):
7715        pass
7716
7717    def result(self):
7718        return '__Pyx_CyFunction_Defaults(%s, %s)->%s' % (
7719            self.defaults_struct.name, Naming.self_cname,
7720            self.defaults_struct.lookup(self.arg.name).cname)
7721
7722
7723class DefaultsTupleNode(TupleNode):
7724    # CyFunction's __defaults__ tuple
7725
7726    def __init__(self, pos, defaults, defaults_struct):
7727        args = []
7728        for arg in defaults:
7729            if not arg.default.is_literal:
7730                arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
7731            else:
7732                arg = arg.default
7733            args.append(arg)
7734        super(DefaultsTupleNode, self).__init__(pos, args=args)
7735
7736
7737class DefaultsKwDictNode(DictNode):
7738    # CyFunction's __kwdefaults__ dict
7739
7740    def __init__(self, pos, defaults, defaults_struct):
7741        items = []
7742        for arg in defaults:
7743            name = IdentifierStringNode(arg.pos, value=arg.name)
7744            if not arg.default.is_literal:
7745                arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
7746            else:
7747                arg = arg.default
7748            items.append(DictItemNode(arg.pos, key=name, value=arg))
7749        super(DefaultsKwDictNode, self).__init__(pos, key_value_pairs=items)
7750
7751
7752class LambdaNode(InnerFunctionNode):
7753    # Lambda expression node (only used as a function reference)
7754    #
7755    # args          [CArgDeclNode]         formal arguments
7756    # star_arg      PyArgDeclNode or None  * argument
7757    # starstar_arg  PyArgDeclNode or None  ** argument
7758    # lambda_name   string                 a module-globally unique lambda name
7759    # result_expr   ExprNode
7760    # def_node      DefNode                the underlying function 'def' node
7761
7762    child_attrs = ['def_node']
7763
7764    name = StringEncoding.EncodedString('<lambda>')
7765
7766    def analyse_declarations(self, env):
7767        self.def_node.no_assignment_synthesis = True
7768        self.def_node.pymethdef_required = True
7769        self.def_node.analyse_declarations(env)
7770        self.def_node.is_cyfunction = True
7771        self.pymethdef_cname = self.def_node.entry.pymethdef_cname
7772        env.add_lambda_def(self.def_node)
7773
7774    def analyse_types(self, env):
7775        self.def_node = self.def_node.analyse_expressions(env)
7776        return super(LambdaNode, self).analyse_types(env)
7777
7778    def generate_result_code(self, code):
7779        self.def_node.generate_execution_code(code)
7780        super(LambdaNode, self).generate_result_code(code)
7781
7782
7783class GeneratorExpressionNode(LambdaNode):
7784    # A generator expression, e.g.  (i for i in range(10))
7785    #
7786    # Result is a generator.
7787    #
7788    # loop      ForStatNode   the for-loop, containing a YieldExprNode
7789    # def_node  DefNode       the underlying generator 'def' node
7790
7791    name = StringEncoding.EncodedString('genexpr')
7792    binding = False
7793
7794    def analyse_declarations(self, env):
7795        super(GeneratorExpressionNode, self).analyse_declarations(env)
7796        # No pymethdef required
7797        self.def_node.pymethdef_required = False
7798        self.def_node.py_wrapper_required = False
7799        self.def_node.is_cyfunction = False
7800        # Force genexpr signature
7801        self.def_node.entry.signature = TypeSlots.pyfunction_noargs
7802
7803    def generate_result_code(self, code):
7804        code.putln(
7805            '%s = %s(%s); %s' % (
7806                self.result(),
7807                self.def_node.entry.pyfunc_cname,
7808                self.self_result_code(),
7809                code.error_goto_if_null(self.result(), self.pos)))
7810        code.put_gotref(self.py_result())
7811
7812
7813class YieldExprNode(ExprNode):
7814    # Yield expression node
7815    #
7816    # arg         ExprNode   the value to return from the generator
7817    # label_num   integer    yield label number
7818    # is_yield_from  boolean is a YieldFromExprNode to delegate to another generator
7819
7820    subexprs = ['arg']
7821    type = py_object_type
7822    label_num = 0
7823    is_yield_from = False
7824
7825    def analyse_types(self, env):
7826        if not self.label_num:
7827            error(self.pos, "'yield' not supported here")
7828        self.is_temp = 1
7829        if self.arg is not None:
7830            self.arg = self.arg.analyse_types(env)
7831            if not self.arg.type.is_pyobject:
7832                self.coerce_yield_argument(env)
7833        return self
7834
7835    def coerce_yield_argument(self, env):
7836        self.arg = self.arg.coerce_to_pyobject(env)
7837
7838    def generate_evaluation_code(self, code):
7839        if self.arg:
7840            self.arg.generate_evaluation_code(code)
7841            self.arg.make_owned_reference(code)
7842            code.putln(
7843                "%s = %s;" % (
7844                    Naming.retval_cname,
7845                    self.arg.result_as(py_object_type)))
7846            self.arg.generate_post_assignment_code(code)
7847            self.arg.free_temps(code)
7848        else:
7849            code.put_init_to_py_none(Naming.retval_cname, py_object_type)
7850        self.generate_yield_code(code)
7851
7852    def generate_yield_code(self, code):
7853        """
7854        Generate the code to return the argument in 'Naming.retval_cname'
7855        and to continue at the yield label.
7856        """
7857        label_num, label_name = code.new_yield_label()
7858        code.use_label(label_name)
7859
7860        saved = []
7861        code.funcstate.closure_temps.reset()
7862        for cname, type, manage_ref in code.funcstate.temps_in_use():
7863            save_cname = code.funcstate.closure_temps.allocate_temp(type)
7864            saved.append((cname, save_cname, type))
7865            if type.is_pyobject:
7866                code.put_xgiveref(cname)
7867            code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
7868
7869        code.put_xgiveref(Naming.retval_cname)
7870        code.put_finish_refcount_context()
7871        code.putln("/* return from generator, yielding value */")
7872        code.putln("%s->resume_label = %d;" % (
7873            Naming.generator_cname, label_num))
7874        code.putln("return %s;" % Naming.retval_cname)
7875
7876        code.put_label(label_name)
7877        for cname, save_cname, type in saved:
7878            code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
7879            if type.is_pyobject:
7880                code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
7881                code.put_xgotref(cname)
7882        code.putln(code.error_goto_if_null(Naming.sent_value_cname, self.pos))
7883        if self.result_is_used:
7884            self.allocate_temp_result(code)
7885            code.put('%s = %s; ' % (self.result(), Naming.sent_value_cname))
7886            code.put_incref(self.result(), py_object_type)
7887
7888
7889class YieldFromExprNode(YieldExprNode):
7890    # "yield from GEN" expression
7891    is_yield_from = True
7892
7893    def coerce_yield_argument(self, env):
7894        if not self.arg.type.is_string:
7895            # FIXME: support C arrays and C++ iterators?
7896            error(self.pos, "yielding from non-Python object not supported")
7897        self.arg = self.arg.coerce_to_pyobject(env)
7898
7899    def generate_evaluation_code(self, code):
7900        code.globalstate.use_utility_code(UtilityCode.load_cached("YieldFrom", "Generator.c"))
7901
7902        self.arg.generate_evaluation_code(code)
7903        code.putln("%s = __Pyx_Generator_Yield_From(%s, %s);" % (
7904            Naming.retval_cname,
7905            Naming.generator_cname,
7906            self.arg.result_as(py_object_type)))
7907        self.arg.generate_disposal_code(code)
7908        self.arg.free_temps(code)
7909        code.put_xgotref(Naming.retval_cname)
7910
7911        code.putln("if (likely(%s)) {" % Naming.retval_cname)
7912        self.generate_yield_code(code)
7913        code.putln("} else {")
7914        # either error or sub-generator has normally terminated: return value => node result
7915        if self.result_is_used:
7916            # YieldExprNode has allocated the result temp for us
7917            code.putln("%s = NULL;" % self.result())
7918            code.putln("if (unlikely(__Pyx_PyGen_FetchStopIterationValue(&%s) < 0)) %s" % (
7919                self.result(),
7920                code.error_goto(self.pos)))
7921            code.put_gotref(self.result())
7922        else:
7923            code.putln("PyObject* exc_type = PyErr_Occurred();")
7924            code.putln("if (exc_type) {")
7925            code.putln("if (likely(exc_type == PyExc_StopIteration ||"
7926                       " PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();")
7927            code.putln("else %s" % code.error_goto(self.pos))
7928            code.putln("}")
7929        code.putln("}")
7930
7931class GlobalsExprNode(AtomicExprNode):
7932    type = dict_type
7933    is_temp = 1
7934
7935    def analyse_types(self, env):
7936        env.use_utility_code(Builtin.globals_utility_code)
7937        return self
7938
7939    gil_message = "Constructing globals dict"
7940
7941    def may_be_none(self):
7942        return False
7943
7944    def generate_result_code(self, code):
7945        code.putln('%s = __Pyx_Globals(); %s' % (
7946            self.result(),
7947            code.error_goto_if_null(self.result(), self.pos)))
7948        code.put_gotref(self.result())
7949
7950
7951class LocalsDictItemNode(DictItemNode):
7952    def analyse_types(self, env):
7953        self.key = self.key.analyse_types(env)
7954        self.value = self.value.analyse_types(env)
7955        self.key = self.key.coerce_to_pyobject(env)
7956        if self.value.type.can_coerce_to_pyobject(env):
7957            self.value = self.value.coerce_to_pyobject(env)
7958        else:
7959            self.value = None
7960        return self
7961
7962
7963class FuncLocalsExprNode(DictNode):
7964    def __init__(self, pos, env):
7965        local_vars = sorted([
7966            entry.name for entry in env.entries.values() if entry.name])
7967        items = [LocalsDictItemNode(
7968            pos, key=IdentifierStringNode(pos, value=var),
7969            value=NameNode(pos, name=var, allow_null=True))
7970                 for var in local_vars]
7971        DictNode.__init__(self, pos, key_value_pairs=items,
7972                          exclude_null_values=True)
7973
7974    def analyse_types(self, env):
7975        node = super(FuncLocalsExprNode, self).analyse_types(env)
7976        node.key_value_pairs = [ i for i in node.key_value_pairs
7977                                 if i.value is not None ]
7978        return node
7979
7980
7981class PyClassLocalsExprNode(AtomicExprNode):
7982    def __init__(self, pos, pyclass_dict):
7983        AtomicExprNode.__init__(self, pos)
7984        self.pyclass_dict = pyclass_dict
7985
7986    def analyse_types(self, env):
7987        self.type = self.pyclass_dict.type
7988        self.is_temp = False
7989        return self
7990
7991    def may_be_none(self):
7992        return False
7993
7994    def result(self):
7995        return self.pyclass_dict.result()
7996
7997    def generate_result_code(self, code):
7998        pass
7999
8000
8001def LocalsExprNode(pos, scope_node, env):
8002    if env.is_module_scope:
8003        return GlobalsExprNode(pos)
8004    if env.is_py_class_scope:
8005        return PyClassLocalsExprNode(pos, scope_node.dict)
8006    return FuncLocalsExprNode(pos, env)
8007
8008
8009#-------------------------------------------------------------------
8010#
8011#  Unary operator nodes
8012#
8013#-------------------------------------------------------------------
8014
8015compile_time_unary_operators = {
8016    'not': operator.not_,
8017    '~': operator.inv,
8018    '-': operator.neg,
8019    '+': operator.pos,
8020}
8021
8022class UnopNode(ExprNode):
8023    #  operator     string
8024    #  operand      ExprNode
8025    #
8026    #  Processing during analyse_expressions phase:
8027    #
8028    #    analyse_c_operation
8029    #      Called when the operand is not a pyobject.
8030    #      - Check operand type and coerce if needed.
8031    #      - Determine result type and result code fragment.
8032    #      - Allocate temporary for result if needed.
8033
8034    subexprs = ['operand']
8035    infix = True
8036
8037    def calculate_constant_result(self):
8038        func = compile_time_unary_operators[self.operator]
8039        self.constant_result = func(self.operand.constant_result)
8040
8041    def compile_time_value(self, denv):
8042        func = compile_time_unary_operators.get(self.operator)
8043        if not func:
8044            error(self.pos,
8045                "Unary '%s' not supported in compile-time expression"
8046                    % self.operator)
8047        operand = self.operand.compile_time_value(denv)
8048        try:
8049            return func(operand)
8050        except Exception, e:
8051            self.compile_time_value_error(e)
8052
8053    def infer_type(self, env):
8054        operand_type = self.operand.infer_type(env)
8055        if operand_type.is_cpp_class or operand_type.is_ptr:
8056            cpp_type = operand_type.find_cpp_operation_type(self.operator)
8057            if cpp_type is not None:
8058                return cpp_type
8059        return self.infer_unop_type(env, operand_type)
8060
8061    def infer_unop_type(self, env, operand_type):
8062        if operand_type.is_pyobject:
8063            return py_object_type
8064        else:
8065            return operand_type
8066
8067    def may_be_none(self):
8068        if self.operand.type and self.operand.type.is_builtin_type:
8069            if self.operand.type is not type_type:
8070                return False
8071        return ExprNode.may_be_none(self)
8072
8073    def analyse_types(self, env):
8074        self.operand = self.operand.analyse_types(env)
8075        if self.is_py_operation():
8076            self.coerce_operand_to_pyobject(env)
8077            self.type = py_object_type
8078            self.is_temp = 1
8079        elif self.is_cpp_operation():
8080            self.analyse_cpp_operation(env)
8081        else:
8082            self.analyse_c_operation(env)
8083        return self
8084
8085    def check_const(self):
8086        return self.operand.check_const()
8087
8088    def is_py_operation(self):
8089        return self.operand.type.is_pyobject
8090
8091    def nogil_check(self, env):
8092        if self.is_py_operation():
8093            self.gil_error()
8094
8095    def is_cpp_operation(self):
8096        type = self.operand.type
8097        return type.is_cpp_class
8098
8099    def coerce_operand_to_pyobject(self, env):
8100        self.operand = self.operand.coerce_to_pyobject(env)
8101
8102    def generate_result_code(self, code):
8103        if self.operand.type.is_pyobject:
8104            self.generate_py_operation_code(code)
8105
8106    def generate_py_operation_code(self, code):
8107        function = self.py_operation_function()
8108        code.putln(
8109            "%s = %s(%s); %s" % (
8110                self.result(),
8111                function,
8112                self.operand.py_result(),
8113                code.error_goto_if_null(self.result(), self.pos)))
8114        code.put_gotref(self.py_result())
8115
8116    def type_error(self):
8117        if not self.operand.type.is_error:
8118            error(self.pos, "Invalid operand type for '%s' (%s)" %
8119                (self.operator, self.operand.type))
8120        self.type = PyrexTypes.error_type
8121
8122    def analyse_cpp_operation(self, env):
8123        cpp_type = self.operand.type.find_cpp_operation_type(self.operator)
8124        if cpp_type is None:
8125            error(self.pos, "'%s' operator not defined for %s" % (
8126                self.operator, type))
8127            self.type_error()
8128            return
8129        self.type = cpp_type
8130
8131
8132class NotNode(UnopNode):
8133    #  'not' operator
8134    #
8135    #  operand   ExprNode
8136    operator = '!'
8137
8138    type = PyrexTypes.c_bint_type
8139
8140    def calculate_constant_result(self):
8141        self.constant_result = not self.operand.constant_result
8142
8143    def compile_time_value(self, denv):
8144        operand = self.operand.compile_time_value(denv)
8145        try:
8146            return not operand
8147        except Exception, e:
8148            self.compile_time_value_error(e)
8149
8150    def infer_unop_type(self, env, operand_type):
8151        return PyrexTypes.c_bint_type
8152
8153    def analyse_types(self, env):
8154        self.operand = self.operand.analyse_types(env)
8155        operand_type = self.operand.type
8156        if operand_type.is_cpp_class:
8157            cpp_type = operand_type.find_cpp_operation_type(self.operator)
8158            if not cpp_type:
8159                error(self.pos, "'!' operator not defined for %s" % operand_type)
8160                self.type = PyrexTypes.error_type
8161                return
8162            self.type = cpp_type
8163        else:
8164            self.operand = self.operand.coerce_to_boolean(env)
8165        return self
8166
8167    def calculate_result_code(self):
8168        return "(!%s)" % self.operand.result()
8169
8170    def generate_result_code(self, code):
8171        pass
8172
8173
8174class UnaryPlusNode(UnopNode):
8175    #  unary '+' operator
8176
8177    operator = '+'
8178
8179    def analyse_c_operation(self, env):
8180        self.type = PyrexTypes.widest_numeric_type(
8181            self.operand.type, PyrexTypes.c_int_type)
8182
8183    def py_operation_function(self):
8184        return "PyNumber_Positive"
8185
8186    def calculate_result_code(self):
8187        if self.is_cpp_operation():
8188            return "(+%s)" % self.operand.result()
8189        else:
8190            return self.operand.result()
8191
8192
8193class UnaryMinusNode(UnopNode):
8194    #  unary '-' operator
8195
8196    operator = '-'
8197
8198    def analyse_c_operation(self, env):
8199        if self.operand.type.is_numeric:
8200            self.type = PyrexTypes.widest_numeric_type(
8201                self.operand.type, PyrexTypes.c_int_type)
8202        elif self.operand.type.is_enum:
8203            self.type = PyrexTypes.c_int_type
8204        else:
8205            self.type_error()
8206        if self.type.is_complex:
8207            self.infix = False
8208
8209    def py_operation_function(self):
8210        return "PyNumber_Negative"
8211
8212    def calculate_result_code(self):
8213        if self.infix:
8214            return "(-%s)" % self.operand.result()
8215        else:
8216            return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
8217
8218    def get_constant_c_result_code(self):
8219        value = self.operand.get_constant_c_result_code()
8220        if value:
8221            return "(-%s)" % value
8222
8223class TildeNode(UnopNode):
8224    #  unary '~' operator
8225
8226    def analyse_c_operation(self, env):
8227        if self.operand.type.is_int:
8228            self.type = PyrexTypes.widest_numeric_type(
8229                self.operand.type, PyrexTypes.c_int_type)
8230        elif self.operand.type.is_enum:
8231            self.type = PyrexTypes.c_int_type
8232        else:
8233            self.type_error()
8234
8235    def py_operation_function(self):
8236        return "PyNumber_Invert"
8237
8238    def calculate_result_code(self):
8239        return "(~%s)" % self.operand.result()
8240
8241
8242class CUnopNode(UnopNode):
8243
8244    def is_py_operation(self):
8245        return False
8246
8247class DereferenceNode(CUnopNode):
8248    #  unary * operator
8249
8250    operator = '*'
8251
8252    def infer_unop_type(self, env, operand_type):
8253        if operand_type.is_ptr:
8254            return operand_type.base_type
8255        else:
8256            return PyrexTypes.error_type
8257
8258    def analyse_c_operation(self, env):
8259        if self.operand.type.is_ptr:
8260            self.type = self.operand.type.base_type
8261        else:
8262            self.type_error()
8263
8264    def calculate_result_code(self):
8265        return "(*%s)" % self.operand.result()
8266
8267
8268class DecrementIncrementNode(CUnopNode):
8269    #  unary ++/-- operator
8270
8271    def analyse_c_operation(self, env):
8272        if self.operand.type.is_numeric:
8273            self.type = PyrexTypes.widest_numeric_type(
8274                self.operand.type, PyrexTypes.c_int_type)
8275        elif self.operand.type.is_ptr:
8276            self.type = self.operand.type
8277        else:
8278            self.type_error()
8279
8280    def calculate_result_code(self):
8281        if self.is_prefix:
8282            return "(%s%s)" % (self.operator, self.operand.result())
8283        else:
8284            return "(%s%s)" % (self.operand.result(), self.operator)
8285
8286def inc_dec_constructor(is_prefix, operator):
8287    return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
8288
8289
8290class AmpersandNode(CUnopNode):
8291    #  The C address-of operator.
8292    #
8293    #  operand  ExprNode
8294    operator = '&'
8295
8296    def infer_unop_type(self, env, operand_type):
8297        return PyrexTypes.c_ptr_type(operand_type)
8298
8299    def analyse_types(self, env):
8300        self.operand = self.operand.analyse_types(env)
8301        argtype = self.operand.type
8302        if argtype.is_cpp_class:
8303            cpp_type = argtype.find_cpp_operation_type(self.operator)
8304            if cpp_type is not None:
8305                self.type = cpp_type
8306                return self
8307        if not (argtype.is_cfunction or argtype.is_reference or self.operand.is_addressable()):
8308            if argtype.is_memoryviewslice:
8309                self.error("Cannot take address of memoryview slice")
8310            else:
8311                self.error("Taking address of non-lvalue")
8312            return self
8313        if argtype.is_pyobject:
8314            self.error("Cannot take address of Python variable")
8315            return self
8316        self.type = PyrexTypes.c_ptr_type(argtype)
8317        return self
8318
8319    def check_const(self):
8320        return self.operand.check_const_addr()
8321
8322    def error(self, mess):
8323        error(self.pos, mess)
8324        self.type = PyrexTypes.error_type
8325        self.result_code = "<error>"
8326
8327    def calculate_result_code(self):
8328        return "(&%s)" % self.operand.result()
8329
8330    def generate_result_code(self, code):
8331        pass
8332
8333
8334unop_node_classes = {
8335    "+":  UnaryPlusNode,
8336    "-":  UnaryMinusNode,
8337    "~":  TildeNode,
8338}
8339
8340def unop_node(pos, operator, operand):
8341    # Construct unnop node of appropriate class for
8342    # given operator.
8343    if isinstance(operand, IntNode) and operator == '-':
8344        return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)),
8345                       longness=operand.longness, unsigned=operand.unsigned)
8346    elif isinstance(operand, UnopNode) and operand.operator == operator in '+-':
8347        warning(pos, "Python has no increment/decrement operator: %s%sx == %s(%sx) == x" % ((operator,)*4), 5)
8348    return unop_node_classes[operator](pos,
8349        operator = operator,
8350        operand = operand)
8351
8352
8353class TypecastNode(ExprNode):
8354    #  C type cast
8355    #
8356    #  operand      ExprNode
8357    #  base_type    CBaseTypeNode
8358    #  declarator   CDeclaratorNode
8359    #  typecheck    boolean
8360    #
8361    #  If used from a transform, one can if wanted specify the attribute
8362    #  "type" directly and leave base_type and declarator to None
8363
8364    subexprs = ['operand']
8365    base_type = declarator = type = None
8366
8367    def type_dependencies(self, env):
8368        return ()
8369
8370    def infer_type(self, env):
8371        if self.type is None:
8372            base_type = self.base_type.analyse(env)
8373            _, self.type = self.declarator.analyse(base_type, env)
8374        return self.type
8375
8376    def analyse_types(self, env):
8377        if self.type is None:
8378            base_type = self.base_type.analyse(env)
8379            _, self.type = self.declarator.analyse(base_type, env)
8380        if self.operand.has_constant_result():
8381            # Must be done after self.type is resolved.
8382            self.calculate_constant_result()
8383        if self.type.is_cfunction:
8384            error(self.pos,
8385                "Cannot cast to a function type")
8386            self.type = PyrexTypes.error_type
8387        self.operand = self.operand.analyse_types(env)
8388        if self.type is PyrexTypes.c_bint_type:
8389            # short circuit this to a coercion
8390            return self.operand.coerce_to_boolean(env)
8391        to_py = self.type.is_pyobject
8392        from_py = self.operand.type.is_pyobject
8393        if from_py and not to_py and self.operand.is_ephemeral():
8394            if not self.type.is_numeric and not self.type.is_cpp_class:
8395                error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
8396        if to_py and not from_py:
8397            if self.type is bytes_type and self.operand.type.is_int:
8398                return CoerceIntToBytesNode(self.operand, env)
8399            elif self.operand.type.can_coerce_to_pyobject(env):
8400                self.result_ctype = py_object_type
8401                base_type = self.base_type.analyse(env)
8402                self.operand = self.operand.coerce_to(base_type, env)
8403            else:
8404                if self.operand.type.is_ptr:
8405                    if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
8406                        error(self.pos, "Python objects cannot be cast from pointers of primitive types")
8407                else:
8408                    # Should this be an error?
8409                    warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
8410                self.operand = self.operand.coerce_to_simple(env)
8411        elif from_py and not to_py:
8412            if self.type.create_from_py_utility_code(env):
8413                self.operand = self.operand.coerce_to(self.type, env)
8414            elif self.type.is_ptr:
8415                if not (self.type.base_type.is_void or self.type.base_type.is_struct):
8416                    error(self.pos, "Python objects cannot be cast to pointers of primitive types")
8417            else:
8418                warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
8419        elif from_py and to_py:
8420            if self.typecheck:
8421                self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
8422            elif isinstance(self.operand, SliceIndexNode):
8423                # This cast can influence the created type of string slices.
8424                self.operand = self.operand.coerce_to(self.type, env)
8425        elif self.type.is_complex and self.operand.type.is_complex:
8426            self.operand = self.operand.coerce_to_simple(env)
8427        elif self.operand.type.is_fused:
8428            self.operand = self.operand.coerce_to(self.type, env)
8429            #self.type = self.operand.type
8430        return self
8431
8432    def is_simple(self):
8433        # either temp or a C cast => no side effects other than the operand's
8434        return self.operand.is_simple()
8435
8436    def nonlocally_immutable(self):
8437        return self.is_temp or self.operand.nonlocally_immutable()
8438
8439    def nogil_check(self, env):
8440        if self.type and self.type.is_pyobject and self.is_temp:
8441            self.gil_error()
8442
8443    def check_const(self):
8444        return self.operand.check_const()
8445
8446    def calculate_constant_result(self):
8447        self.constant_result = self.calculate_result_code(self.operand.constant_result)
8448
8449    def calculate_result_code(self, operand_result = None):
8450        if operand_result is None:
8451            operand_result = self.operand.result()
8452        if self.type.is_complex:
8453            operand_result = self.operand.result()
8454            if self.operand.type.is_complex:
8455                real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
8456                imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
8457            else:
8458                real_part = self.type.real_type.cast_code(operand_result)
8459                imag_part = "0"
8460            return "%s(%s, %s)" % (
8461                    self.type.from_parts,
8462                    real_part,
8463                    imag_part)
8464        else:
8465            return self.type.cast_code(operand_result)
8466
8467    def get_constant_c_result_code(self):
8468        operand_result = self.operand.get_constant_c_result_code()
8469        if operand_result:
8470            return self.type.cast_code(operand_result)
8471
8472    def result_as(self, type):
8473        if self.type.is_pyobject and not self.is_temp:
8474            #  Optimise away some unnecessary casting
8475            return self.operand.result_as(type)
8476        else:
8477            return ExprNode.result_as(self, type)
8478
8479    def generate_result_code(self, code):
8480        if self.is_temp:
8481            code.putln(
8482                "%s = (PyObject *)%s;" % (
8483                    self.result(),
8484                    self.operand.result()))
8485            code.put_incref(self.result(), self.ctype())
8486
8487
8488ERR_START = "Start may not be given"
8489ERR_NOT_STOP = "Stop must be provided to indicate shape"
8490ERR_STEPS = ("Strides may only be given to indicate contiguity. "
8491             "Consider slicing it after conversion")
8492ERR_NOT_POINTER = "Can only create cython.array from pointer or array"
8493ERR_BASE_TYPE = "Pointer base type does not match cython.array base type"
8494
8495class CythonArrayNode(ExprNode):
8496    """
8497    Used when a pointer of base_type is cast to a memoryviewslice with that
8498    base type. i.e.
8499
8500        <int[:M:1, :N]> p
8501
8502    creates a fortran-contiguous cython.array.
8503
8504    We leave the type set to object so coercions to object are more efficient
8505    and less work. Acquiring a memoryviewslice from this will be just as
8506    efficient. ExprNode.coerce_to() will do the additional typecheck on
8507    self.compile_time_type
8508
8509    This also handles <int[:, :]> my_c_array
8510
8511
8512    operand             ExprNode                 the thing we're casting
8513    base_type_node      MemoryViewSliceTypeNode  the cast expression node
8514    """
8515
8516    subexprs = ['operand', 'shapes']
8517
8518    shapes = None
8519    is_temp = True
8520    mode = "c"
8521    array_dtype = None
8522
8523    shape_type = PyrexTypes.c_py_ssize_t_type
8524
8525    def analyse_types(self, env):
8526        import MemoryView
8527
8528        self.operand = self.operand.analyse_types(env)
8529        if self.array_dtype:
8530            array_dtype = self.array_dtype
8531        else:
8532            array_dtype = self.base_type_node.base_type_node.analyse(env)
8533        axes = self.base_type_node.axes
8534
8535        MemoryView.validate_memslice_dtype(self.pos, array_dtype)
8536
8537        self.type = error_type
8538        self.shapes = []
8539        ndim = len(axes)
8540
8541        # Base type of the pointer or C array we are converting
8542        base_type = self.operand.type
8543
8544        if not self.operand.type.is_ptr and not self.operand.type.is_array:
8545            error(self.operand.pos, ERR_NOT_POINTER)
8546            return self
8547
8548        # Dimension sizes of C array
8549        array_dimension_sizes = []
8550        if base_type.is_array:
8551            while base_type.is_array:
8552                array_dimension_sizes.append(base_type.size)
8553                base_type = base_type.base_type
8554        elif base_type.is_ptr:
8555            base_type = base_type.base_type
8556        else:
8557            error(self.pos, "unexpected base type %s found" % base_type)
8558            return self
8559
8560        if not (base_type.same_as(array_dtype) or base_type.is_void):
8561            error(self.operand.pos, ERR_BASE_TYPE)
8562            return self
8563        elif self.operand.type.is_array and len(array_dimension_sizes) != ndim:
8564            error(self.operand.pos,
8565                  "Expected %d dimensions, array has %d dimensions" %
8566                                            (ndim, len(array_dimension_sizes)))
8567            return self
8568
8569        # Verify the start, stop and step values
8570        # In case of a C array, use the size of C array in each dimension to
8571        # get an automatic cast
8572        for axis_no, axis in enumerate(axes):
8573            if not axis.start.is_none:
8574                error(axis.start.pos, ERR_START)
8575                return self
8576
8577            if axis.stop.is_none:
8578                if array_dimension_sizes:
8579                    dimsize = array_dimension_sizes[axis_no]
8580                    axis.stop = IntNode(self.pos, value=str(dimsize),
8581                                        constant_result=dimsize,
8582                                        type=PyrexTypes.c_int_type)
8583                else:
8584                    error(axis.pos, ERR_NOT_STOP)
8585                    return self
8586
8587            axis.stop = axis.stop.analyse_types(env)
8588            shape = axis.stop.coerce_to(self.shape_type, env)
8589            if not shape.is_literal:
8590                shape.coerce_to_temp(env)
8591
8592            self.shapes.append(shape)
8593
8594            first_or_last = axis_no in (0, ndim - 1)
8595            if not axis.step.is_none and first_or_last:
8596                # '1' in the first or last dimension denotes F or C contiguity
8597                axis.step = axis.step.analyse_types(env)
8598                if (not axis.step.type.is_int and axis.step.is_literal and not
8599                        axis.step.type.is_error):
8600                    error(axis.step.pos, "Expected an integer literal")
8601                    return self
8602
8603                if axis.step.compile_time_value(env) != 1:
8604                    error(axis.step.pos, ERR_STEPS)
8605                    return self
8606
8607                if axis_no == 0:
8608                    self.mode = "fortran"
8609
8610            elif not axis.step.is_none and not first_or_last:
8611                # step provided in some other dimension
8612                error(axis.step.pos, ERR_STEPS)
8613                return self
8614
8615        if not self.operand.is_name:
8616            self.operand = self.operand.coerce_to_temp(env)
8617
8618        axes = [('direct', 'follow')] * len(axes)
8619        if self.mode == "fortran":
8620            axes[0] = ('direct', 'contig')
8621        else:
8622            axes[-1] = ('direct', 'contig')
8623
8624        self.coercion_type = PyrexTypes.MemoryViewSliceType(array_dtype, axes)
8625        self.type = self.get_cython_array_type(env)
8626        MemoryView.use_cython_array_utility_code(env)
8627        env.use_utility_code(MemoryView.typeinfo_to_format_code)
8628        return self
8629
8630    def allocate_temp_result(self, code):
8631        if self.temp_code:
8632            raise RuntimeError("temp allocated mulitple times")
8633
8634        self.temp_code = code.funcstate.allocate_temp(self.type, True)
8635
8636    def infer_type(self, env):
8637        return self.get_cython_array_type(env)
8638
8639    def get_cython_array_type(self, env):
8640        return env.global_scope().context.cython_scope.viewscope.lookup("array").type
8641
8642    def generate_result_code(self, code):
8643        import Buffer
8644
8645        shapes = [self.shape_type.cast_code(shape.result())
8646                      for shape in self.shapes]
8647        dtype = self.coercion_type.dtype
8648
8649        shapes_temp = code.funcstate.allocate_temp(py_object_type, True)
8650        format_temp = code.funcstate.allocate_temp(py_object_type, True)
8651
8652        itemsize = "sizeof(%s)" % dtype.declaration_code("")
8653        type_info = Buffer.get_type_information_cname(code, dtype)
8654
8655        if self.operand.type.is_ptr:
8656            code.putln("if (!%s) {" % self.operand.result())
8657            code.putln(    'PyErr_SetString(PyExc_ValueError,'
8658                                '"Cannot create cython.array from NULL pointer");')
8659            code.putln(code.error_goto(self.operand.pos))
8660            code.putln("}")
8661
8662        code.putln("%s = __pyx_format_from_typeinfo(&%s);" %
8663                                                (format_temp, type_info))
8664        buildvalue_fmt = " __PYX_BUILD_PY_SSIZE_T " * len(shapes)
8665        code.putln('%s = Py_BuildValue((char*) "(" %s ")", %s);' % (
8666            shapes_temp, buildvalue_fmt, ", ".join(shapes)))
8667
8668        err = "!%s || !%s || !PyBytes_AsString(%s)" % (format_temp,
8669                                                       shapes_temp,
8670                                                       format_temp)
8671        code.putln(code.error_goto_if(err, self.pos))
8672        code.put_gotref(format_temp)
8673        code.put_gotref(shapes_temp)
8674
8675        tup = (self.result(), shapes_temp, itemsize, format_temp,
8676               self.mode, self.operand.result())
8677        code.putln('%s = __pyx_array_new('
8678                            '%s, %s, PyBytes_AS_STRING(%s), '
8679                            '(char *) "%s", (char *) %s);' % tup)
8680        code.putln(code.error_goto_if_null(self.result(), self.pos))
8681        code.put_gotref(self.result())
8682
8683        def dispose(temp):
8684            code.put_decref_clear(temp, py_object_type)
8685            code.funcstate.release_temp(temp)
8686
8687        dispose(shapes_temp)
8688        dispose(format_temp)
8689
8690    @classmethod
8691    def from_carray(cls, src_node, env):
8692        """
8693        Given a C array type, return a CythonArrayNode
8694        """
8695        pos = src_node.pos
8696        base_type = src_node.type
8697
8698        none_node = NoneNode(pos)
8699        axes = []
8700
8701        while base_type.is_array:
8702            axes.append(SliceNode(pos, start=none_node, stop=none_node,
8703                                       step=none_node))
8704            base_type = base_type.base_type
8705        axes[-1].step = IntNode(pos, value="1", is_c_literal=True)
8706
8707        memslicenode = Nodes.MemoryViewSliceTypeNode(pos, axes=axes,
8708                                                     base_type_node=base_type)
8709        result = CythonArrayNode(pos, base_type_node=memslicenode,
8710                                 operand=src_node, array_dtype=base_type)
8711        result = result.analyse_types(env)
8712        return result
8713
8714class SizeofNode(ExprNode):
8715    #  Abstract base class for sizeof(x) expression nodes.
8716
8717    type = PyrexTypes.c_size_t_type
8718
8719    def check_const(self):
8720        return True
8721
8722    def generate_result_code(self, code):
8723        pass
8724
8725
8726class SizeofTypeNode(SizeofNode):
8727    #  C sizeof function applied to a type
8728    #
8729    #  base_type   CBaseTypeNode
8730    #  declarator  CDeclaratorNode
8731
8732    subexprs = []
8733    arg_type = None
8734
8735    def analyse_types(self, env):
8736        # we may have incorrectly interpreted a dotted name as a type rather than an attribute
8737        # this could be better handled by more uniformly treating types as runtime-available objects
8738        if 0 and self.base_type.module_path:
8739            path = self.base_type.module_path
8740            obj = env.lookup(path[0])
8741            if obj.as_module is None:
8742                operand = NameNode(pos=self.pos, name=path[0])
8743                for attr in path[1:]:
8744                    operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
8745                operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
8746                self.operand = operand
8747                self.__class__ = SizeofVarNode
8748                node = self.analyse_types(env)
8749                return node
8750        if self.arg_type is None:
8751            base_type = self.base_type.analyse(env)
8752            _, arg_type = self.declarator.analyse(base_type, env)
8753            self.arg_type = arg_type
8754        self.check_type()
8755        return self
8756
8757    def check_type(self):
8758        arg_type = self.arg_type
8759        if arg_type.is_pyobject and not arg_type.is_extension_type:
8760            error(self.pos, "Cannot take sizeof Python object")
8761        elif arg_type.is_void:
8762            error(self.pos, "Cannot take sizeof void")
8763        elif not arg_type.is_complete():
8764            error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
8765
8766    def calculate_result_code(self):
8767        if self.arg_type.is_extension_type:
8768            # the size of the pointer is boring
8769            # we want the size of the actual struct
8770            arg_code = self.arg_type.declaration_code("", deref=1)
8771        else:
8772            arg_code = self.arg_type.declaration_code("")
8773        return "(sizeof(%s))" % arg_code
8774
8775
8776class SizeofVarNode(SizeofNode):
8777    #  C sizeof function applied to a variable
8778    #
8779    #  operand   ExprNode
8780
8781    subexprs = ['operand']
8782
8783    def analyse_types(self, env):
8784        # We may actually be looking at a type rather than a variable...
8785        # If we are, traditional analysis would fail...
8786        operand_as_type = self.operand.analyse_as_type(env)
8787        if operand_as_type:
8788            self.arg_type = operand_as_type
8789            if self.arg_type.is_fused:
8790                self.arg_type = self.arg_type.specialize(env.fused_to_specific)
8791            self.__class__ = SizeofTypeNode
8792            self.check_type()
8793        else:
8794            self.operand = self.operand.analyse_types(env)
8795        return self
8796
8797    def calculate_result_code(self):
8798        return "(sizeof(%s))" % self.operand.result()
8799
8800    def generate_result_code(self, code):
8801        pass
8802
8803class TypeofNode(ExprNode):
8804    #  Compile-time type of an expression, as a string.
8805    #
8806    #  operand   ExprNode
8807    #  literal   StringNode # internal
8808
8809    literal = None
8810    type = py_object_type
8811
8812    subexprs = ['literal'] # 'operand' will be ignored after type analysis!
8813
8814    def analyse_types(self, env):
8815        self.operand = self.operand.analyse_types(env)
8816        value = StringEncoding.EncodedString(str(self.operand.type)) #self.operand.type.typeof_name())
8817        literal = StringNode(self.pos, value=value)
8818        literal = literal.analyse_types(env)
8819        self.literal = literal.coerce_to_pyobject(env)
8820        return self
8821
8822    def may_be_none(self):
8823        return False
8824
8825    def generate_evaluation_code(self, code):
8826        self.literal.generate_evaluation_code(code)
8827
8828    def calculate_result_code(self):
8829        return self.literal.calculate_result_code()
8830
8831#-------------------------------------------------------------------
8832#
8833#  Binary operator nodes
8834#
8835#-------------------------------------------------------------------
8836
8837compile_time_binary_operators = {
8838    '<': operator.lt,
8839    '<=': operator.le,
8840    '==': operator.eq,
8841    '!=': operator.ne,
8842    '>=': operator.ge,
8843    '>': operator.gt,
8844    'is': operator.is_,
8845    'is_not': operator.is_not,
8846    '+': operator.add,
8847    '&': operator.and_,
8848    '/': operator.truediv,
8849    '//': operator.floordiv,
8850    '<<': operator.lshift,
8851    '%': operator.mod,
8852    '*': operator.mul,
8853    '|': operator.or_,
8854    '**': operator.pow,
8855    '>>': operator.rshift,
8856    '-': operator.sub,
8857    '^': operator.xor,
8858    'in': lambda x, seq: x in seq,
8859    'not_in': lambda x, seq: x not in seq,
8860}
8861
8862def get_compile_time_binop(node):
8863    func = compile_time_binary_operators.get(node.operator)
8864    if not func:
8865        error(node.pos,
8866            "Binary '%s' not supported in compile-time expression"
8867                % node.operator)
8868    return func
8869
8870class BinopNode(ExprNode):
8871    #  operator     string
8872    #  operand1     ExprNode
8873    #  operand2     ExprNode
8874    #
8875    #  Processing during analyse_expressions phase:
8876    #
8877    #    analyse_c_operation
8878    #      Called when neither operand is a pyobject.
8879    #      - Check operand types and coerce if needed.
8880    #      - Determine result type and result code fragment.
8881    #      - Allocate temporary for result if needed.
8882
8883    subexprs = ['operand1', 'operand2']
8884    inplace = False
8885
8886    def calculate_constant_result(self):
8887        func = compile_time_binary_operators[self.operator]
8888        self.constant_result = func(
8889            self.operand1.constant_result,
8890            self.operand2.constant_result)
8891
8892    def compile_time_value(self, denv):
8893        func = get_compile_time_binop(self)
8894        operand1 = self.operand1.compile_time_value(denv)
8895        operand2 = self.operand2.compile_time_value(denv)
8896        try:
8897            return func(operand1, operand2)
8898        except Exception, e:
8899            self.compile_time_value_error(e)
8900
8901    def infer_type(self, env):
8902        return self.result_type(self.operand1.infer_type(env),
8903                                self.operand2.infer_type(env))
8904
8905    def analyse_types(self, env):
8906        self.operand1 = self.operand1.analyse_types(env)
8907        self.operand2 = self.operand2.analyse_types(env)
8908        self.analyse_operation(env)
8909        return self
8910
8911    def analyse_operation(self, env):
8912        if self.is_py_operation():
8913            self.coerce_operands_to_pyobjects(env)
8914            self.type = self.result_type(self.operand1.type,
8915                                         self.operand2.type)
8916            assert self.type.is_pyobject
8917            self.is_temp = 1
8918        elif self.is_cpp_operation():
8919            self.analyse_cpp_operation(env)
8920        else:
8921            self.analyse_c_operation(env)
8922
8923    def is_py_operation(self):
8924        return self.is_py_operation_types(self.operand1.type, self.operand2.type)
8925
8926    def is_py_operation_types(self, type1, type2):
8927        return type1.is_pyobject or type2.is_pyobject
8928
8929    def is_cpp_operation(self):
8930        return (self.operand1.type.is_cpp_class
8931            or self.operand2.type.is_cpp_class)
8932
8933    def analyse_cpp_operation(self, env):
8934        entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
8935        if not entry:
8936            self.type_error()
8937            return
8938        func_type = entry.type
8939        if func_type.is_ptr:
8940            func_type = func_type.base_type
8941        if len(func_type.args) == 1:
8942            self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
8943        else:
8944            self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
8945            self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
8946        self.type = func_type.return_type
8947
8948    def result_type(self, type1, type2):
8949        if self.is_py_operation_types(type1, type2):
8950            if type2.is_string:
8951                type2 = Builtin.bytes_type
8952            elif type2.is_pyunicode_ptr:
8953                type2 = Builtin.unicode_type
8954            if type1.is_string:
8955                type1 = Builtin.bytes_type
8956            elif type1.is_pyunicode_ptr:
8957                type1 = Builtin.unicode_type
8958            if type1.is_builtin_type or type2.is_builtin_type:
8959                if type1 is type2 and self.operator in '**%+|&^':
8960                    # FIXME: at least these operators should be safe - others?
8961                    return type1
8962                result_type = self.infer_builtin_types_operation(type1, type2)
8963                if result_type is not None:
8964                    return result_type
8965            return py_object_type
8966        else:
8967            return self.compute_c_result_type(type1, type2)
8968
8969    def infer_builtin_types_operation(self, type1, type2):
8970        return None
8971
8972    def nogil_check(self, env):
8973        if self.is_py_operation():
8974            self.gil_error()
8975
8976    def coerce_operands_to_pyobjects(self, env):
8977        self.operand1 = self.operand1.coerce_to_pyobject(env)
8978        self.operand2 = self.operand2.coerce_to_pyobject(env)
8979
8980    def check_const(self):
8981        return self.operand1.check_const() and self.operand2.check_const()
8982
8983    def generate_result_code(self, code):
8984        #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
8985        if self.operand1.type.is_pyobject:
8986            function = self.py_operation_function()
8987            if self.operator == '**':
8988                extra_args = ", Py_None"
8989            else:
8990                extra_args = ""
8991            code.putln(
8992                "%s = %s(%s, %s%s); %s" % (
8993                    self.result(),
8994                    function,
8995                    self.operand1.py_result(),
8996                    self.operand2.py_result(),
8997                    extra_args,
8998                    code.error_goto_if_null(self.result(), self.pos)))
8999            code.put_gotref(self.py_result())
9000        elif self.is_temp:
9001            code.putln("%s = %s;" % (self.result(), self.calculate_result_code()))
9002
9003    def type_error(self):
9004        if not (self.operand1.type.is_error
9005                or self.operand2.type.is_error):
9006            error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
9007                (self.operator, self.operand1.type,
9008                    self.operand2.type))
9009        self.type = PyrexTypes.error_type
9010
9011
9012class CBinopNode(BinopNode):
9013
9014    def analyse_types(self, env):
9015        node = BinopNode.analyse_types(self, env)
9016        if node.is_py_operation():
9017            node.type = PyrexTypes.error_type
9018        return node
9019
9020    def py_operation_function(self):
9021        return ""
9022
9023    def calculate_result_code(self):
9024        return "(%s %s %s)" % (
9025            self.operand1.result(),
9026            self.operator,
9027            self.operand2.result())
9028
9029    def compute_c_result_type(self, type1, type2):
9030        cpp_type = None
9031        if type1.is_cpp_class or type1.is_ptr:
9032            cpp_type = type1.find_cpp_operation_type(self.operator, type2)
9033        # FIXME: handle the reversed case?
9034        #if cpp_type is None and (type2.is_cpp_class or type2.is_ptr):
9035        #    cpp_type = type2.find_cpp_operation_type(self.operator, type1)
9036        # FIXME: do we need to handle other cases here?
9037        return cpp_type
9038
9039
9040def c_binop_constructor(operator):
9041    def make_binop_node(pos, **operands):
9042        return CBinopNode(pos, operator=operator, **operands)
9043    return make_binop_node
9044
9045class NumBinopNode(BinopNode):
9046    #  Binary operation taking numeric arguments.
9047
9048    infix = True
9049    overflow_check = False
9050    overflow_bit_node = None
9051
9052    def analyse_c_operation(self, env):
9053        type1 = self.operand1.type
9054        type2 = self.operand2.type
9055        self.type = self.compute_c_result_type(type1, type2)
9056        if not self.type:
9057            self.type_error()
9058            return
9059        if self.type.is_complex:
9060            self.infix = False
9061        if (self.type.is_int
9062                and env.directives['overflowcheck']
9063                and self.operator in self.overflow_op_names):
9064            if (self.operator in ('+', '*')
9065                    and self.operand1.has_constant_result()
9066                    and not self.operand2.has_constant_result()):
9067                self.operand1, self.operand2 = self.operand2, self.operand1
9068            self.overflow_check = True
9069            self.overflow_fold = env.directives['overflowcheck.fold']
9070            self.func = self.type.overflow_check_binop(
9071                self.overflow_op_names[self.operator],
9072                env,
9073                const_rhs = self.operand2.has_constant_result())
9074            self.is_temp = True
9075        if not self.infix or (type1.is_numeric and type2.is_numeric):
9076            self.operand1 = self.operand1.coerce_to(self.type, env)
9077            self.operand2 = self.operand2.coerce_to(self.type, env)
9078
9079    def compute_c_result_type(self, type1, type2):
9080        if self.c_types_okay(type1, type2):
9081            widest_type = PyrexTypes.widest_numeric_type(type1, type2)
9082            if widest_type is PyrexTypes.c_bint_type:
9083                if self.operator not in '|^&':
9084                    # False + False == 0 # not False!
9085                    widest_type = PyrexTypes.c_int_type
9086            else:
9087                widest_type = PyrexTypes.widest_numeric_type(
9088                    widest_type, PyrexTypes.c_int_type)
9089            return widest_type
9090        else:
9091            return None
9092
9093    def may_be_none(self):
9094        if self.type and self.type.is_builtin_type:
9095            # if we know the result type, we know the operation, so it can't be None
9096            return False
9097        type1 = self.operand1.type
9098        type2 = self.operand2.type
9099        if type1 and type1.is_builtin_type and type2 and type2.is_builtin_type:
9100            # XXX: I can't think of any case where a binary operation
9101            # on builtin types evaluates to None - add a special case
9102            # here if there is one.
9103            return False
9104        return super(NumBinopNode, self).may_be_none()
9105
9106    def get_constant_c_result_code(self):
9107        value1 = self.operand1.get_constant_c_result_code()
9108        value2 = self.operand2.get_constant_c_result_code()
9109        if value1 and value2:
9110            return "(%s %s %s)" % (value1, self.operator, value2)
9111        else:
9112            return None
9113
9114    def c_types_okay(self, type1, type2):
9115        #print "NumBinopNode.c_types_okay:", type1, type2 ###
9116        return (type1.is_numeric  or type1.is_enum) \
9117            and (type2.is_numeric  or type2.is_enum)
9118
9119    def generate_evaluation_code(self, code):
9120        if self.overflow_check:
9121            self.overflow_bit_node = self
9122            self.overflow_bit = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
9123            code.putln("%s = 0;" % self.overflow_bit)
9124        super(NumBinopNode, self).generate_evaluation_code(code)
9125        if self.overflow_check:
9126            code.putln("if (unlikely(%s)) {" % self.overflow_bit)
9127            code.putln('PyErr_SetString(PyExc_OverflowError, "value too large");')
9128            code.putln(code.error_goto(self.pos))
9129            code.putln("}")
9130            code.funcstate.release_temp(self.overflow_bit)
9131
9132    def calculate_result_code(self):
9133        if self.overflow_bit_node is not None:
9134            return "%s(%s, %s, &%s)" % (
9135                self.func,
9136                self.operand1.result(),
9137                self.operand2.result(),
9138                self.overflow_bit_node.overflow_bit)
9139        elif self.infix:
9140            return "(%s %s %s)" % (
9141                self.operand1.result(),
9142                self.operator,
9143                self.operand2.result())
9144        else:
9145            func = self.type.binary_op(self.operator)
9146            if func is None:
9147                error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
9148            return "%s(%s, %s)" % (
9149                func,
9150                self.operand1.result(),
9151                self.operand2.result())
9152
9153    def is_py_operation_types(self, type1, type2):
9154        return (type1.is_unicode_char or
9155                type2.is_unicode_char or
9156                BinopNode.is_py_operation_types(self, type1, type2))
9157
9158    def py_operation_function(self):
9159        function_name = self.py_functions[self.operator]
9160        if self.inplace:
9161            function_name = function_name.replace('PyNumber_', 'PyNumber_InPlace')
9162        return function_name
9163
9164    py_functions = {
9165        "|":        "PyNumber_Or",
9166        "^":        "PyNumber_Xor",
9167        "&":        "PyNumber_And",
9168        "<<":       "PyNumber_Lshift",
9169        ">>":       "PyNumber_Rshift",
9170        "+":        "PyNumber_Add",
9171        "-":        "PyNumber_Subtract",
9172        "*":        "PyNumber_Multiply",
9173        "/":        "__Pyx_PyNumber_Divide",
9174        "//":       "PyNumber_FloorDivide",
9175        "%":        "PyNumber_Remainder",
9176        "**":       "PyNumber_Power"
9177    }
9178
9179    overflow_op_names = {
9180        "+":  "add",
9181        "-":  "sub",
9182        "*":  "mul",
9183        "<<":  "lshift",
9184    }
9185
9186
9187class IntBinopNode(NumBinopNode):
9188    #  Binary operation taking integer arguments.
9189
9190    def c_types_okay(self, type1, type2):
9191        #print "IntBinopNode.c_types_okay:", type1, type2 ###
9192        return (type1.is_int or type1.is_enum) \
9193            and (type2.is_int or type2.is_enum)
9194
9195
9196class AddNode(NumBinopNode):
9197    #  '+' operator.
9198
9199    def is_py_operation_types(self, type1, type2):
9200        if type1.is_string and type2.is_string or type1.is_pyunicode_ptr and type2.is_pyunicode_ptr:
9201            return 1
9202        else:
9203            return NumBinopNode.is_py_operation_types(self, type1, type2)
9204
9205    def infer_builtin_types_operation(self, type1, type2):
9206        # b'abc' + 'abc' raises an exception in Py3,
9207        # so we can safely infer the Py2 type for bytes here
9208        string_types = [bytes_type, str_type, basestring_type, unicode_type]  # Py2.4 lacks tuple.index()
9209        if type1 in string_types and type2 in string_types:
9210            return string_types[max(string_types.index(type1),
9211                                    string_types.index(type2))]
9212        return None
9213
9214    def compute_c_result_type(self, type1, type2):
9215        #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
9216        if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
9217            return type1
9218        elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
9219            return type2
9220        else:
9221            return NumBinopNode.compute_c_result_type(
9222                self, type1, type2)
9223
9224    def py_operation_function(self):
9225        type1, type2 = self.operand1.type, self.operand2.type
9226        if type1 is unicode_type or type2 is unicode_type:
9227            if type1.is_builtin_type and type2.is_builtin_type:
9228                if self.operand1.may_be_none() or self.operand2.may_be_none():
9229                    return '__Pyx_PyUnicode_ConcatSafe'
9230                else:
9231                    return '__Pyx_PyUnicode_Concat'
9232        return super(AddNode, self).py_operation_function()
9233
9234
9235class SubNode(NumBinopNode):
9236    #  '-' operator.
9237
9238    def compute_c_result_type(self, type1, type2):
9239        if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
9240            return type1
9241        elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
9242            return PyrexTypes.c_ptrdiff_t_type
9243        else:
9244            return NumBinopNode.compute_c_result_type(
9245                self, type1, type2)
9246
9247
9248class MulNode(NumBinopNode):
9249    #  '*' operator.
9250
9251    def is_py_operation_types(self, type1, type2):
9252        if ((type1.is_string and type2.is_int) or
9253                (type2.is_string and type1.is_int)):
9254            return 1
9255        else:
9256            return NumBinopNode.is_py_operation_types(self, type1, type2)
9257
9258    def infer_builtin_types_operation(self, type1, type2):
9259        # let's assume that whatever builtin type you multiply a string with
9260        # will either return a string of the same type or fail with an exception
9261        string_types = (bytes_type, str_type, basestring_type, unicode_type)
9262        if type1 in string_types and type2.is_builtin_type:
9263            return type1
9264        if type2 in string_types and type1.is_builtin_type:
9265            return type2
9266        # multiplication of containers/numbers with an integer value
9267        # always (?) returns the same type
9268        if type1.is_int:
9269            return type2
9270        if type2.is_int:
9271            return type1
9272        return None
9273
9274
9275class DivNode(NumBinopNode):
9276    #  '/' or '//' operator.
9277
9278    cdivision = None
9279    truedivision = None   # == "unknown" if operator == '/'
9280    ctruedivision = False
9281    cdivision_warnings = False
9282    zerodivision_check = None
9283
9284    def find_compile_time_binary_operator(self, op1, op2):
9285        func = compile_time_binary_operators[self.operator]
9286        if self.operator == '/' and self.truedivision is None:
9287            # => true div for floats, floor div for integers
9288            if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
9289                func = compile_time_binary_operators['//']
9290        return func
9291
9292    def calculate_constant_result(self):
9293        op1 = self.operand1.constant_result
9294        op2 = self.operand2.constant_result
9295        func = self.find_compile_time_binary_operator(op1, op2)
9296        self.constant_result = func(
9297            self.operand1.constant_result,
9298            self.operand2.constant_result)
9299
9300    def compile_time_value(self, denv):
9301        operand1 = self.operand1.compile_time_value(denv)
9302        operand2 = self.operand2.compile_time_value(denv)
9303        try:
9304            func = self.find_compile_time_binary_operator(
9305                operand1, operand2)
9306            return func(operand1, operand2)
9307        except Exception, e:
9308            self.compile_time_value_error(e)
9309
9310    def analyse_operation(self, env):
9311        if self.cdivision or env.directives['cdivision']:
9312            self.ctruedivision = False
9313        else:
9314            self.ctruedivision = self.truedivision
9315        NumBinopNode.analyse_operation(self, env)
9316        if self.is_cpp_operation():
9317            self.cdivision = True
9318        if not self.type.is_pyobject:
9319            self.zerodivision_check = (
9320                self.cdivision is None and not env.directives['cdivision']
9321                and (not self.operand2.has_constant_result() or
9322                     self.operand2.constant_result == 0))
9323            if self.zerodivision_check or env.directives['cdivision_warnings']:
9324                # Need to check ahead of time to warn or raise zero division error
9325                self.operand1 = self.operand1.coerce_to_simple(env)
9326                self.operand2 = self.operand2.coerce_to_simple(env)
9327
9328    def compute_c_result_type(self, type1, type2):
9329        if self.operator == '/' and self.ctruedivision:
9330            if not type1.is_float and not type2.is_float:
9331                widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
9332                widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
9333                return widest_type
9334        return NumBinopNode.compute_c_result_type(self, type1, type2)
9335
9336    def zero_division_message(self):
9337        if self.type.is_int:
9338            return "integer division or modulo by zero"
9339        else:
9340            return "float division"
9341
9342    def generate_evaluation_code(self, code):
9343        if not self.type.is_pyobject and not self.type.is_complex:
9344            if self.cdivision is None:
9345                self.cdivision = (code.globalstate.directives['cdivision']
9346                                    or not self.type.signed
9347                                    or self.type.is_float)
9348            if not self.cdivision:
9349                code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
9350        NumBinopNode.generate_evaluation_code(self, code)
9351        self.generate_div_warning_code(code)
9352
9353    def generate_div_warning_code(self, code):
9354        if not self.type.is_pyobject:
9355            if self.zerodivision_check:
9356                if not self.infix:
9357                    zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
9358                else:
9359                    zero_test = "%s == 0" % self.operand2.result()
9360                code.putln("if (unlikely(%s)) {" % zero_test)
9361                code.put_ensure_gil()
9362                code.putln('PyErr_SetString(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
9363                code.put_release_ensured_gil()
9364                code.putln(code.error_goto(self.pos))
9365                code.putln("}")
9366                if self.type.is_int and self.type.signed and self.operator != '%':
9367                    code.globalstate.use_utility_code(division_overflow_test_code)
9368                    if self.operand2.type.signed == 2:
9369                        # explicitly signed, no runtime check needed
9370                        minus1_check = 'unlikely(%s == -1)' % self.operand2.result()
9371                    else:
9372                        type_of_op2 = self.operand2.type.declaration_code('')
9373                        minus1_check = '(!(((%s)-1) > 0)) && unlikely(%s == (%s)-1)' % (
9374                            type_of_op2, self.operand2.result(), type_of_op2)
9375                    code.putln("else if (sizeof(%s) == sizeof(long) && %s "
9376                               " && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
9377                               self.type.declaration_code(''),
9378                               minus1_check,
9379                               self.operand1.result()))
9380                    code.put_ensure_gil()
9381                    code.putln('PyErr_SetString(PyExc_OverflowError, "value too large to perform division");')
9382                    code.put_release_ensured_gil()
9383                    code.putln(code.error_goto(self.pos))
9384                    code.putln("}")
9385            if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
9386                code.globalstate.use_utility_code(cdivision_warning_utility_code)
9387                code.putln("if (unlikely((%s < 0) ^ (%s < 0))) {" % (
9388                                self.operand1.result(),
9389                                self.operand2.result()))
9390                code.put_ensure_gil()
9391                code.putln(code.set_error_info(self.pos, used=True))
9392                code.putln("if (__Pyx_cdivision_warning(%(FILENAME)s, "
9393                                                       "%(LINENO)s)) {" % {
9394                    'FILENAME': Naming.filename_cname,
9395                    'LINENO':  Naming.lineno_cname,
9396                    })
9397                code.put_release_ensured_gil()
9398                code.put_goto(code.error_label)
9399                code.putln("}")
9400                code.put_release_ensured_gil()
9401                code.putln("}")
9402
9403    def calculate_result_code(self):
9404        if self.type.is_complex:
9405            return NumBinopNode.calculate_result_code(self)
9406        elif self.type.is_float and self.operator == '//':
9407            return "floor(%s / %s)" % (
9408                self.operand1.result(),
9409                self.operand2.result())
9410        elif self.truedivision or self.cdivision:
9411            op1 = self.operand1.result()
9412            op2 = self.operand2.result()
9413            if self.truedivision:
9414                if self.type != self.operand1.type:
9415                    op1 = self.type.cast_code(op1)
9416                if self.type != self.operand2.type:
9417                    op2 = self.type.cast_code(op2)
9418            return "(%s / %s)" % (op1, op2)
9419        else:
9420            return "__Pyx_div_%s(%s, %s)" % (
9421                self.type.specialization_name(),
9422                self.operand1.result(),
9423                self.operand2.result())
9424
9425
9426class ModNode(DivNode):
9427    #  '%' operator.
9428
9429    def is_py_operation_types(self, type1, type2):
9430        return (type1.is_string
9431                or type2.is_string
9432                or NumBinopNode.is_py_operation_types(self, type1, type2))
9433
9434    def infer_builtin_types_operation(self, type1, type2):
9435        # b'%s' % xyz  raises an exception in Py3, so it's safe to infer the type for Py2
9436        if type1 is unicode_type:
9437            # None + xyz  may be implemented by RHS
9438            if type2.is_builtin_type or not self.operand1.may_be_none():
9439                return type1
9440        elif type1 in (bytes_type, str_type, basestring_type):
9441            if type2 is unicode_type:
9442                return type2
9443            elif type2.is_numeric:
9444                return type1
9445            elif type1 is bytes_type and not type2.is_builtin_type:
9446                return None   # RHS might implement '% operator differently in Py3
9447            else:
9448                return basestring_type  # either str or unicode, can't tell
9449        return None
9450
9451    def zero_division_message(self):
9452        if self.type.is_int:
9453            return "integer division or modulo by zero"
9454        else:
9455            return "float divmod()"
9456
9457    def analyse_operation(self, env):
9458        DivNode.analyse_operation(self, env)
9459        if not self.type.is_pyobject:
9460            if self.cdivision is None:
9461                self.cdivision = env.directives['cdivision'] or not self.type.signed
9462            if not self.cdivision and not self.type.is_int and not self.type.is_float:
9463                error(self.pos, "mod operator not supported for type '%s'" % self.type)
9464
9465    def generate_evaluation_code(self, code):
9466        if not self.type.is_pyobject and not self.cdivision:
9467            if self.type.is_int:
9468                code.globalstate.use_utility_code(
9469                    mod_int_utility_code.specialize(self.type))
9470            else:  # float
9471                code.globalstate.use_utility_code(
9472                    mod_float_utility_code.specialize(
9473                        self.type, math_h_modifier=self.type.math_h_modifier))
9474        # note: skipping over DivNode here
9475        NumBinopNode.generate_evaluation_code(self, code)
9476        self.generate_div_warning_code(code)
9477
9478    def calculate_result_code(self):
9479        if self.cdivision:
9480            if self.type.is_float:
9481                return "fmod%s(%s, %s)" % (
9482                    self.type.math_h_modifier,
9483                    self.operand1.result(),
9484                    self.operand2.result())
9485            else:
9486                return "(%s %% %s)" % (
9487                    self.operand1.result(),
9488                    self.operand2.result())
9489        else:
9490            return "__Pyx_mod_%s(%s, %s)" % (
9491                    self.type.specialization_name(),
9492                    self.operand1.result(),
9493                    self.operand2.result())
9494
9495    def py_operation_function(self):
9496        if self.operand1.type is unicode_type:
9497            if self.operand1.may_be_none():
9498                return '__Pyx_PyUnicode_FormatSafe'
9499            else:
9500                return 'PyUnicode_Format'
9501        elif self.operand1.type is str_type:
9502            if self.operand1.may_be_none():
9503                return '__Pyx_PyString_FormatSafe'
9504            else:
9505                return '__Pyx_PyString_Format'
9506        return super(ModNode, self).py_operation_function()
9507
9508
9509class PowNode(NumBinopNode):
9510    #  '**' operator.
9511
9512    def analyse_c_operation(self, env):
9513        NumBinopNode.analyse_c_operation(self, env)
9514        if self.type.is_complex:
9515            if self.type.real_type.is_float:
9516                self.operand1 = self.operand1.coerce_to(self.type, env)
9517                self.operand2 = self.operand2.coerce_to(self.type, env)
9518                self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
9519            else:
9520                error(self.pos, "complex int powers not supported")
9521                self.pow_func = "<error>"
9522        elif self.type.is_float:
9523            self.pow_func = "pow" + self.type.math_h_modifier
9524        elif self.type.is_int:
9525            self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
9526            env.use_utility_code(
9527                int_pow_utility_code.specialize(
9528                    func_name=self.pow_func,
9529                    type=self.type.declaration_code(''),
9530                    signed=self.type.signed and 1 or 0))
9531        elif not self.type.is_error:
9532            error(self.pos, "got unexpected types for C power operator: %s, %s" %
9533                            (self.operand1.type, self.operand2.type))
9534
9535    def calculate_result_code(self):
9536        # Work around MSVC overloading ambiguity.
9537        def typecast(operand):
9538            if self.type == operand.type:
9539                return operand.result()
9540            else:
9541                return self.type.cast_code(operand.result())
9542        return "%s(%s, %s)" % (
9543            self.pow_func,
9544            typecast(self.operand1),
9545            typecast(self.operand2))
9546
9547
9548# Note: This class is temporarily "shut down" into an ineffective temp
9549# allocation mode.
9550#
9551# More sophisticated temp reuse was going on before, one could have a
9552# look at adding this again after /all/ classes are converted to the
9553# new temp scheme. (The temp juggling cannot work otherwise).
9554class BoolBinopNode(ExprNode):
9555    #  Short-circuiting boolean operation.
9556    #
9557    #  operator     string
9558    #  operand1     ExprNode
9559    #  operand2     ExprNode
9560
9561    subexprs = ['operand1', 'operand2']
9562
9563    def infer_type(self, env):
9564        type1 = self.operand1.infer_type(env)
9565        type2 = self.operand2.infer_type(env)
9566        return PyrexTypes.independent_spanning_type(type1, type2)
9567
9568    def may_be_none(self):
9569        if self.operator == 'or':
9570            return self.operand2.may_be_none()
9571        else:
9572            return self.operand1.may_be_none() or self.operand2.may_be_none()
9573
9574    def calculate_constant_result(self):
9575        if self.operator == 'and':
9576            self.constant_result = \
9577                self.operand1.constant_result and \
9578                self.operand2.constant_result
9579        else:
9580            self.constant_result = \
9581                self.operand1.constant_result or \
9582                self.operand2.constant_result
9583
9584    def compile_time_value(self, denv):
9585        if self.operator == 'and':
9586            return self.operand1.compile_time_value(denv) \
9587                and self.operand2.compile_time_value(denv)
9588        else:
9589            return self.operand1.compile_time_value(denv) \
9590                or self.operand2.compile_time_value(denv)
9591
9592    def coerce_to_boolean(self, env):
9593        return BoolBinopNode(
9594            self.pos,
9595            operator = self.operator,
9596            operand1 = self.operand1.coerce_to_boolean(env),
9597            operand2 = self.operand2.coerce_to_boolean(env),
9598            type = PyrexTypes.c_bint_type,
9599            is_temp = self.is_temp)
9600
9601    def analyse_types(self, env):
9602        self.operand1 = self.operand1.analyse_types(env)
9603        self.operand2 = self.operand2.analyse_types(env)
9604        self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
9605        self.operand1 = self.operand1.coerce_to(self.type, env)
9606        self.operand2 = self.operand2.coerce_to(self.type, env)
9607
9608        # For what we're about to do, it's vital that
9609        # both operands be temp nodes.
9610        self.operand1 = self.operand1.coerce_to_simple(env)
9611        self.operand2 = self.operand2.coerce_to_simple(env)
9612        self.is_temp = 1
9613        return self
9614
9615    gil_message = "Truth-testing Python object"
9616
9617    def check_const(self):
9618        return self.operand1.check_const() and self.operand2.check_const()
9619
9620    def generate_evaluation_code(self, code):
9621        code.mark_pos(self.pos)
9622        self.operand1.generate_evaluation_code(code)
9623        test_result, uses_temp = self.generate_operand1_test(code)
9624        if self.operator == 'and':
9625            sense = ""
9626        else:
9627            sense = "!"
9628        code.putln(
9629            "if (%s%s) {" % (
9630                sense,
9631                test_result))
9632        if uses_temp:
9633            code.funcstate.release_temp(test_result)
9634        self.operand1.generate_disposal_code(code)
9635        self.operand2.generate_evaluation_code(code)
9636        self.allocate_temp_result(code)
9637        self.operand2.make_owned_reference(code)
9638        code.putln("%s = %s;" % (self.result(), self.operand2.result()))
9639        self.operand2.generate_post_assignment_code(code)
9640        self.operand2.free_temps(code)
9641        code.putln("} else {")
9642        self.operand1.make_owned_reference(code)
9643        code.putln("%s = %s;" % (self.result(), self.operand1.result()))
9644        self.operand1.generate_post_assignment_code(code)
9645        self.operand1.free_temps(code)
9646        code.putln("}")
9647
9648    def generate_operand1_test(self, code):
9649        #  Generate code to test the truth of the first operand.
9650        if self.type.is_pyobject:
9651            test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
9652                                                       manage_ref=False)
9653            code.putln(
9654                "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
9655                    test_result,
9656                    self.operand1.py_result(),
9657                    code.error_goto_if_neg(test_result, self.pos)))
9658        else:
9659            test_result = self.operand1.result()
9660        return (test_result, self.type.is_pyobject)
9661
9662
9663class CondExprNode(ExprNode):
9664    #  Short-circuiting conditional expression.
9665    #
9666    #  test        ExprNode
9667    #  true_val    ExprNode
9668    #  false_val   ExprNode
9669
9670    true_val = None
9671    false_val = None
9672
9673    subexprs = ['test', 'true_val', 'false_val']
9674
9675    def type_dependencies(self, env):
9676        return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
9677
9678    def infer_type(self, env):
9679        return PyrexTypes.independent_spanning_type(
9680            self.true_val.infer_type(env),
9681            self.false_val.infer_type(env))
9682
9683    def calculate_constant_result(self):
9684        if self.test.constant_result:
9685            self.constant_result = self.true_val.constant_result
9686        else:
9687            self.constant_result = self.false_val.constant_result
9688
9689    def analyse_types(self, env):
9690        self.test = self.test.analyse_types(env).coerce_to_boolean(env)
9691        self.true_val = self.true_val.analyse_types(env)
9692        self.false_val = self.false_val.analyse_types(env)
9693        self.is_temp = 1
9694        return self.analyse_result_type(env)
9695
9696    def analyse_result_type(self, env):
9697        self.type = PyrexTypes.independent_spanning_type(
9698            self.true_val.type, self.false_val.type)
9699        if self.type.is_pyobject:
9700            self.result_ctype = py_object_type
9701        if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
9702            self.true_val = self.true_val.coerce_to(self.type, env)
9703            self.false_val = self.false_val.coerce_to(self.type, env)
9704        if self.type == PyrexTypes.error_type:
9705            self.type_error()
9706        return self
9707
9708    def coerce_to(self, dst_type, env):
9709        self.true_val = self.true_val.coerce_to(dst_type, env)
9710        self.false_val = self.false_val.coerce_to(dst_type, env)
9711        self.result_ctype = None
9712        return self.analyse_result_type(env)
9713
9714    def type_error(self):
9715        if not (self.true_val.type.is_error or self.false_val.type.is_error):
9716            error(self.pos, "Incompatible types in conditional expression (%s; %s)" %
9717                (self.true_val.type, self.false_val.type))
9718        self.type = PyrexTypes.error_type
9719
9720    def check_const(self):
9721        return (self.test.check_const()
9722            and self.true_val.check_const()
9723            and self.false_val.check_const())
9724
9725    def generate_evaluation_code(self, code):
9726        # Because subexprs may not be evaluated we can use a more optimal
9727        # subexpr allocation strategy than the default, so override evaluation_code.
9728
9729        code.mark_pos(self.pos)
9730        self.allocate_temp_result(code)
9731        self.test.generate_evaluation_code(code)
9732        code.putln("if (%s) {" % self.test.result() )
9733        self.eval_and_get(code, self.true_val)
9734        code.putln("} else {")
9735        self.eval_and_get(code, self.false_val)
9736        code.putln("}")
9737        self.test.generate_disposal_code(code)
9738        self.test.free_temps(code)
9739
9740    def eval_and_get(self, code, expr):
9741        expr.generate_evaluation_code(code)
9742        expr.make_owned_reference(code)
9743        code.putln('%s = %s;' % (self.result(), expr.result_as(self.ctype())))
9744        expr.generate_post_assignment_code(code)
9745        expr.free_temps(code)
9746
9747richcmp_constants = {
9748    "<" : "Py_LT",
9749    "<=": "Py_LE",
9750    "==": "Py_EQ",
9751    "!=": "Py_NE",
9752    "<>": "Py_NE",
9753    ">" : "Py_GT",
9754    ">=": "Py_GE",
9755    # the following are faked by special compare functions
9756    "in"    : "Py_EQ",
9757    "not_in": "Py_NE",
9758}
9759
9760class CmpNode(object):
9761    #  Mixin class containing code common to PrimaryCmpNodes
9762    #  and CascadedCmpNodes.
9763
9764    special_bool_cmp_function = None
9765    special_bool_cmp_utility_code = None
9766
9767    def infer_type(self, env):
9768        # TODO: Actually implement this (after merging with -unstable).
9769        return py_object_type
9770
9771    def calculate_cascaded_constant_result(self, operand1_result):
9772        func = compile_time_binary_operators[self.operator]
9773        operand2_result = self.operand2.constant_result
9774        if (isinstance(operand1_result, (bytes, unicode)) and
9775                isinstance(operand2_result, (bytes, unicode)) and
9776                type(operand1_result) != type(operand2_result)):
9777            # string comparison of different types isn't portable
9778            return
9779
9780        if self.operator in ('in', 'not_in'):
9781            if isinstance(self.operand2, (ListNode, TupleNode, SetNode)):
9782                if not self.operand2.args:
9783                    self.constant_result = self.operator == 'not_in'
9784                    return
9785                elif isinstance(self.operand2, ListNode) and not self.cascade:
9786                    # tuples are more efficient to store than lists
9787                    self.operand2 = self.operand2.as_tuple()
9788            elif isinstance(self.operand2, DictNode):
9789                if not self.operand2.key_value_pairs:
9790                    self.constant_result = self.operator == 'not_in'
9791                    return
9792
9793        self.constant_result = func(operand1_result, operand2_result)
9794
9795    def cascaded_compile_time_value(self, operand1, denv):
9796        func = get_compile_time_binop(self)
9797        operand2 = self.operand2.compile_time_value(denv)
9798        try:
9799            result = func(operand1, operand2)
9800        except Exception, e:
9801            self.compile_time_value_error(e)
9802            result = None
9803        if result:
9804            cascade = self.cascade
9805            if cascade:
9806                result = result and cascade.cascaded_compile_time_value(operand2, denv)
9807        return result
9808
9809    def is_cpp_comparison(self):
9810        return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
9811
9812    def find_common_int_type(self, env, op, operand1, operand2):
9813        # type1 != type2 and at least one of the types is not a C int
9814        type1 = operand1.type
9815        type2 = operand2.type
9816        type1_can_be_int = False
9817        type2_can_be_int = False
9818
9819        if operand1.is_string_literal and operand1.can_coerce_to_char_literal():
9820            type1_can_be_int = True
9821        if operand2.is_string_literal and operand2.can_coerce_to_char_literal():
9822            type2_can_be_int = True
9823
9824        if type1.is_int:
9825            if type2_can_be_int:
9826                return type1
9827        elif type2.is_int:
9828            if type1_can_be_int:
9829                return type2
9830        elif type1_can_be_int:
9831            if type2_can_be_int:
9832                if Builtin.unicode_type in (type1, type2):
9833                    return PyrexTypes.c_py_ucs4_type
9834                else:
9835                    return PyrexTypes.c_uchar_type
9836
9837        return None
9838
9839    def find_common_type(self, env, op, operand1, common_type=None):
9840        operand2 = self.operand2
9841        type1 = operand1.type
9842        type2 = operand2.type
9843
9844        new_common_type = None
9845
9846        # catch general errors
9847        if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
9848               type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
9849            error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
9850            new_common_type = error_type
9851
9852        # try to use numeric comparisons where possible
9853        elif type1.is_complex or type2.is_complex:
9854            if op not in ('==', '!=') \
9855               and (type1.is_complex or type1.is_numeric) \
9856               and (type2.is_complex or type2.is_numeric):
9857                error(self.pos, "complex types are unordered")
9858                new_common_type = error_type
9859            elif type1.is_pyobject:
9860                new_common_type = type1
9861            elif type2.is_pyobject:
9862                new_common_type = type2
9863            else:
9864                new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
9865        elif type1.is_numeric and type2.is_numeric:
9866            new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
9867        elif common_type is None or not common_type.is_pyobject:
9868            new_common_type = self.find_common_int_type(env, op, operand1, operand2)
9869
9870        if new_common_type is None:
9871            # fall back to generic type compatibility tests
9872            if type1 == type2:
9873                new_common_type = type1
9874            elif type1.is_pyobject or type2.is_pyobject:
9875                if type2.is_numeric or type2.is_string:
9876                    if operand2.check_for_coercion_error(type1, env):
9877                        new_common_type = error_type
9878                    else:
9879                        new_common_type = py_object_type
9880                elif type1.is_numeric or type1.is_string:
9881                    if operand1.check_for_coercion_error(type2, env):
9882                        new_common_type = error_type
9883                    else:
9884                        new_common_type = py_object_type
9885                elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
9886                    new_common_type = py_object_type
9887                else:
9888                    # one Python type and one non-Python type, not assignable
9889                    self.invalid_types_error(operand1, op, operand2)
9890                    new_common_type = error_type
9891            elif type1.assignable_from(type2):
9892                new_common_type = type1
9893            elif type2.assignable_from(type1):
9894                new_common_type = type2
9895            else:
9896                # C types that we couldn't handle up to here are an error
9897                self.invalid_types_error(operand1, op, operand2)
9898                new_common_type = error_type
9899
9900        if new_common_type.is_string and (isinstance(operand1, BytesNode) or
9901                                          isinstance(operand2, BytesNode)):
9902            # special case when comparing char* to bytes literal: must
9903            # compare string values!
9904            new_common_type = bytes_type
9905
9906        # recursively merge types
9907        if common_type is None or new_common_type.is_error:
9908            common_type = new_common_type
9909        else:
9910            # we could do a lot better by splitting the comparison
9911            # into a non-Python part and a Python part, but this is
9912            # safer for now
9913            common_type = PyrexTypes.spanning_type(common_type, new_common_type)
9914
9915        if self.cascade:
9916            common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
9917
9918        return common_type
9919
9920    def invalid_types_error(self, operand1, op, operand2):
9921        error(self.pos, "Invalid types for '%s' (%s, %s)" %
9922              (op, operand1.type, operand2.type))
9923
9924    def is_python_comparison(self):
9925        return (not self.is_ptr_contains()
9926            and not self.is_c_string_contains()
9927            and (self.has_python_operands()
9928                 or (self.cascade and self.cascade.is_python_comparison())
9929                 or self.operator in ('in', 'not_in')))
9930
9931    def coerce_operands_to(self, dst_type, env):
9932        operand2 = self.operand2
9933        if operand2.type != dst_type:
9934            self.operand2 = operand2.coerce_to(dst_type, env)
9935        if self.cascade:
9936            self.cascade.coerce_operands_to(dst_type, env)
9937
9938    def is_python_result(self):
9939        return ((self.has_python_operands() and
9940                 self.special_bool_cmp_function is None and
9941                 self.operator not in ('is', 'is_not', 'in', 'not_in') and
9942                 not self.is_c_string_contains() and
9943                 not self.is_ptr_contains())
9944            or (self.cascade and self.cascade.is_python_result()))
9945
9946    def is_c_string_contains(self):
9947        return self.operator in ('in', 'not_in') and \
9948               ((self.operand1.type.is_int
9949                 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
9950                (self.operand1.type.is_unicode_char
9951                 and self.operand2.type is unicode_type))
9952
9953    def is_ptr_contains(self):
9954        if self.operator in ('in', 'not_in'):
9955            container_type = self.operand2.type
9956            return (container_type.is_ptr or container_type.is_array) \
9957                and not container_type.is_string
9958
9959    def find_special_bool_compare_function(self, env, operand1, result_is_bool=False):
9960        # note: currently operand1 must get coerced to a Python object if we succeed here!
9961        if self.operator in ('==', '!='):
9962            type1, type2 = operand1.type, self.operand2.type
9963            if result_is_bool or (type1.is_builtin_type and type2.is_builtin_type):
9964                if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
9965                    self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
9966                    self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
9967                    return True
9968                elif type1 is Builtin.bytes_type or type2 is Builtin.bytes_type:
9969                    self.special_bool_cmp_utility_code = UtilityCode.load_cached("BytesEquals", "StringTools.c")
9970                    self.special_bool_cmp_function = "__Pyx_PyBytes_Equals"
9971                    return True
9972                elif type1 is Builtin.basestring_type or type2 is Builtin.basestring_type:
9973                    self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
9974                    self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
9975                    return True
9976                elif type1 is Builtin.str_type or type2 is Builtin.str_type:
9977                    self.special_bool_cmp_utility_code = UtilityCode.load_cached("StrEquals", "StringTools.c")
9978                    self.special_bool_cmp_function = "__Pyx_PyString_Equals"
9979                    return True
9980        elif self.operator in ('in', 'not_in'):
9981            if self.operand2.type is Builtin.dict_type:
9982                self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
9983                self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyDictContains", "ObjectHandling.c")
9984                self.special_bool_cmp_function = "__Pyx_PyDict_Contains"
9985                return True
9986            elif self.operand2.type is Builtin.unicode_type:
9987                self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
9988                self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyUnicodeContains", "StringTools.c")
9989                self.special_bool_cmp_function = "__Pyx_PyUnicode_Contains"
9990                return True
9991            else:
9992                if not self.operand2.type.is_pyobject:
9993                    self.operand2 = self.operand2.coerce_to_pyobject(env)
9994                self.special_bool_cmp_utility_code = UtilityCode.load_cached("PySequenceContains", "ObjectHandling.c")
9995                self.special_bool_cmp_function = "__Pyx_PySequence_Contains"
9996                return True
9997        return False
9998
9999    def generate_operation_code(self, code, result_code,
10000            operand1, op , operand2):
10001        if self.type.is_pyobject:
10002            error_clause = code.error_goto_if_null
10003            got_ref = "__Pyx_XGOTREF(%s); " % result_code
10004            if self.special_bool_cmp_function:
10005                code.globalstate.use_utility_code(
10006                    UtilityCode.load_cached("PyBoolOrNullFromLong", "ObjectHandling.c"))
10007                coerce_result = "__Pyx_PyBoolOrNull_FromLong"
10008            else:
10009                coerce_result = "__Pyx_PyBool_FromLong"
10010        else:
10011            error_clause = code.error_goto_if_neg
10012            got_ref = ""
10013            coerce_result = ""
10014
10015        if self.special_bool_cmp_function:
10016            if operand1.type.is_pyobject:
10017                result1 = operand1.py_result()
10018            else:
10019                result1 = operand1.result()
10020            if operand2.type.is_pyobject:
10021                result2 = operand2.py_result()
10022            else:
10023                result2 = operand2.result()
10024            if self.special_bool_cmp_utility_code:
10025                code.globalstate.use_utility_code(self.special_bool_cmp_utility_code)
10026            code.putln(
10027                "%s = %s(%s(%s, %s, %s)); %s%s" % (
10028                    result_code,
10029                    coerce_result,
10030                    self.special_bool_cmp_function,
10031                    result1, result2, richcmp_constants[op],
10032                    got_ref,
10033                    error_clause(result_code, self.pos)))
10034
10035        elif operand1.type.is_pyobject and op not in ('is', 'is_not'):
10036            assert op not in ('in', 'not_in'), op
10037            code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s%s" % (
10038                    result_code,
10039                    operand1.py_result(),
10040                    operand2.py_result(),
10041                    richcmp_constants[op],
10042                    got_ref,
10043                    error_clause(result_code, self.pos)))
10044
10045        elif operand1.type.is_complex:
10046            code.putln("%s = %s(%s%s(%s, %s));" % (
10047                result_code,
10048                coerce_result,
10049                op == "!=" and "!" or "",
10050                operand1.type.unary_op('eq'),
10051                operand1.result(),
10052                operand2.result()))
10053
10054        else:
10055            type1 = operand1.type
10056            type2 = operand2.type
10057            if (type1.is_extension_type or type2.is_extension_type) \
10058                    and not type1.same_as(type2):
10059                common_type = py_object_type
10060            elif type1.is_numeric:
10061                common_type = PyrexTypes.widest_numeric_type(type1, type2)
10062            else:
10063                common_type = type1
10064            code1 = operand1.result_as(common_type)
10065            code2 = operand2.result_as(common_type)
10066            code.putln("%s = %s(%s %s %s);" % (
10067                result_code,
10068                coerce_result,
10069                code1,
10070                self.c_operator(op),
10071                code2))
10072
10073    def c_operator(self, op):
10074        if op == 'is':
10075            return "=="
10076        elif op == 'is_not':
10077            return "!="
10078        else:
10079            return op
10080
10081class PrimaryCmpNode(ExprNode, CmpNode):
10082    #  Non-cascaded comparison or first comparison of
10083    #  a cascaded sequence.
10084    #
10085    #  operator      string
10086    #  operand1      ExprNode
10087    #  operand2      ExprNode
10088    #  cascade       CascadedCmpNode
10089
10090    #  We don't use the subexprs mechanism, because
10091    #  things here are too complicated for it to handle.
10092    #  Instead, we override all the framework methods
10093    #  which use it.
10094
10095    child_attrs = ['operand1', 'operand2', 'coerced_operand2', 'cascade']
10096
10097    cascade = None
10098    coerced_operand2 = None
10099    is_memslice_nonecheck = False
10100
10101    def infer_type(self, env):
10102        # TODO: Actually implement this (after merging with -unstable).
10103        return py_object_type
10104
10105    def type_dependencies(self, env):
10106        return ()
10107
10108    def calculate_constant_result(self):
10109        assert not self.cascade
10110        self.calculate_cascaded_constant_result(self.operand1.constant_result)
10111
10112    def compile_time_value(self, denv):
10113        operand1 = self.operand1.compile_time_value(denv)
10114        return self.cascaded_compile_time_value(operand1, denv)
10115
10116    def analyse_types(self, env):
10117        self.operand1 = self.operand1.analyse_types(env)
10118        self.operand2 = self.operand2.analyse_types(env)
10119        if self.is_cpp_comparison():
10120            self.analyse_cpp_comparison(env)
10121            if self.cascade:
10122                error(self.pos, "Cascading comparison not yet supported for cpp types.")
10123            return self
10124
10125        if self.analyse_memoryviewslice_comparison(env):
10126            return self
10127
10128        if self.cascade:
10129            self.cascade = self.cascade.analyse_types(env)
10130
10131        if self.operator in ('in', 'not_in'):
10132            if self.is_c_string_contains():
10133                self.is_pycmp = False
10134                common_type = None
10135                if self.cascade:
10136                    error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
10137                    return self
10138                if self.operand2.type is unicode_type:
10139                    env.use_utility_code(UtilityCode.load_cached("PyUCS4InUnicode", "StringTools.c"))
10140                else:
10141                    if self.operand1.type is PyrexTypes.c_uchar_type:
10142                        self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
10143                    if self.operand2.type is not bytes_type:
10144                        self.operand2 = self.operand2.coerce_to(bytes_type, env)
10145                    env.use_utility_code(UtilityCode.load_cached("BytesContains", "StringTools.c"))
10146                self.operand2 = self.operand2.as_none_safe_node(
10147                    "argument of type 'NoneType' is not iterable")
10148            elif self.is_ptr_contains():
10149                if self.cascade:
10150                    error(self.pos, "Cascading comparison not supported for 'val in sliced pointer'.")
10151                self.type = PyrexTypes.c_bint_type
10152                # Will be transformed by IterationTransform
10153                return self
10154            elif self.find_special_bool_compare_function(env, self.operand1):
10155                if not self.operand1.type.is_pyobject:
10156                    self.operand1 = self.operand1.coerce_to_pyobject(env)
10157                common_type = None # if coercion needed, the method call above has already done it
10158                self.is_pycmp = False # result is bint
10159            else:
10160                common_type = py_object_type
10161                self.is_pycmp = True
10162        elif self.find_special_bool_compare_function(env, self.operand1):
10163            if not self.operand1.type.is_pyobject:
10164                self.operand1 = self.operand1.coerce_to_pyobject(env)
10165            common_type = None # if coercion needed, the method call above has already done it
10166            self.is_pycmp = False # result is bint
10167        else:
10168            common_type = self.find_common_type(env, self.operator, self.operand1)
10169            self.is_pycmp = common_type.is_pyobject
10170
10171        if common_type is not None and not common_type.is_error:
10172            if self.operand1.type != common_type:
10173                self.operand1 = self.operand1.coerce_to(common_type, env)
10174            self.coerce_operands_to(common_type, env)
10175
10176        if self.cascade:
10177            self.operand2 = self.operand2.coerce_to_simple(env)
10178            self.cascade.coerce_cascaded_operands_to_temp(env)
10179            operand2 = self.cascade.optimise_comparison(self.operand2, env)
10180            if operand2 is not self.operand2:
10181                self.coerced_operand2 = operand2
10182        if self.is_python_result():
10183            self.type = PyrexTypes.py_object_type
10184        else:
10185            self.type = PyrexTypes.c_bint_type
10186        cdr = self.cascade
10187        while cdr:
10188            cdr.type = self.type
10189            cdr = cdr.cascade
10190        if self.is_pycmp or self.cascade or self.special_bool_cmp_function:
10191            # 1) owned reference, 2) reused value, 3) potential function error return value
10192            self.is_temp = 1
10193        return self
10194
10195    def analyse_cpp_comparison(self, env):
10196        type1 = self.operand1.type
10197        type2 = self.operand2.type
10198        entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
10199        if entry is None:
10200            error(self.pos, "Invalid types for '%s' (%s, %s)" %
10201                (self.operator, type1, type2))
10202            self.type = PyrexTypes.error_type
10203            self.result_code = "<error>"
10204            return
10205        func_type = entry.type
10206        if func_type.is_ptr:
10207            func_type = func_type.base_type
10208        if len(func_type.args) == 1:
10209            self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
10210        else:
10211            self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
10212            self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
10213        self.is_pycmp = False
10214        self.type = func_type.return_type
10215
10216    def analyse_memoryviewslice_comparison(self, env):
10217        have_none = self.operand1.is_none or self.operand2.is_none
10218        have_slice = (self.operand1.type.is_memoryviewslice or
10219                      self.operand2.type.is_memoryviewslice)
10220        ops = ('==', '!=', 'is', 'is_not')
10221        if have_slice and have_none and self.operator in ops:
10222            self.is_pycmp = False
10223            self.type = PyrexTypes.c_bint_type
10224            self.is_memslice_nonecheck = True
10225            return True
10226
10227        return False
10228
10229    def coerce_to_boolean(self, env):
10230        if self.is_pycmp:
10231            # coercing to bool => may allow for more efficient comparison code
10232            if self.find_special_bool_compare_function(
10233                    env, self.operand1, result_is_bool=True):
10234                self.is_pycmp = False
10235                self.type = PyrexTypes.c_bint_type
10236                self.is_temp = 1
10237                if self.cascade:
10238                    operand2 = self.cascade.optimise_comparison(
10239                        self.operand2, env, result_is_bool=True)
10240                    if operand2 is not self.operand2:
10241                        self.coerced_operand2 = operand2
10242                return self
10243        # TODO: check if we can optimise parts of the cascade here
10244        return ExprNode.coerce_to_boolean(self, env)
10245
10246    def has_python_operands(self):
10247        return (self.operand1.type.is_pyobject
10248            or self.operand2.type.is_pyobject)
10249
10250    def check_const(self):
10251        if self.cascade:
10252            self.not_const()
10253            return False
10254        else:
10255            return self.operand1.check_const() and self.operand2.check_const()
10256
10257    def calculate_result_code(self):
10258        if self.operand1.type.is_complex:
10259            if self.operator == "!=":
10260                negation = "!"
10261            else:
10262                negation = ""
10263            return "(%s%s(%s, %s))" % (
10264                negation,
10265                self.operand1.type.binary_op('=='),
10266                self.operand1.result(),
10267                self.operand2.result())
10268        elif self.is_c_string_contains():
10269            if self.operand2.type is unicode_type:
10270                method = "__Pyx_UnicodeContainsUCS4"
10271            else:
10272                method = "__Pyx_BytesContains"
10273            if self.operator == "not_in":
10274                negation = "!"
10275            else:
10276                negation = ""
10277            return "(%s%s(%s, %s))" % (
10278                negation,
10279                method,
10280                self.operand2.result(),
10281                self.operand1.result())
10282        else:
10283            result1 = self.operand1.result()
10284            result2 = self.operand2.result()
10285            if self.is_memslice_nonecheck:
10286                if self.operand1.type.is_memoryviewslice:
10287                    result1 = "((PyObject *) %s.memview)" % result1
10288                else:
10289                    result2 = "((PyObject *) %s.memview)" % result2
10290
10291            return "(%s %s %s)" % (
10292                result1,
10293                self.c_operator(self.operator),
10294                result2)
10295
10296    def generate_evaluation_code(self, code):
10297        self.operand1.generate_evaluation_code(code)
10298        self.operand2.generate_evaluation_code(code)
10299        if self.is_temp:
10300            self.allocate_temp_result(code)
10301            self.generate_operation_code(code, self.result(),
10302                self.operand1, self.operator, self.operand2)
10303            if self.cascade:
10304                self.cascade.generate_evaluation_code(
10305                    code, self.result(), self.coerced_operand2 or self.operand2,
10306                    needs_evaluation=self.coerced_operand2 is not None)
10307            self.operand1.generate_disposal_code(code)
10308            self.operand1.free_temps(code)
10309            self.operand2.generate_disposal_code(code)
10310            self.operand2.free_temps(code)
10311
10312    def generate_subexpr_disposal_code(self, code):
10313        #  If this is called, it is a non-cascaded cmp,
10314        #  so only need to dispose of the two main operands.
10315        self.operand1.generate_disposal_code(code)
10316        self.operand2.generate_disposal_code(code)
10317
10318    def free_subexpr_temps(self, code):
10319        #  If this is called, it is a non-cascaded cmp,
10320        #  so only need to dispose of the two main operands.
10321        self.operand1.free_temps(code)
10322        self.operand2.free_temps(code)
10323
10324    def annotate(self, code):
10325        self.operand1.annotate(code)
10326        self.operand2.annotate(code)
10327        if self.cascade:
10328            self.cascade.annotate(code)
10329
10330
10331class CascadedCmpNode(Node, CmpNode):
10332    #  A CascadedCmpNode is not a complete expression node. It
10333    #  hangs off the side of another comparison node, shares
10334    #  its left operand with that node, and shares its result
10335    #  with the PrimaryCmpNode at the head of the chain.
10336    #
10337    #  operator      string
10338    #  operand2      ExprNode
10339    #  cascade       CascadedCmpNode
10340
10341    child_attrs = ['operand2', 'coerced_operand2', 'cascade']
10342
10343    cascade = None
10344    coerced_operand2 = None
10345    constant_result = constant_value_not_set # FIXME: where to calculate this?
10346
10347    def infer_type(self, env):
10348        # TODO: Actually implement this (after merging with -unstable).
10349        return py_object_type
10350
10351    def type_dependencies(self, env):
10352        return ()
10353
10354    def has_constant_result(self):
10355        return self.constant_result is not constant_value_not_set and \
10356               self.constant_result is not not_a_constant
10357
10358    def analyse_types(self, env):
10359        self.operand2 = self.operand2.analyse_types(env)
10360        if self.cascade:
10361            self.cascade = self.cascade.analyse_types(env)
10362        return self
10363
10364    def has_python_operands(self):
10365        return self.operand2.type.is_pyobject
10366
10367    def optimise_comparison(self, operand1, env, result_is_bool=False):
10368        if self.find_special_bool_compare_function(env, operand1, result_is_bool):
10369            self.is_pycmp = False
10370            self.type = PyrexTypes.c_bint_type
10371            if not operand1.type.is_pyobject:
10372                operand1 = operand1.coerce_to_pyobject(env)
10373        if self.cascade:
10374            operand2 = self.cascade.optimise_comparison(self.operand2, env, result_is_bool)
10375            if operand2 is not self.operand2:
10376                self.coerced_operand2 = operand2
10377        return operand1
10378
10379    def coerce_operands_to_pyobjects(self, env):
10380        self.operand2 = self.operand2.coerce_to_pyobject(env)
10381        if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
10382            self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
10383        if self.cascade:
10384            self.cascade.coerce_operands_to_pyobjects(env)
10385
10386    def coerce_cascaded_operands_to_temp(self, env):
10387        if self.cascade:
10388            #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
10389            self.operand2 = self.operand2.coerce_to_simple(env)
10390            self.cascade.coerce_cascaded_operands_to_temp(env)
10391
10392    def generate_evaluation_code(self, code, result, operand1, needs_evaluation=False):
10393        if self.type.is_pyobject:
10394            code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
10395            code.put_decref(result, self.type)
10396        else:
10397            code.putln("if (%s) {" % result)
10398        if needs_evaluation:
10399            operand1.generate_evaluation_code(code)
10400        self.operand2.generate_evaluation_code(code)
10401        self.generate_operation_code(code, result,
10402            operand1, self.operator, self.operand2)
10403        if self.cascade:
10404            self.cascade.generate_evaluation_code(
10405                code, result, self.coerced_operand2 or self.operand2,
10406                needs_evaluation=self.coerced_operand2 is not None)
10407        if needs_evaluation:
10408            operand1.generate_disposal_code(code)
10409            operand1.free_temps(code)
10410        # Cascaded cmp result is always temp
10411        self.operand2.generate_disposal_code(code)
10412        self.operand2.free_temps(code)
10413        code.putln("}")
10414
10415    def annotate(self, code):
10416        self.operand2.annotate(code)
10417        if self.cascade:
10418            self.cascade.annotate(code)
10419
10420
10421binop_node_classes = {
10422    "or":       BoolBinopNode,
10423    "and":      BoolBinopNode,
10424    "|":        IntBinopNode,
10425    "^":        IntBinopNode,
10426    "&":        IntBinopNode,
10427    "<<":       IntBinopNode,
10428    ">>":       IntBinopNode,
10429    "+":        AddNode,
10430    "-":        SubNode,
10431    "*":        MulNode,
10432    "/":        DivNode,
10433    "//":       DivNode,
10434    "%":        ModNode,
10435    "**":       PowNode
10436}
10437
10438def binop_node(pos, operator, operand1, operand2, inplace=False):
10439    # Construct binop node of appropriate class for
10440    # given operator.
10441    return binop_node_classes[operator](pos,
10442        operator = operator,
10443        operand1 = operand1,
10444        operand2 = operand2,
10445        inplace = inplace)
10446
10447#-------------------------------------------------------------------
10448#
10449#  Coercion nodes
10450#
10451#  Coercion nodes are special in that they are created during
10452#  the analyse_types phase of parse tree processing.
10453#  Their __init__ methods consequently incorporate some aspects
10454#  of that phase.
10455#
10456#-------------------------------------------------------------------
10457
10458class CoercionNode(ExprNode):
10459    #  Abstract base class for coercion nodes.
10460    #
10461    #  arg       ExprNode       node being coerced
10462
10463    subexprs = ['arg']
10464    constant_result = not_a_constant
10465
10466    def __init__(self, arg):
10467        super(CoercionNode, self).__init__(arg.pos)
10468        self.arg = arg
10469        if debug_coercion:
10470            print("%s Coercing %s" % (self, self.arg))
10471
10472    def calculate_constant_result(self):
10473        # constant folding can break type coercion, so this is disabled
10474        pass
10475
10476    def annotate(self, code):
10477        self.arg.annotate(code)
10478        if self.arg.type != self.type:
10479            file, line, col = self.pos
10480            code.annotate((file, line, col-1), AnnotationItem(
10481                style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
10482
10483class CoerceToMemViewSliceNode(CoercionNode):
10484    """
10485    Coerce an object to a memoryview slice. This holds a new reference in
10486    a managed temp.
10487    """
10488
10489    def __init__(self, arg, dst_type, env):
10490        assert dst_type.is_memoryviewslice
10491        assert not arg.type.is_memoryviewslice
10492        CoercionNode.__init__(self, arg)
10493        self.type = dst_type
10494        self.is_temp = 1
10495        self.env = env
10496        self.use_managed_ref = True
10497        self.arg = arg
10498
10499    def generate_result_code(self, code):
10500        self.type.create_from_py_utility_code(self.env)
10501        code.putln("%s = %s(%s);" % (self.result(),
10502                                     self.type.from_py_function,
10503                                     self.arg.py_result()))
10504
10505        error_cond = self.type.error_condition(self.result())
10506        code.putln(code.error_goto_if(error_cond, self.pos))
10507
10508
10509class CastNode(CoercionNode):
10510    #  Wrap a node in a C type cast.
10511
10512    def __init__(self, arg, new_type):
10513        CoercionNode.__init__(self, arg)
10514        self.type = new_type
10515
10516    def may_be_none(self):
10517        return self.arg.may_be_none()
10518
10519    def calculate_result_code(self):
10520        return self.arg.result_as(self.type)
10521
10522    def generate_result_code(self, code):
10523        self.arg.generate_result_code(code)
10524
10525
10526class PyTypeTestNode(CoercionNode):
10527    #  This node is used to check that a generic Python
10528    #  object is an instance of a particular extension type.
10529    #  This node borrows the result of its argument node.
10530
10531    exact_builtin_type = True
10532
10533    def __init__(self, arg, dst_type, env, notnone=False):
10534        #  The arg is know to be a Python object, and
10535        #  the dst_type is known to be an extension type.
10536        assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
10537        CoercionNode.__init__(self, arg)
10538        self.type = dst_type
10539        self.result_ctype = arg.ctype()
10540        self.notnone = notnone
10541
10542    nogil_check = Node.gil_error
10543    gil_message = "Python type test"
10544
10545    def analyse_types(self, env):
10546        return self
10547
10548    def may_be_none(self):
10549        if self.notnone:
10550            return False
10551        return self.arg.may_be_none()
10552
10553    def is_simple(self):
10554        return self.arg.is_simple()
10555
10556    def result_in_temp(self):
10557        return self.arg.result_in_temp()
10558
10559    def is_ephemeral(self):
10560        return self.arg.is_ephemeral()
10561
10562    def nonlocally_immutable(self):
10563        return self.arg.nonlocally_immutable()
10564
10565    def calculate_constant_result(self):
10566        # FIXME
10567        pass
10568
10569    def calculate_result_code(self):
10570        return self.arg.result()
10571
10572    def generate_result_code(self, code):
10573        if self.type.typeobj_is_available():
10574            if self.type.is_builtin_type:
10575                type_test = self.type.type_test_code(
10576                    self.arg.py_result(),
10577                    self.notnone, exact=self.exact_builtin_type)
10578            else:
10579                type_test = self.type.type_test_code(
10580                    self.arg.py_result(), self.notnone)
10581                code.globalstate.use_utility_code(
10582                    UtilityCode.load_cached("ExtTypeTest", "ObjectHandling.c"))
10583            code.putln("if (!(%s)) %s" % (
10584                type_test, code.error_goto(self.pos)))
10585        else:
10586            error(self.pos, "Cannot test type of extern C class "
10587                "without type object name specification")
10588
10589    def generate_post_assignment_code(self, code):
10590        self.arg.generate_post_assignment_code(code)
10591
10592    def free_temps(self, code):
10593        self.arg.free_temps(code)
10594
10595
10596class NoneCheckNode(CoercionNode):
10597    # This node is used to check that a Python object is not None and
10598    # raises an appropriate exception (as specified by the creating
10599    # transform).
10600
10601    is_nonecheck = True
10602
10603    def __init__(self, arg, exception_type_cname, exception_message,
10604                 exception_format_args):
10605        CoercionNode.__init__(self, arg)
10606        self.type = arg.type
10607        self.result_ctype = arg.ctype()
10608        self.exception_type_cname = exception_type_cname
10609        self.exception_message = exception_message
10610        self.exception_format_args = tuple(exception_format_args or ())
10611
10612    nogil_check = None # this node only guards an operation that would fail already
10613
10614    def analyse_types(self, env):
10615        return self
10616
10617    def may_be_none(self):
10618        return False
10619
10620    def is_simple(self):
10621        return self.arg.is_simple()
10622
10623    def result_in_temp(self):
10624        return self.arg.result_in_temp()
10625
10626    def nonlocally_immutable(self):
10627        return self.arg.nonlocally_immutable()
10628
10629    def calculate_result_code(self):
10630        return self.arg.result()
10631
10632    def condition(self):
10633        if self.type.is_pyobject:
10634            return self.arg.py_result()
10635        elif self.type.is_memoryviewslice:
10636            return "((PyObject *) %s.memview)" % self.arg.result()
10637        else:
10638            raise Exception("unsupported type")
10639
10640    def put_nonecheck(self, code):
10641        code.putln(
10642            "if (unlikely(%s == Py_None)) {" % self.condition())
10643
10644        if self.in_nogil_context:
10645            code.put_ensure_gil()
10646
10647        escape = StringEncoding.escape_byte_string
10648        if self.exception_format_args:
10649            code.putln('PyErr_Format(%s, "%s", %s);' % (
10650                self.exception_type_cname,
10651                StringEncoding.escape_byte_string(
10652                    self.exception_message.encode('UTF-8')),
10653                ', '.join([ '"%s"' % escape(str(arg).encode('UTF-8'))
10654                            for arg in self.exception_format_args ])))
10655        else:
10656            code.putln('PyErr_SetString(%s, "%s");' % (
10657                self.exception_type_cname,
10658                escape(self.exception_message.encode('UTF-8'))))
10659
10660        if self.in_nogil_context:
10661            code.put_release_ensured_gil()
10662
10663        code.putln(code.error_goto(self.pos))
10664        code.putln("}")
10665
10666    def generate_result_code(self, code):
10667        self.put_nonecheck(code)
10668
10669    def generate_post_assignment_code(self, code):
10670        self.arg.generate_post_assignment_code(code)
10671
10672    def free_temps(self, code):
10673        self.arg.free_temps(code)
10674
10675
10676class CoerceToPyTypeNode(CoercionNode):
10677    #  This node is used to convert a C data type
10678    #  to a Python object.
10679
10680    type = py_object_type
10681    is_temp = 1
10682
10683    def __init__(self, arg, env, type=py_object_type):
10684        if not arg.type.create_to_py_utility_code(env):
10685            error(arg.pos, "Cannot convert '%s' to Python object" % arg.type)
10686        elif arg.type.is_complex:
10687            # special case: complex coercion is so complex that it
10688            # uses a macro ("__pyx_PyComplex_FromComplex()"), for
10689            # which the argument must be simple
10690            arg = arg.coerce_to_simple(env)
10691        CoercionNode.__init__(self, arg)
10692        if type is py_object_type:
10693            # be specific about some known types
10694            if arg.type.is_string or arg.type.is_cpp_string:
10695                self.type = default_str_type(env)
10696            elif arg.type.is_pyunicode_ptr or arg.type.is_unicode_char:
10697                self.type = unicode_type
10698            elif arg.type.is_complex:
10699                self.type = Builtin.complex_type
10700        elif arg.type.is_string or arg.type.is_cpp_string:
10701            if (type not in (bytes_type, bytearray_type)
10702                    and not env.directives['c_string_encoding']):
10703                error(arg.pos,
10704                    "default encoding required for conversion from '%s' to '%s'" %
10705                    (arg.type, type))
10706            self.type = type
10707        else:
10708            # FIXME: check that the target type and the resulting type are compatible
10709            pass
10710
10711        if arg.type.is_memoryviewslice:
10712            # Register utility codes at this point
10713            arg.type.get_to_py_function(env, arg)
10714
10715        self.env = env
10716
10717    gil_message = "Converting to Python object"
10718
10719    def may_be_none(self):
10720        # FIXME: is this always safe?
10721        return False
10722
10723    def coerce_to_boolean(self, env):
10724        arg_type = self.arg.type
10725        if (arg_type == PyrexTypes.c_bint_type or
10726            (arg_type.is_pyobject and arg_type.name == 'bool')):
10727            return self.arg.coerce_to_temp(env)
10728        else:
10729            return CoerceToBooleanNode(self, env)
10730
10731    def coerce_to_integer(self, env):
10732        # If not already some C integer type, coerce to longint.
10733        if self.arg.type.is_int:
10734            return self.arg
10735        else:
10736            return self.arg.coerce_to(PyrexTypes.c_long_type, env)
10737
10738    def analyse_types(self, env):
10739        # The arg is always already analysed
10740        return self
10741
10742    def generate_result_code(self, code):
10743        arg_type = self.arg.type
10744        if arg_type.is_memoryviewslice:
10745            funccall = arg_type.get_to_py_function(self.env, self.arg)
10746        else:
10747            func = arg_type.to_py_function
10748            if arg_type.is_string or arg_type.is_cpp_string:
10749                if self.type in (bytes_type, str_type, unicode_type):
10750                    func = func.replace("Object", self.type.name.title())
10751                elif self.type is bytearray_type:
10752                    func = func.replace("Object", "ByteArray")
10753            funccall = "%s(%s)" % (func, self.arg.result())
10754
10755        code.putln('%s = %s; %s' % (
10756            self.result(),
10757            funccall,
10758            code.error_goto_if_null(self.result(), self.pos)))
10759
10760        code.put_gotref(self.py_result())
10761
10762
10763class CoerceIntToBytesNode(CoerceToPyTypeNode):
10764    #  This node is used to convert a C int type to a Python bytes
10765    #  object.
10766
10767    is_temp = 1
10768
10769    def __init__(self, arg, env):
10770        arg = arg.coerce_to_simple(env)
10771        CoercionNode.__init__(self, arg)
10772        self.type = Builtin.bytes_type
10773
10774    def generate_result_code(self, code):
10775        arg = self.arg
10776        arg_result = arg.result()
10777        if arg.type not in (PyrexTypes.c_char_type,
10778                            PyrexTypes.c_uchar_type,
10779                            PyrexTypes.c_schar_type):
10780            if arg.type.signed:
10781                code.putln("if ((%s < 0) || (%s > 255)) {" % (
10782                    arg_result, arg_result))
10783            else:
10784                code.putln("if (%s > 255) {" % arg_result)
10785            code.putln('PyErr_SetString(PyExc_OverflowError, '
10786                       '"value too large to pack into a byte"); %s' % (
10787                           code.error_goto(self.pos)))
10788            code.putln('}')
10789        temp = None
10790        if arg.type is not PyrexTypes.c_char_type:
10791            temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
10792            code.putln("%s = (char)%s;" % (temp, arg_result))
10793            arg_result = temp
10794        code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
10795            self.result(),
10796            arg_result,
10797            code.error_goto_if_null(self.result(), self.pos)))
10798        if temp is not None:
10799            code.funcstate.release_temp(temp)
10800        code.put_gotref(self.py_result())
10801
10802
10803class CoerceFromPyTypeNode(CoercionNode):
10804    #  This node is used to convert a Python object
10805    #  to a C data type.
10806
10807    def __init__(self, result_type, arg, env):
10808        CoercionNode.__init__(self, arg)
10809        self.type = result_type
10810        self.is_temp = 1
10811        if not result_type.create_from_py_utility_code(env):
10812            error(arg.pos,
10813                  "Cannot convert Python object to '%s'" % result_type)
10814        if self.type.is_string or self.type.is_pyunicode_ptr:
10815            if self.arg.is_ephemeral():
10816                error(arg.pos,
10817                      "Obtaining '%s' from temporary Python value" % result_type)
10818            elif self.arg.is_name and self.arg.entry and self.arg.entry.is_pyglobal:
10819                warning(arg.pos,
10820                        "Obtaining '%s' from externally modifiable global Python value" % result_type,
10821                        level=1)
10822
10823    def analyse_types(self, env):
10824        # The arg is always already analysed
10825        return self
10826
10827    def generate_result_code(self, code):
10828        function = self.type.from_py_function
10829        operand = self.arg.py_result()
10830        rhs = "%s(%s)" % (function, operand)
10831        if self.type.is_enum:
10832            rhs = typecast(self.type, c_long_type, rhs)
10833        code.putln('%s = %s; %s' % (
10834            self.result(),
10835            rhs,
10836            code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
10837        if self.type.is_pyobject:
10838            code.put_gotref(self.py_result())
10839
10840    def nogil_check(self, env):
10841        error(self.pos, "Coercion from Python not allowed without the GIL")
10842
10843
10844class CoerceToBooleanNode(CoercionNode):
10845    #  This node is used when a result needs to be used
10846    #  in a boolean context.
10847
10848    type = PyrexTypes.c_bint_type
10849
10850    _special_builtins = {
10851        Builtin.list_type    : 'PyList_GET_SIZE',
10852        Builtin.tuple_type   : 'PyTuple_GET_SIZE',
10853        Builtin.bytes_type   : 'PyBytes_GET_SIZE',
10854        Builtin.unicode_type : 'PyUnicode_GET_SIZE',
10855        }
10856
10857    def __init__(self, arg, env):
10858        CoercionNode.__init__(self, arg)
10859        if arg.type.is_pyobject:
10860            self.is_temp = 1
10861
10862    def nogil_check(self, env):
10863        if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
10864            self.gil_error()
10865
10866    gil_message = "Truth-testing Python object"
10867
10868    def check_const(self):
10869        if self.is_temp:
10870            self.not_const()
10871            return False
10872        return self.arg.check_const()
10873
10874    def calculate_result_code(self):
10875        return "(%s != 0)" % self.arg.result()
10876
10877    def generate_result_code(self, code):
10878        if not self.is_temp:
10879            return
10880        test_func = self._special_builtins.get(self.arg.type)
10881        if test_func is not None:
10882            code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
10883                       self.result(),
10884                       self.arg.py_result(),
10885                       test_func,
10886                       self.arg.py_result()))
10887        else:
10888            code.putln(
10889                "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
10890                    self.result(),
10891                    self.arg.py_result(),
10892                    code.error_goto_if_neg(self.result(), self.pos)))
10893
10894class CoerceToComplexNode(CoercionNode):
10895
10896    def __init__(self, arg, dst_type, env):
10897        if arg.type.is_complex:
10898            arg = arg.coerce_to_simple(env)
10899        self.type = dst_type
10900        CoercionNode.__init__(self, arg)
10901        dst_type.create_declaration_utility_code(env)
10902
10903    def calculate_result_code(self):
10904        if self.arg.type.is_complex:
10905            real_part = "__Pyx_CREAL(%s)" % self.arg.result()
10906            imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
10907        else:
10908            real_part = self.arg.result()
10909            imag_part = "0"
10910        return "%s(%s, %s)" % (
10911                self.type.from_parts,
10912                real_part,
10913                imag_part)
10914
10915    def generate_result_code(self, code):
10916        pass
10917
10918class CoerceToTempNode(CoercionNode):
10919    #  This node is used to force the result of another node
10920    #  to be stored in a temporary. It is only used if the
10921    #  argument node's result is not already in a temporary.
10922
10923    def __init__(self, arg, env):
10924        CoercionNode.__init__(self, arg)
10925        self.type = self.arg.type.as_argument_type()
10926        self.constant_result = self.arg.constant_result
10927        self.is_temp = 1
10928        if self.type.is_pyobject:
10929            self.result_ctype = py_object_type
10930
10931    gil_message = "Creating temporary Python reference"
10932
10933    def analyse_types(self, env):
10934        # The arg is always already analysed
10935        return self
10936
10937    def coerce_to_boolean(self, env):
10938        self.arg = self.arg.coerce_to_boolean(env)
10939        if self.arg.is_simple():
10940            return self.arg
10941        self.type = self.arg.type
10942        self.result_ctype = self.type
10943        return self
10944
10945    def generate_result_code(self, code):
10946        #self.arg.generate_evaluation_code(code) # Already done
10947        # by generic generate_subexpr_evaluation_code!
10948        code.putln("%s = %s;" % (
10949            self.result(), self.arg.result_as(self.ctype())))
10950        if self.use_managed_ref:
10951            if self.type.is_pyobject:
10952                code.put_incref(self.result(), self.ctype())
10953            elif self.type.is_memoryviewslice:
10954                code.put_incref_memoryviewslice(self.result(),
10955                                                not self.in_nogil_context)
10956
10957class ProxyNode(CoercionNode):
10958    """
10959    A node that should not be replaced by transforms or other means,
10960    and hence can be useful to wrap the argument to a clone node
10961
10962    MyNode    -> ProxyNode -> ArgNode
10963    CloneNode -^
10964    """
10965
10966    nogil_check = None
10967
10968    def __init__(self, arg):
10969        super(ProxyNode, self).__init__(arg)
10970        self.constant_result = arg.constant_result
10971        self._proxy_type()
10972
10973    def analyse_expressions(self, env):
10974        self.arg = self.arg.analyse_expressions(env)
10975        self._proxy_type()
10976        return self
10977
10978    def _proxy_type(self):
10979        if hasattr(self.arg, 'type'):
10980            self.type = self.arg.type
10981            self.result_ctype = self.arg.result_ctype
10982        if hasattr(self.arg, 'entry'):
10983            self.entry = self.arg.entry
10984
10985    def generate_result_code(self, code):
10986        self.arg.generate_result_code(code)
10987
10988    def result(self):
10989        return self.arg.result()
10990
10991    def is_simple(self):
10992        return self.arg.is_simple()
10993
10994    def may_be_none(self):
10995        return self.arg.may_be_none()
10996
10997    def generate_evaluation_code(self, code):
10998        self.arg.generate_evaluation_code(code)
10999
11000    def generate_result_code(self, code):
11001        self.arg.generate_result_code(code)
11002
11003    def generate_disposal_code(self, code):
11004        self.arg.generate_disposal_code(code)
11005
11006    def free_temps(self, code):
11007        self.arg.free_temps(code)
11008
11009class CloneNode(CoercionNode):
11010    #  This node is employed when the result of another node needs
11011    #  to be used multiple times. The argument node's result must
11012    #  be in a temporary. This node "borrows" the result from the
11013    #  argument node, and does not generate any evaluation or
11014    #  disposal code for it. The original owner of the argument
11015    #  node is responsible for doing those things.
11016
11017    subexprs = [] # Arg is not considered a subexpr
11018    nogil_check = None
11019
11020    def __init__(self, arg):
11021        CoercionNode.__init__(self, arg)
11022        self.constant_result = arg.constant_result
11023        if hasattr(arg, 'type'):
11024            self.type = arg.type
11025            self.result_ctype = arg.result_ctype
11026        if hasattr(arg, 'entry'):
11027            self.entry = arg.entry
11028
11029    def result(self):
11030        return self.arg.result()
11031
11032    def may_be_none(self):
11033        return self.arg.may_be_none()
11034
11035    def type_dependencies(self, env):
11036        return self.arg.type_dependencies(env)
11037
11038    def infer_type(self, env):
11039        return self.arg.infer_type(env)
11040
11041    def analyse_types(self, env):
11042        self.type = self.arg.type
11043        self.result_ctype = self.arg.result_ctype
11044        self.is_temp = 1
11045        if hasattr(self.arg, 'entry'):
11046            self.entry = self.arg.entry
11047        return self
11048
11049    def is_simple(self):
11050        return True # result is always in a temp (or a name)
11051
11052    def generate_evaluation_code(self, code):
11053        pass
11054
11055    def generate_result_code(self, code):
11056        pass
11057
11058    def generate_disposal_code(self, code):
11059        pass
11060
11061    def free_temps(self, code):
11062        pass
11063
11064
11065class CMethodSelfCloneNode(CloneNode):
11066    # Special CloneNode for the self argument of builtin C methods
11067    # that accepts subtypes of the builtin type.  This is safe only
11068    # for 'final' subtypes, as subtypes of the declared type may
11069    # override the C method.
11070
11071    def coerce_to(self, dst_type, env):
11072        if dst_type.is_builtin_type and self.type.subtype_of(dst_type):
11073            return self
11074        return CloneNode.coerce_to(self, dst_type, env)
11075
11076
11077class ModuleRefNode(ExprNode):
11078    # Simple returns the module object
11079
11080    type = py_object_type
11081    is_temp = False
11082    subexprs = []
11083
11084    def analyse_types(self, env):
11085        return self
11086
11087    def may_be_none(self):
11088        return False
11089
11090    def calculate_result_code(self):
11091        return Naming.module_cname
11092
11093    def generate_result_code(self, code):
11094        pass
11095
11096class DocstringRefNode(ExprNode):
11097    # Extracts the docstring of the body element
11098
11099    subexprs = ['body']
11100    type = py_object_type
11101    is_temp = True
11102
11103    def __init__(self, pos, body):
11104        ExprNode.__init__(self, pos)
11105        assert body.type.is_pyobject
11106        self.body = body
11107
11108    def analyse_types(self, env):
11109        return self
11110
11111    def generate_result_code(self, code):
11112        code.putln('%s = __Pyx_GetAttr(%s, %s); %s' % (
11113            self.result(), self.body.result(),
11114            code.intern_identifier(StringEncoding.EncodedString("__doc__")),
11115            code.error_goto_if_null(self.result(), self.pos)))
11116        code.put_gotref(self.result())
11117
11118
11119
11120#------------------------------------------------------------------------------------
11121#
11122#  Runtime support code
11123#
11124#------------------------------------------------------------------------------------
11125
11126pyerr_occurred_withgil_utility_code= UtilityCode(
11127proto = """
11128static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
11129""",
11130impl = """
11131static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
11132  int err;
11133  #ifdef WITH_THREAD
11134  PyGILState_STATE _save = PyGILState_Ensure();
11135  #endif
11136  err = !!PyErr_Occurred();
11137  #ifdef WITH_THREAD
11138  PyGILState_Release(_save);
11139  #endif
11140  return err;
11141}
11142"""
11143)
11144
11145#------------------------------------------------------------------------------------
11146
11147raise_unbound_local_error_utility_code = UtilityCode(
11148proto = """
11149static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
11150""",
11151impl = """
11152static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
11153    PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
11154}
11155""")
11156
11157raise_closure_name_error_utility_code = UtilityCode(
11158proto = """
11159static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);
11160""",
11161impl = """
11162static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) {
11163    PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname);
11164}
11165""")
11166
11167# Don't inline the function, it should really never be called in production
11168raise_unbound_memoryview_utility_code_nogil = UtilityCode(
11169proto = """
11170static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname);
11171""",
11172impl = """
11173static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname) {
11174    #ifdef WITH_THREAD
11175    PyGILState_STATE gilstate = PyGILState_Ensure();
11176    #endif
11177    __Pyx_RaiseUnboundLocalError(varname);
11178    #ifdef WITH_THREAD
11179    PyGILState_Release(gilstate);
11180    #endif
11181}
11182""",
11183requires = [raise_unbound_local_error_utility_code])
11184
11185#------------------------------------------------------------------------------------
11186
11187raise_too_many_values_to_unpack = UtilityCode.load_cached("RaiseTooManyValuesToUnpack", "ObjectHandling.c")
11188raise_need_more_values_to_unpack = UtilityCode.load_cached("RaiseNeedMoreValuesToUnpack", "ObjectHandling.c")
11189tuple_unpacking_error_code = UtilityCode.load_cached("UnpackTupleError", "ObjectHandling.c")
11190
11191#------------------------------------------------------------------------------------
11192
11193int_pow_utility_code = UtilityCode(
11194proto="""
11195static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
11196""",
11197impl="""
11198static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
11199    %(type)s t = b;
11200    switch (e) {
11201        case 3:
11202            t *= b;
11203        case 2:
11204            t *= b;
11205        case 1:
11206            return t;
11207        case 0:
11208            return 1;
11209    }
11210    #if %(signed)s
11211    if (unlikely(e<0)) return 0;
11212    #endif
11213    t = 1;
11214    while (likely(e)) {
11215        t *= (b * (e&1)) | ((~e)&1);    /* 1 or b */
11216        b *= b;
11217        e >>= 1;
11218    }
11219    return t;
11220}
11221""")
11222
11223# ------------------------------ Division ------------------------------------
11224
11225div_int_utility_code = UtilityCode(
11226proto="""
11227static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
11228""",
11229impl="""
11230static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
11231    %(type)s q = a / b;
11232    %(type)s r = a - q*b;
11233    q -= ((r != 0) & ((r ^ b) < 0));
11234    return q;
11235}
11236""")
11237
11238mod_int_utility_code = UtilityCode(
11239proto="""
11240static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
11241""",
11242impl="""
11243static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
11244    %(type)s r = a %% b;
11245    r += ((r != 0) & ((r ^ b) < 0)) * b;
11246    return r;
11247}
11248""")
11249
11250mod_float_utility_code = UtilityCode(
11251proto="""
11252static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
11253""",
11254impl="""
11255static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
11256    %(type)s r = fmod%(math_h_modifier)s(a, b);
11257    r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
11258    return r;
11259}
11260""")
11261
11262cdivision_warning_utility_code = UtilityCode(
11263proto="""
11264static int __Pyx_cdivision_warning(const char *, int); /* proto */
11265""",
11266impl="""
11267static int __Pyx_cdivision_warning(const char *filename, int lineno) {
11268#if CYTHON_COMPILING_IN_PYPY
11269    filename++; // avoid compiler warnings
11270    lineno++;
11271    return PyErr_Warn(PyExc_RuntimeWarning,
11272                     "division with oppositely signed operands, C and Python semantics differ");
11273#else
11274    return PyErr_WarnExplicit(PyExc_RuntimeWarning,
11275                              "division with oppositely signed operands, C and Python semantics differ",
11276                              filename,
11277                              lineno,
11278                              __Pyx_MODULE_NAME,
11279                              NULL);
11280#endif
11281}
11282""")
11283
11284# from intobject.c
11285division_overflow_test_code = UtilityCode(
11286proto="""
11287#define UNARY_NEG_WOULD_OVERFLOW(x)    \
11288        (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
11289""")
11290