1#
2#   Parse tree nodes for expressions
3#
4
5from __future__ import absolute_import
6
7import cython
8cython.declare(error=object, warning=object, warn_once=object, InternalError=object,
9               CompileError=object, UtilityCode=object, TempitaUtilityCode=object,
10               StringEncoding=object, operator=object, local_errors=object, report_error=object,
11               Naming=object, Nodes=object, PyrexTypes=object, py_object_type=object,
12               list_type=object, tuple_type=object, set_type=object, dict_type=object,
13               unicode_type=object, str_type=object, bytes_type=object, type_type=object,
14               Builtin=object, Symtab=object, Utils=object, find_coercion_error=object,
15               debug_disposal_code=object, debug_temp_alloc=object, debug_coercion=object,
16               bytearray_type=object, slice_type=object, _py_int_types=object,
17               IS_PYTHON3=cython.bint)
18
19import re
20import sys
21import copy
22import os.path
23import operator
24
25from .Errors import (
26    error, warning, InternalError, CompileError, report_error, local_errors)
27from .Code import UtilityCode, TempitaUtilityCode
28from . import StringEncoding
29from . import Naming
30from . import Nodes
31from .Nodes import Node, utility_code_for_imports, analyse_type_annotation
32from . import PyrexTypes
33from .PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
34    unspecified_type
35from . import TypeSlots
36from .Builtin import list_type, tuple_type, set_type, dict_type, type_type, \
37     unicode_type, str_type, bytes_type, bytearray_type, basestring_type, slice_type
38from . import Builtin
39from . import Symtab
40from .. import Utils
41from .Annotate import AnnotationItem
42from . import Future
43from ..Debugging import print_call_chain
44from .DebugFlags import debug_disposal_code, debug_temp_alloc, \
45    debug_coercion
46from .Pythran import (to_pythran, is_pythran_supported_type, is_pythran_supported_operation_type,
47     is_pythran_expr, pythran_func_type, pythran_binop_type, pythran_unaryop_type, has_np_pythran,
48     pythran_indexing_code, pythran_indexing_type, is_pythran_supported_node_or_none, pythran_type,
49     pythran_is_numpy_func_supported, pythran_get_func_include_file, pythran_functor)
50from .PyrexTypes import PythranExpr
51
52try:
53    from __builtin__ import basestring
54except ImportError:
55    # Python 3
56    basestring = str
57    any_string_type = (bytes, str)
58else:
59    # Python 2
60    any_string_type = (bytes, unicode)
61
62
63if sys.version_info[0] >= 3:
64    IS_PYTHON3 = True
65    _py_int_types = int
66else:
67    IS_PYTHON3 = False
68    _py_int_types = (int, long)
69
70
71class NotConstant(object):
72    _obj = None
73
74    def __new__(cls):
75        if NotConstant._obj is None:
76            NotConstant._obj = super(NotConstant, cls).__new__(cls)
77
78        return NotConstant._obj
79
80    def __repr__(self):
81        return "<NOT CONSTANT>"
82
83not_a_constant = NotConstant()
84constant_value_not_set = object()
85
86# error messages when coercing from key[0] to key[1]
87coercion_error_dict = {
88    # string related errors
89    (unicode_type, str_type): ("Cannot convert Unicode string to 'str' implicitly."
90                               " This is not portable and requires explicit encoding."),
91    (unicode_type, bytes_type): "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
92    (unicode_type, PyrexTypes.c_char_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
93    (unicode_type, PyrexTypes.c_const_char_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
94    (unicode_type, PyrexTypes.c_uchar_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
95    (unicode_type, PyrexTypes.c_const_uchar_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
96    (bytes_type, unicode_type): "Cannot convert 'bytes' object to unicode implicitly, decoding required",
97    (bytes_type, str_type): "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
98    (bytes_type, basestring_type): ("Cannot convert 'bytes' object to basestring implicitly."
99                                    " This is not portable to Py3."),
100    (bytes_type, PyrexTypes.c_py_unicode_ptr_type): "Cannot convert 'bytes' object to Py_UNICODE*, use 'unicode'.",
101    (bytes_type, PyrexTypes.c_const_py_unicode_ptr_type): (
102        "Cannot convert 'bytes' object to Py_UNICODE*, use 'unicode'."),
103    (basestring_type, bytes_type): "Cannot convert 'basestring' object to bytes implicitly. This is not portable.",
104    (str_type, unicode_type): ("str objects do not support coercion to unicode,"
105                               " use a unicode string literal instead (u'')"),
106    (str_type, bytes_type): "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
107    (str_type, PyrexTypes.c_char_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
108    (str_type, PyrexTypes.c_const_char_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
109    (str_type, PyrexTypes.c_uchar_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
110    (str_type, PyrexTypes.c_const_uchar_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
111    (str_type, PyrexTypes.c_py_unicode_ptr_type): "'str' objects do not support coercion to C types (use 'unicode'?).",
112    (str_type, PyrexTypes.c_const_py_unicode_ptr_type): (
113        "'str' objects do not support coercion to C types (use 'unicode'?)."),
114    (PyrexTypes.c_char_ptr_type, unicode_type): "Cannot convert 'char*' to unicode implicitly, decoding required",
115    (PyrexTypes.c_const_char_ptr_type, unicode_type): (
116        "Cannot convert 'char*' to unicode implicitly, decoding required"),
117    (PyrexTypes.c_uchar_ptr_type, unicode_type): "Cannot convert 'char*' to unicode implicitly, decoding required",
118    (PyrexTypes.c_const_uchar_ptr_type, unicode_type): (
119        "Cannot convert 'char*' to unicode implicitly, decoding required"),
120}
121
122def find_coercion_error(type_tuple, default, env):
123    err = coercion_error_dict.get(type_tuple)
124    if err is None:
125        return default
126    elif (env.directives['c_string_encoding'] and
127              any(t in type_tuple for t in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_uchar_ptr_type,
128                                            PyrexTypes.c_const_char_ptr_type, PyrexTypes.c_const_uchar_ptr_type))):
129        if type_tuple[1].is_pyobject:
130            return default
131        elif env.directives['c_string_encoding'] in ('ascii', 'default'):
132            return default
133        else:
134            return "'%s' objects do not support coercion to C types with non-ascii or non-default c_string_encoding" % type_tuple[0].name
135    else:
136        return err
137
138
139def default_str_type(env):
140    return {
141        'bytes': bytes_type,
142        'bytearray': bytearray_type,
143        'str': str_type,
144        'unicode': unicode_type
145    }.get(env.directives['c_string_type'])
146
147
148def check_negative_indices(*nodes):
149    """
150    Raise a warning on nodes that are known to have negative numeric values.
151    Used to find (potential) bugs inside of "wraparound=False" sections.
152    """
153    for node in nodes:
154        if node is None or (
155                not isinstance(node.constant_result, _py_int_types) and
156                not isinstance(node.constant_result, float)):
157            continue
158        if node.constant_result < 0:
159            warning(node.pos,
160                    "the result of using negative indices inside of "
161                    "code sections marked as 'wraparound=False' is "
162                    "undefined", level=1)
163
164
165def infer_sequence_item_type(env, seq_node, index_node=None, seq_type=None):
166    if not seq_node.is_sequence_constructor:
167        if seq_type is None:
168            seq_type = seq_node.infer_type(env)
169        if seq_type is tuple_type:
170            # tuples are immutable => we can safely follow assignments
171            if seq_node.cf_state and len(seq_node.cf_state) == 1:
172                try:
173                    seq_node = seq_node.cf_state[0].rhs
174                except AttributeError:
175                    pass
176    if seq_node is not None and seq_node.is_sequence_constructor:
177        if index_node is not None and index_node.has_constant_result():
178            try:
179                item = seq_node.args[index_node.constant_result]
180            except (ValueError, TypeError, IndexError):
181                pass
182            else:
183                return item.infer_type(env)
184        # if we're lucky, all items have the same type
185        item_types = set([item.infer_type(env) for item in seq_node.args])
186        if len(item_types) == 1:
187            return item_types.pop()
188    return None
189
190
191def make_dedup_key(outer_type, item_nodes):
192    """
193    Recursively generate a deduplication key from a sequence of values.
194    Includes Cython node types to work around the fact that (1, 2.0) == (1.0, 2), for example.
195
196    @param outer_type: The type of the outer container.
197    @param item_nodes: A sequence of constant nodes that will be traversed recursively.
198    @return: A tuple that can be used as a dict key for deduplication.
199    """
200    item_keys = [
201        (py_object_type, None, type(None)) if node is None
202        # For sequences and their "mult_factor", see TupleNode.
203        else make_dedup_key(node.type, [node.mult_factor if node.is_literal else None] + node.args) if node.is_sequence_constructor
204        else make_dedup_key(node.type, (node.start, node.stop, node.step)) if node.is_slice
205        # For constants, look at the Python value type if we don't know the concrete Cython type.
206        else (node.type, node.constant_result,
207              type(node.constant_result) if node.type is py_object_type else None) if node.has_constant_result()
208        else None  # something we cannot handle => short-circuit below
209        for node in item_nodes
210    ]
211    if None in item_keys:
212        return None
213    return outer_type, tuple(item_keys)
214
215
216# Returns a block of code to translate the exception,
217# plus a boolean indicating whether to check for Python exceptions.
218def get_exception_handler(exception_value):
219    if exception_value is None:
220        return "__Pyx_CppExn2PyErr();", False
221    elif (exception_value.type == PyrexTypes.c_char_type
222          and exception_value.value == '*'):
223        return "__Pyx_CppExn2PyErr();", True
224    elif exception_value.type.is_pyobject:
225        return (
226            'try { throw; } catch(const std::exception& exn) {'
227            'PyErr_SetString(%s, exn.what());'
228            '} catch(...) { PyErr_SetNone(%s); }' % (
229                exception_value.entry.cname,
230                exception_value.entry.cname),
231            False)
232    else:
233        return (
234            '%s(); if (!PyErr_Occurred())'
235            'PyErr_SetString(PyExc_RuntimeError, '
236            '"Error converting c++ exception.");' % (
237                exception_value.entry.cname),
238            False)
239
240def maybe_check_py_error(code, check_py_exception, pos, nogil):
241    if check_py_exception:
242        if nogil:
243            code.putln(code.error_goto_if("__Pyx_ErrOccurredWithGIL()", pos))
244        else:
245            code.putln(code.error_goto_if("PyErr_Occurred()", pos))
246
247def translate_cpp_exception(code, pos, inside, py_result, exception_value, nogil):
248    raise_py_exception, check_py_exception = get_exception_handler(exception_value)
249    code.putln("try {")
250    code.putln("%s" % inside)
251    if py_result:
252      code.putln(code.error_goto_if_null(py_result, pos))
253    maybe_check_py_error(code, check_py_exception, pos, nogil)
254    code.putln("} catch(...) {")
255    if nogil:
256        code.put_ensure_gil(declare_gilstate=True)
257    code.putln(raise_py_exception)
258    if nogil:
259        code.put_release_ensured_gil()
260    code.putln(code.error_goto(pos))
261    code.putln("}")
262
263# Used to handle the case where an lvalue expression and an overloaded assignment
264# both have an exception declaration.
265def translate_double_cpp_exception(code, pos, lhs_type, lhs_code, rhs_code,
266    lhs_exc_val, assign_exc_val, nogil):
267    handle_lhs_exc, lhc_check_py_exc = get_exception_handler(lhs_exc_val)
268    handle_assignment_exc, assignment_check_py_exc = get_exception_handler(assign_exc_val)
269    code.putln("try {")
270    code.putln(lhs_type.declaration_code("__pyx_local_lvalue = %s;" % lhs_code))
271    maybe_check_py_error(code, lhc_check_py_exc, pos, nogil)
272    code.putln("try {")
273    code.putln("__pyx_local_lvalue = %s;" % rhs_code)
274    maybe_check_py_error(code, assignment_check_py_exc, pos, nogil)
275    # Catch any exception from the overloaded assignment.
276    code.putln("} catch(...) {")
277    if nogil:
278        code.put_ensure_gil(declare_gilstate=True)
279    code.putln(handle_assignment_exc)
280    if nogil:
281        code.put_release_ensured_gil()
282    code.putln(code.error_goto(pos))
283    code.putln("}")
284    # Catch any exception from evaluating lhs.
285    code.putln("} catch(...) {")
286    if nogil:
287        code.put_ensure_gil(declare_gilstate=True)
288    code.putln(handle_lhs_exc)
289    if nogil:
290        code.put_release_ensured_gil()
291    code.putln(code.error_goto(pos))
292    code.putln('}')
293
294
295class ExprNode(Node):
296    #  subexprs     [string]     Class var holding names of subexpr node attrs
297    #  type         PyrexType    Type of the result
298    #  result_code  string       Code fragment
299    #  result_ctype string       C type of result_code if different from type
300    #  is_temp      boolean      Result is in a temporary variable
301    #  is_sequence_constructor
302    #               boolean      Is a list or tuple constructor expression
303    #  is_starred   boolean      Is a starred expression (e.g. '*a')
304    #  saved_subexpr_nodes
305    #               [ExprNode or [ExprNode or None] or None]
306    #                            Cached result of subexpr_nodes()
307    #  use_managed_ref boolean   use ref-counted temps/assignments/etc.
308    #  result_is_used  boolean   indicates that the result will be dropped and the
309    #  is_numpy_attribute   boolean   Is a Numpy module attribute
310    #                            result_code/temp_result can safely be set to None
311    #  annotation   ExprNode or None    PEP526 annotation for names or expressions
312
313    result_ctype = None
314    type = None
315    annotation = None
316    temp_code = None
317    old_temp = None # error checker for multiple frees etc.
318    use_managed_ref = True # can be set by optimisation transforms
319    result_is_used = True
320    is_numpy_attribute = False
321
322    #  The Analyse Expressions phase for expressions is split
323    #  into two sub-phases:
324    #
325    #    Analyse Types
326    #      Determines the result type of the expression based
327    #      on the types of its sub-expressions, and inserts
328    #      coercion nodes into the expression tree where needed.
329    #      Marks nodes which will need to have temporary variables
330    #      allocated.
331    #
332    #    Allocate Temps
333    #      Allocates temporary variables where needed, and fills
334    #      in the result_code field of each node.
335    #
336    #  ExprNode provides some convenience routines which
337    #  perform both of the above phases. These should only
338    #  be called from statement nodes, and only when no
339    #  coercion nodes need to be added around the expression
340    #  being analysed. In that case, the above two phases
341    #  should be invoked separately.
342    #
343    #  Framework code in ExprNode provides much of the common
344    #  processing for the various phases. It makes use of the
345    #  'subexprs' class attribute of ExprNodes, which should
346    #  contain a list of the names of attributes which can
347    #  hold sub-nodes or sequences of sub-nodes.
348    #
349    #  The framework makes use of a number of abstract methods.
350    #  Their responsibilities are as follows.
351    #
352    #    Declaration Analysis phase
353    #
354    #      analyse_target_declaration
355    #        Called during the Analyse Declarations phase to analyse
356    #        the LHS of an assignment or argument of a del statement.
357    #        Nodes which cannot be the LHS of an assignment need not
358    #        implement it.
359    #
360    #    Expression Analysis phase
361    #
362    #      analyse_types
363    #        - Call analyse_types on all sub-expressions.
364    #        - Check operand types, and wrap coercion nodes around
365    #          sub-expressions where needed.
366    #        - Set the type of this node.
367    #        - If a temporary variable will be required for the
368    #          result, set the is_temp flag of this node.
369    #
370    #      analyse_target_types
371    #        Called during the Analyse Types phase to analyse
372    #        the LHS of an assignment or argument of a del
373    #        statement. Similar responsibilities to analyse_types.
374    #
375    #      target_code
376    #        Called by the default implementation of allocate_target_temps.
377    #        Should return a C lvalue for assigning to the node. The default
378    #        implementation calls calculate_result_code.
379    #
380    #      check_const
381    #        - Check that this node and its subnodes form a
382    #          legal constant expression. If so, do nothing,
383    #          otherwise call not_const.
384    #
385    #        The default implementation of check_const
386    #        assumes that the expression is not constant.
387    #
388    #      check_const_addr
389    #        - Same as check_const, except check that the
390    #          expression is a C lvalue whose address is
391    #          constant. Otherwise, call addr_not_const.
392    #
393    #        The default implementation of calc_const_addr
394    #        assumes that the expression is not a constant
395    #        lvalue.
396    #
397    #   Code Generation phase
398    #
399    #      generate_evaluation_code
400    #        - Call generate_evaluation_code for sub-expressions.
401    #        - Perform the functions of generate_result_code
402    #          (see below).
403    #        - If result is temporary, call generate_disposal_code
404    #          on all sub-expressions.
405    #
406    #        A default implementation of generate_evaluation_code
407    #        is provided which uses the following abstract methods:
408    #
409    #          generate_result_code
410    #            - Generate any C statements necessary to calculate
411    #              the result of this node from the results of its
412    #              sub-expressions.
413    #
414    #          calculate_result_code
415    #            - Should return a C code fragment evaluating to the
416    #              result. This is only called when the result is not
417    #              a temporary.
418    #
419    #      generate_assignment_code
420    #        Called on the LHS of an assignment.
421    #        - Call generate_evaluation_code for sub-expressions.
422    #        - Generate code to perform the assignment.
423    #        - If the assignment absorbed a reference, call
424    #          generate_post_assignment_code on the RHS,
425    #          otherwise call generate_disposal_code on it.
426    #
427    #      generate_deletion_code
428    #        Called on an argument of a del statement.
429    #        - Call generate_evaluation_code for sub-expressions.
430    #        - Generate code to perform the deletion.
431    #        - Call generate_disposal_code on all sub-expressions.
432    #
433    #
434
435    is_sequence_constructor = False
436    is_dict_literal = False
437    is_set_literal = False
438    is_string_literal = False
439    is_attribute = False
440    is_subscript = False
441    is_slice = False
442
443    is_buffer_access = False
444    is_memview_index = False
445    is_memview_slice = False
446    is_memview_broadcast = False
447    is_memview_copy_assignment = False
448
449    saved_subexpr_nodes = None
450    is_temp = False
451    is_target = False
452    is_starred = False
453
454    constant_result = constant_value_not_set
455
456    child_attrs = property(fget=operator.attrgetter('subexprs'))
457
458    def not_implemented(self, method_name):
459        print_call_chain(method_name, "not implemented") ###
460        raise InternalError(
461            "%s.%s not implemented" %
462                (self.__class__.__name__, method_name))
463
464    def is_lvalue(self):
465        return 0
466
467    def is_addressable(self):
468        return self.is_lvalue() and not self.type.is_memoryviewslice
469
470    def is_ephemeral(self):
471        #  An ephemeral node is one whose result is in
472        #  a Python temporary and we suspect there are no
473        #  other references to it. Certain operations are
474        #  disallowed on such values, since they are
475        #  likely to result in a dangling pointer.
476        return self.type.is_pyobject and self.is_temp
477
478    def subexpr_nodes(self):
479        #  Extract a list of subexpression nodes based
480        #  on the contents of the subexprs class attribute.
481        nodes = []
482        for name in self.subexprs:
483            item = getattr(self, name)
484            if item is not None:
485                if type(item) is list:
486                    nodes.extend(item)
487                else:
488                    nodes.append(item)
489        return nodes
490
491    def result(self):
492        if self.is_temp:
493            #if not self.temp_code:
494            #    pos = (os.path.basename(self.pos[0].get_description()),) + self.pos[1:] if self.pos else '(?)'
495            #    raise RuntimeError("temp result name not set in %s at %r" % (
496            #        self.__class__.__name__, pos))
497            return self.temp_code
498        else:
499            return self.calculate_result_code()
500
501    def pythran_result(self, type_=None):
502        if is_pythran_supported_node_or_none(self):
503            return to_pythran(self)
504
505        assert(type_ is not None)
506        return to_pythran(self, type_)
507
508    def is_c_result_required(self):
509        """
510        Subtypes may return False here if result temp allocation can be skipped.
511        """
512        return True
513
514    def result_as(self, type = None):
515        #  Return the result code cast to the specified C type.
516        if (self.is_temp and self.type.is_pyobject and
517                type != py_object_type):
518            # Allocated temporaries are always PyObject *, which may not
519            # reflect the actual type (e.g. an extension type)
520            return typecast(type, py_object_type, self.result())
521        return typecast(type, self.ctype(), self.result())
522
523    def py_result(self):
524        #  Return the result code cast to PyObject *.
525        return self.result_as(py_object_type)
526
527    def ctype(self):
528        #  Return the native C type of the result (i.e. the
529        #  C type of the result_code expression).
530        return self.result_ctype or self.type
531
532    def get_constant_c_result_code(self):
533        # Return the constant value of this node as a result code
534        # string, or None if the node is not constant.  This method
535        # can be called when the constant result code is required
536        # before the code generation phase.
537        #
538        # The return value is a string that can represent a simple C
539        # value, a constant C name or a constant C expression.  If the
540        # node type depends on Python code, this must return None.
541        return None
542
543    def calculate_constant_result(self):
544        # Calculate the constant compile time result value of this
545        # expression and store it in ``self.constant_result``.  Does
546        # nothing by default, thus leaving ``self.constant_result``
547        # unknown.  If valid, the result can be an arbitrary Python
548        # value.
549        #
550        # This must only be called when it is assured that all
551        # sub-expressions have a valid constant_result value.  The
552        # ConstantFolding transform will do this.
553        pass
554
555    def has_constant_result(self):
556        return self.constant_result is not constant_value_not_set and \
557               self.constant_result is not not_a_constant
558
559    def compile_time_value(self, denv):
560        #  Return value of compile-time expression, or report error.
561        error(self.pos, "Invalid compile-time expression")
562
563    def compile_time_value_error(self, e):
564        error(self.pos, "Error in compile-time expression: %s: %s" % (
565            e.__class__.__name__, e))
566
567    # ------------- Declaration Analysis ----------------
568
569    def analyse_target_declaration(self, env):
570        error(self.pos, "Cannot assign to or delete this")
571
572    # ------------- Expression Analysis ----------------
573
574    def analyse_const_expression(self, env):
575        #  Called during the analyse_declarations phase of a
576        #  constant expression. Analyses the expression's type,
577        #  checks whether it is a legal const expression,
578        #  and determines its value.
579        node = self.analyse_types(env)
580        node.check_const()
581        return node
582
583    def analyse_expressions(self, env):
584        #  Convenience routine performing both the Type
585        #  Analysis and Temp Allocation phases for a whole
586        #  expression.
587        return self.analyse_types(env)
588
589    def analyse_target_expression(self, env, rhs):
590        #  Convenience routine performing both the Type
591        #  Analysis and Temp Allocation phases for the LHS of
592        #  an assignment.
593        return self.analyse_target_types(env)
594
595    def analyse_boolean_expression(self, env):
596        #  Analyse expression and coerce to a boolean.
597        node = self.analyse_types(env)
598        bool = node.coerce_to_boolean(env)
599        return bool
600
601    def analyse_temp_boolean_expression(self, env):
602        #  Analyse boolean expression and coerce result into
603        #  a temporary. This is used when a branch is to be
604        #  performed on the result and we won't have an
605        #  opportunity to ensure disposal code is executed
606        #  afterwards. By forcing the result into a temporary,
607        #  we ensure that all disposal has been done by the
608        #  time we get the result.
609        node = self.analyse_types(env)
610        return node.coerce_to_boolean(env).coerce_to_simple(env)
611
612    # --------------- Type Inference -----------------
613
614    def type_dependencies(self, env):
615        # Returns the list of entries whose types must be determined
616        # before the type of self can be inferred.
617        if hasattr(self, 'type') and self.type is not None:
618            return ()
619        return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
620
621    def infer_type(self, env):
622        # Attempt to deduce the type of self.
623        # Differs from analyse_types as it avoids unnecessary
624        # analysis of subexpressions, but can assume everything
625        # in self.type_dependencies() has been resolved.
626        if hasattr(self, 'type') and self.type is not None:
627            return self.type
628        elif hasattr(self, 'entry') and self.entry is not None:
629            return self.entry.type
630        else:
631            self.not_implemented("infer_type")
632
633    def nonlocally_immutable(self):
634        # Returns whether this variable is a safe reference, i.e.
635        # can't be modified as part of globals or closures.
636        return self.is_literal or self.is_temp or self.type.is_array or self.type.is_cfunction
637
638    def inferable_item_node(self, index=0):
639        """
640        Return a node that represents the (type) result of an indexing operation,
641        e.g. for tuple unpacking or iteration.
642        """
643        return IndexNode(self.pos, base=self, index=IntNode(
644            self.pos, value=str(index), constant_result=index, type=PyrexTypes.c_py_ssize_t_type))
645
646    # --------------- Type Analysis ------------------
647
648    def analyse_as_module(self, env):
649        # If this node can be interpreted as a reference to a
650        # cimported module, return its scope, else None.
651        return None
652
653    def analyse_as_type(self, env):
654        # If this node can be interpreted as a reference to a
655        # type, return that type, else None.
656        return None
657
658    def analyse_as_extension_type(self, env):
659        # If this node can be interpreted as a reference to an
660        # extension type or builtin type, return its type, else None.
661        return None
662
663    def analyse_types(self, env):
664        self.not_implemented("analyse_types")
665
666    def analyse_target_types(self, env):
667        return self.analyse_types(env)
668
669    def nogil_check(self, env):
670        # By default, any expression based on Python objects is
671        # prevented in nogil environments.  Subtypes must override
672        # this if they can work without the GIL.
673        if self.type and self.type.is_pyobject:
674            self.gil_error()
675
676    def gil_assignment_check(self, env):
677        if env.nogil and self.type.is_pyobject:
678            error(self.pos, "Assignment of Python object not allowed without gil")
679
680    def check_const(self):
681        self.not_const()
682        return False
683
684    def not_const(self):
685        error(self.pos, "Not allowed in a constant expression")
686
687    def check_const_addr(self):
688        self.addr_not_const()
689        return False
690
691    def addr_not_const(self):
692        error(self.pos, "Address is not constant")
693
694    # ----------------- Result Allocation -----------------
695
696    def result_in_temp(self):
697        #  Return true if result is in a temporary owned by
698        #  this node or one of its subexpressions. Overridden
699        #  by certain nodes which can share the result of
700        #  a subnode.
701        return self.is_temp
702
703    def target_code(self):
704        #  Return code fragment for use as LHS of a C assignment.
705        return self.calculate_result_code()
706
707    def calculate_result_code(self):
708        self.not_implemented("calculate_result_code")
709
710#    def release_target_temp(self, env):
711#        #  Release temporaries used by LHS of an assignment.
712#        self.release_subexpr_temps(env)
713
714    def allocate_temp_result(self, code):
715        if self.temp_code:
716            raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
717        type = self.type
718        if not type.is_void:
719            if type.is_pyobject:
720                type = PyrexTypes.py_object_type
721            elif not (self.result_is_used or type.is_memoryviewslice or self.is_c_result_required()):
722                self.temp_code = None
723                return
724            self.temp_code = code.funcstate.allocate_temp(
725                type, manage_ref=self.use_managed_ref)
726        else:
727            self.temp_code = None
728
729    def release_temp_result(self, code):
730        if not self.temp_code:
731            if not self.result_is_used:
732                # not used anyway, so ignore if not set up
733                return
734            pos = (os.path.basename(self.pos[0].get_description()),) + self.pos[1:] if self.pos else '(?)'
735            if self.old_temp:
736                raise RuntimeError("temp %s released multiple times in %s at %r" % (
737                    self.old_temp, self.__class__.__name__, pos))
738            else:
739                raise RuntimeError("no temp, but release requested in %s at %r" % (
740                    self.__class__.__name__, pos))
741        code.funcstate.release_temp(self.temp_code)
742        self.old_temp = self.temp_code
743        self.temp_code = None
744
745    # ---------------- Code Generation -----------------
746
747    def make_owned_reference(self, code):
748        """
749        If result is a pyobject, make sure we own a reference to it.
750        If the result is in a temp, it is already a new reference.
751        """
752        if self.type.is_pyobject and not self.result_in_temp():
753            code.put_incref(self.result(), self.ctype())
754
755    def make_owned_memoryviewslice(self, code):
756        """
757        Make sure we own the reference to this memoryview slice.
758        """
759        if not self.result_in_temp():
760            code.put_incref_memoryviewslice(self.result(),
761                                            have_gil=self.in_nogil_context)
762
763    def generate_evaluation_code(self, code):
764        #  Generate code to evaluate this node and
765        #  its sub-expressions, and dispose of any
766        #  temporary results of its sub-expressions.
767        self.generate_subexpr_evaluation_code(code)
768
769        code.mark_pos(self.pos)
770        if self.is_temp:
771            self.allocate_temp_result(code)
772
773        self.generate_result_code(code)
774        if self.is_temp and not (self.type.is_string or self.type.is_pyunicode_ptr):
775            # If we are temp we do not need to wait until this node is disposed
776            # before disposing children.
777            self.generate_subexpr_disposal_code(code)
778            self.free_subexpr_temps(code)
779
780    def generate_subexpr_evaluation_code(self, code):
781        for node in self.subexpr_nodes():
782            node.generate_evaluation_code(code)
783
784    def generate_result_code(self, code):
785        self.not_implemented("generate_result_code")
786
787    def generate_disposal_code(self, code):
788        if self.is_temp:
789            if self.type.is_string or self.type.is_pyunicode_ptr:
790                # postponed from self.generate_evaluation_code()
791                self.generate_subexpr_disposal_code(code)
792                self.free_subexpr_temps(code)
793            if self.result():
794                if self.type.is_pyobject:
795                    code.put_decref_clear(self.result(), self.ctype())
796                elif self.type.is_memoryviewslice:
797                    code.put_xdecref_memoryviewslice(
798                            self.result(), have_gil=not self.in_nogil_context)
799                    code.putln("%s.memview = NULL;" % self.result())
800                    code.putln("%s.data = NULL;" % self.result())
801        else:
802            # Already done if self.is_temp
803            self.generate_subexpr_disposal_code(code)
804
805    def generate_subexpr_disposal_code(self, code):
806        #  Generate code to dispose of temporary results
807        #  of all sub-expressions.
808        for node in self.subexpr_nodes():
809            node.generate_disposal_code(code)
810
811    def generate_post_assignment_code(self, code):
812        if self.is_temp:
813            if self.type.is_string or self.type.is_pyunicode_ptr:
814                # postponed from self.generate_evaluation_code()
815                self.generate_subexpr_disposal_code(code)
816                self.free_subexpr_temps(code)
817            elif self.type.is_pyobject:
818                code.putln("%s = 0;" % self.result())
819            elif self.type.is_memoryviewslice:
820                code.putln("%s.memview = NULL;" % self.result())
821                code.putln("%s.data = NULL;" % self.result())
822        else:
823            self.generate_subexpr_disposal_code(code)
824
825    def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
826        exception_check=None, exception_value=None):
827        #  Stub method for nodes which are not legal as
828        #  the LHS of an assignment. An error will have
829        #  been reported earlier.
830        pass
831
832    def generate_deletion_code(self, code, ignore_nonexisting=False):
833        #  Stub method for nodes that are not legal as
834        #  the argument of a del statement. An error
835        #  will have been reported earlier.
836        pass
837
838    def free_temps(self, code):
839        if self.is_temp:
840            if not self.type.is_void:
841                self.release_temp_result(code)
842        else:
843            self.free_subexpr_temps(code)
844
845    def free_subexpr_temps(self, code):
846        for sub in self.subexpr_nodes():
847            sub.free_temps(code)
848
849    def generate_function_definitions(self, env, code):
850        pass
851
852    # ---------------- Annotation ---------------------
853
854    def annotate(self, code):
855        for node in self.subexpr_nodes():
856            node.annotate(code)
857
858    # ----------------- Coercion ----------------------
859
860    def coerce_to(self, dst_type, env):
861        #   Coerce the result so that it can be assigned to
862        #   something of type dst_type. If processing is necessary,
863        #   wraps this node in a coercion node and returns that.
864        #   Otherwise, returns this node unchanged.
865        #
866        #   This method is called during the analyse_expressions
867        #   phase of the src_node's processing.
868        #
869        #   Note that subclasses that override this (especially
870        #   ConstNodes) must not (re-)set their own .type attribute
871        #   here.  Since expression nodes may turn up in different
872        #   places in the tree (e.g. inside of CloneNodes in cascaded
873        #   assignments), this method must return a new node instance
874        #   if it changes the type.
875        #
876        src = self
877        src_type = self.type
878
879        if self.check_for_coercion_error(dst_type, env):
880            return self
881
882        used_as_reference = dst_type.is_reference
883        if used_as_reference and not src_type.is_reference:
884            dst_type = dst_type.ref_base_type
885
886        if src_type.is_const:
887            src_type = src_type.const_base_type
888
889        if src_type.is_fused or dst_type.is_fused:
890            # See if we are coercing a fused function to a pointer to a
891            # specialized function
892            if (src_type.is_cfunction and not dst_type.is_fused and
893                    dst_type.is_ptr and dst_type.base_type.is_cfunction):
894
895                dst_type = dst_type.base_type
896
897                for signature in src_type.get_all_specialized_function_types():
898                    if signature.same_as(dst_type):
899                        src.type = signature
900                        src.entry = src.type.entry
901                        src.entry.used = True
902                        return self
903
904            if src_type.is_fused:
905                error(self.pos, "Type is not specialized")
906            elif src_type.is_null_ptr and dst_type.is_ptr:
907                # NULL can be implicitly cast to any pointer type
908                return self
909            else:
910                error(self.pos, "Cannot coerce to a type that is not specialized")
911
912            self.type = error_type
913            return self
914
915        if self.coercion_type is not None:
916            # This is purely for error checking purposes!
917            node = NameNode(self.pos, name='', type=self.coercion_type)
918            node.coerce_to(dst_type, env)
919
920        if dst_type.is_memoryviewslice:
921            from . import MemoryView
922            if not src.type.is_memoryviewslice:
923                if src.type.is_pyobject:
924                    src = CoerceToMemViewSliceNode(src, dst_type, env)
925                elif src.type.is_array:
926                    src = CythonArrayNode.from_carray(src, env).coerce_to(dst_type, env)
927                elif not src_type.is_error:
928                    error(self.pos,
929                          "Cannot convert '%s' to memoryviewslice" % (src_type,))
930            else:
931                if src.type.writable_needed:
932                    dst_type.writable_needed = True
933                if not src.type.conforms_to(dst_type, broadcast=self.is_memview_broadcast,
934                                            copying=self.is_memview_copy_assignment):
935                    if src.type.dtype.same_as(dst_type.dtype):
936                        msg = "Memoryview '%s' not conformable to memoryview '%s'."
937                        tup = src.type, dst_type
938                    else:
939                        msg = "Different base types for memoryviews (%s, %s)"
940                        tup = src.type.dtype, dst_type.dtype
941
942                    error(self.pos, msg % tup)
943
944        elif dst_type.is_pyobject:
945            if not src.type.is_pyobject:
946                if dst_type is bytes_type and src.type.is_int:
947                    src = CoerceIntToBytesNode(src, env)
948                else:
949                    src = CoerceToPyTypeNode(src, env, type=dst_type)
950            if not src.type.subtype_of(dst_type):
951                if src.constant_result is not None:
952                    src = PyTypeTestNode(src, dst_type, env)
953        elif is_pythran_expr(dst_type) and is_pythran_supported_type(src.type):
954            # We let the compiler decide whether this is valid
955            return src
956        elif is_pythran_expr(src.type):
957            if is_pythran_supported_type(dst_type):
958                # Match the case were a pythran expr is assigned to a value, or vice versa.
959                # We let the C++ compiler decide whether this is valid or not!
960                return src
961            # Else, we need to convert the Pythran expression to a Python object
962            src = CoerceToPyTypeNode(src, env, type=dst_type)
963        elif src.type.is_pyobject:
964            if used_as_reference and dst_type.is_cpp_class:
965                warning(
966                    self.pos,
967                    "Cannot pass Python object as C++ data structure reference (%s &), will pass by copy." % dst_type)
968            src = CoerceFromPyTypeNode(dst_type, src, env)
969        elif (dst_type.is_complex
970              and src_type != dst_type
971              and dst_type.assignable_from(src_type)):
972            src = CoerceToComplexNode(src, dst_type, env)
973        else: # neither src nor dst are py types
974            # Added the string comparison, since for c types that
975            # is enough, but Cython gets confused when the types are
976            # in different pxi files.
977            # TODO: Remove this hack and require shared declarations.
978            if not (src.type == dst_type or str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
979                self.fail_assignment(dst_type)
980        return src
981
982    def fail_assignment(self, dst_type):
983        error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
984
985    def check_for_coercion_error(self, dst_type, env, fail=False, default=None):
986        if fail and not default:
987            default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
988        message = find_coercion_error((self.type, dst_type), default, env)
989        if message is not None:
990            error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
991            return True
992        if fail:
993            self.fail_assignment(dst_type)
994            return True
995        return False
996
997    def coerce_to_pyobject(self, env):
998        return self.coerce_to(PyrexTypes.py_object_type, env)
999
1000    def coerce_to_boolean(self, env):
1001        #  Coerce result to something acceptable as
1002        #  a boolean value.
1003
1004        # if it's constant, calculate the result now
1005        if self.has_constant_result():
1006            bool_value = bool(self.constant_result)
1007            return BoolNode(self.pos, value=bool_value,
1008                            constant_result=bool_value)
1009
1010        type = self.type
1011        if type.is_enum or type.is_error:
1012            return self
1013        elif type.is_pyobject or type.is_int or type.is_ptr or type.is_float:
1014            return CoerceToBooleanNode(self, env)
1015        elif type.is_cpp_class:
1016            return SimpleCallNode(
1017                self.pos,
1018                function=AttributeNode(
1019                    self.pos, obj=self, attribute='operator bool'),
1020                args=[]).analyse_types(env)
1021        elif type.is_ctuple:
1022            bool_value = len(type.components) == 0
1023            return BoolNode(self.pos, value=bool_value,
1024                            constant_result=bool_value)
1025        else:
1026            error(self.pos, "Type '%s' not acceptable as a boolean" % type)
1027            return self
1028
1029    def coerce_to_integer(self, env):
1030        # If not already some C integer type, coerce to longint.
1031        if self.type.is_int:
1032            return self
1033        else:
1034            return self.coerce_to(PyrexTypes.c_long_type, env)
1035
1036    def coerce_to_temp(self, env):
1037        #  Ensure that the result is in a temporary.
1038        if self.result_in_temp():
1039            return self
1040        else:
1041            return CoerceToTempNode(self, env)
1042
1043    def coerce_to_simple(self, env):
1044        #  Ensure that the result is simple (see is_simple).
1045        if self.is_simple():
1046            return self
1047        else:
1048            return self.coerce_to_temp(env)
1049
1050    def is_simple(self):
1051        #  A node is simple if its result is something that can
1052        #  be referred to without performing any operations, e.g.
1053        #  a constant, local var, C global var, struct member
1054        #  reference, or temporary.
1055        return self.result_in_temp()
1056
1057    def may_be_none(self):
1058        if self.type and not (self.type.is_pyobject or
1059                              self.type.is_memoryviewslice):
1060            return False
1061        if self.has_constant_result():
1062            return self.constant_result is not None
1063        return True
1064
1065    def as_cython_attribute(self):
1066        return None
1067
1068    def as_none_safe_node(self, message, error="PyExc_TypeError", format_args=()):
1069        # Wraps the node in a NoneCheckNode if it is not known to be
1070        # not-None (e.g. because it is a Python literal).
1071        if self.may_be_none():
1072            return NoneCheckNode(self, error, message, format_args)
1073        else:
1074            return self
1075
1076    @classmethod
1077    def from_node(cls, node, **kwargs):
1078        """Instantiate this node class from another node, properly
1079        copying over all attributes that one would forget otherwise.
1080        """
1081        attributes = "cf_state cf_maybe_null cf_is_null constant_result".split()
1082        for attr_name in attributes:
1083            if attr_name in kwargs:
1084                continue
1085            try:
1086                value = getattr(node, attr_name)
1087            except AttributeError:
1088                pass
1089            else:
1090                kwargs[attr_name] = value
1091        return cls(node.pos, **kwargs)
1092
1093
1094class AtomicExprNode(ExprNode):
1095    #  Abstract base class for expression nodes which have
1096    #  no sub-expressions.
1097
1098    subexprs = []
1099
1100    # Override to optimize -- we know we have no children
1101    def generate_subexpr_evaluation_code(self, code):
1102        pass
1103    def generate_subexpr_disposal_code(self, code):
1104        pass
1105
1106class PyConstNode(AtomicExprNode):
1107    #  Abstract base class for constant Python values.
1108
1109    is_literal = 1
1110    type = py_object_type
1111
1112    def is_simple(self):
1113        return 1
1114
1115    def may_be_none(self):
1116        return False
1117
1118    def analyse_types(self, env):
1119        return self
1120
1121    def calculate_result_code(self):
1122        return self.value
1123
1124    def generate_result_code(self, code):
1125        pass
1126
1127
1128class NoneNode(PyConstNode):
1129    #  The constant value None
1130
1131    is_none = 1
1132    value = "Py_None"
1133
1134    constant_result = None
1135
1136    nogil_check = None
1137
1138    def compile_time_value(self, denv):
1139        return None
1140
1141    def may_be_none(self):
1142        return True
1143
1144    def coerce_to(self, dst_type, env):
1145        if not (dst_type.is_pyobject or dst_type.is_memoryviewslice or dst_type.is_error):
1146            # Catch this error early and loudly.
1147            error(self.pos, "Cannot assign None to %s" % dst_type)
1148        return super(NoneNode, self).coerce_to(dst_type, env)
1149
1150
1151class EllipsisNode(PyConstNode):
1152    #  '...' in a subscript list.
1153
1154    value = "Py_Ellipsis"
1155
1156    constant_result = Ellipsis
1157
1158    def compile_time_value(self, denv):
1159        return Ellipsis
1160
1161
1162class ConstNode(AtomicExprNode):
1163    # Abstract base type for literal constant nodes.
1164    #
1165    # value     string      C code fragment
1166
1167    is_literal = 1
1168    nogil_check = None
1169
1170    def is_simple(self):
1171        return 1
1172
1173    def nonlocally_immutable(self):
1174        return 1
1175
1176    def may_be_none(self):
1177        return False
1178
1179    def analyse_types(self, env):
1180        return self  # Types are held in class variables
1181
1182    def check_const(self):
1183        return True
1184
1185    def get_constant_c_result_code(self):
1186        return self.calculate_result_code()
1187
1188    def calculate_result_code(self):
1189        return str(self.value)
1190
1191    def generate_result_code(self, code):
1192        pass
1193
1194
1195class BoolNode(ConstNode):
1196    type = PyrexTypes.c_bint_type
1197    #  The constant value True or False
1198
1199    def calculate_constant_result(self):
1200        self.constant_result = self.value
1201
1202    def compile_time_value(self, denv):
1203        return self.value
1204
1205    def calculate_result_code(self):
1206        if self.type.is_pyobject:
1207            return self.value and 'Py_True' or 'Py_False'
1208        else:
1209            return str(int(self.value))
1210
1211    def coerce_to(self, dst_type, env):
1212        if dst_type == self.type:
1213            return self
1214        if dst_type is py_object_type and self.type is Builtin.bool_type:
1215            return self
1216        if dst_type.is_pyobject and self.type.is_int:
1217            return BoolNode(
1218                self.pos, value=self.value,
1219                constant_result=self.constant_result,
1220                type=Builtin.bool_type)
1221        if dst_type.is_int and self.type.is_pyobject:
1222            return BoolNode(
1223                self.pos, value=self.value,
1224                constant_result=self.constant_result,
1225                type=PyrexTypes.c_bint_type)
1226        return ConstNode.coerce_to(self, dst_type, env)
1227
1228
1229class NullNode(ConstNode):
1230    type = PyrexTypes.c_null_ptr_type
1231    value = "NULL"
1232    constant_result = 0
1233
1234    def get_constant_c_result_code(self):
1235        return self.value
1236
1237
1238class CharNode(ConstNode):
1239    type = PyrexTypes.c_char_type
1240
1241    def calculate_constant_result(self):
1242        self.constant_result = ord(self.value)
1243
1244    def compile_time_value(self, denv):
1245        return ord(self.value)
1246
1247    def calculate_result_code(self):
1248        return "'%s'" % StringEncoding.escape_char(self.value)
1249
1250
1251class IntNode(ConstNode):
1252
1253    # unsigned     "" or "U"
1254    # longness     "" or "L" or "LL"
1255    # is_c_literal   True/False/None   creator considers this a C integer literal
1256
1257    unsigned = ""
1258    longness = ""
1259    is_c_literal = None # unknown
1260
1261    def __init__(self, pos, **kwds):
1262        ExprNode.__init__(self, pos, **kwds)
1263        if 'type' not in kwds:
1264            self.type = self.find_suitable_type_for_value()
1265
1266    def find_suitable_type_for_value(self):
1267        if self.constant_result is constant_value_not_set:
1268            try:
1269                self.calculate_constant_result()
1270            except ValueError:
1271                pass
1272        # we ignore 'is_c_literal = True' and instead map signed 32bit
1273        # integers as C long values
1274        if self.is_c_literal or \
1275               not self.has_constant_result() or \
1276               self.unsigned or self.longness == 'LL':
1277            # clearly a C literal
1278            rank = (self.longness == 'LL') and 2 or 1
1279            suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
1280            if self.type:
1281                suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
1282        else:
1283            # C literal or Python literal - split at 32bit boundary
1284            if -2**31 <= self.constant_result < 2**31:
1285                if self.type and self.type.is_int:
1286                    suitable_type = self.type
1287                else:
1288                    suitable_type = PyrexTypes.c_long_type
1289            else:
1290                suitable_type = PyrexTypes.py_object_type
1291        return suitable_type
1292
1293    def coerce_to(self, dst_type, env):
1294        if self.type is dst_type:
1295            return self
1296        elif dst_type.is_float:
1297            if self.has_constant_result():
1298                return FloatNode(self.pos, value='%d.0' % int(self.constant_result), type=dst_type,
1299                                 constant_result=float(self.constant_result))
1300            else:
1301                return FloatNode(self.pos, value=self.value, type=dst_type,
1302                                 constant_result=not_a_constant)
1303        if dst_type.is_numeric and not dst_type.is_complex:
1304            node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
1305                           type=dst_type, is_c_literal=True,
1306                           unsigned=self.unsigned, longness=self.longness)
1307            return node
1308        elif dst_type.is_pyobject:
1309            node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
1310                           type=PyrexTypes.py_object_type, is_c_literal=False,
1311                           unsigned=self.unsigned, longness=self.longness)
1312        else:
1313            # FIXME: not setting the type here to keep it working with
1314            # complex numbers. Should they be special cased?
1315            node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
1316                           unsigned=self.unsigned, longness=self.longness)
1317        # We still need to perform normal coerce_to processing on the
1318        # result, because we might be coercing to an extension type,
1319        # in which case a type test node will be needed.
1320        return ConstNode.coerce_to(node, dst_type, env)
1321
1322    def coerce_to_boolean(self, env):
1323        return IntNode(
1324            self.pos, value=self.value,
1325            constant_result=self.constant_result,
1326            type=PyrexTypes.c_bint_type,
1327            unsigned=self.unsigned, longness=self.longness)
1328
1329    def generate_evaluation_code(self, code):
1330        if self.type.is_pyobject:
1331            # pre-allocate a Python version of the number
1332            plain_integer_string = str(Utils.str_to_number(self.value))
1333            self.result_code = code.get_py_int(plain_integer_string, self.longness)
1334        else:
1335            self.result_code = self.get_constant_c_result_code()
1336
1337    def get_constant_c_result_code(self):
1338        unsigned, longness = self.unsigned, self.longness
1339        literal = self.value_as_c_integer_string()
1340        if not (unsigned or longness) and self.type.is_int and literal[0] == '-' and literal[1] != '0':
1341            # negative decimal literal => guess longness from type to prevent wrap-around
1342            if self.type.rank >= PyrexTypes.c_longlong_type.rank:
1343                longness = 'LL'
1344            elif self.type.rank >= PyrexTypes.c_long_type.rank:
1345                longness = 'L'
1346        return literal + unsigned + longness
1347
1348    def value_as_c_integer_string(self):
1349        value = self.value
1350        if len(value) <= 2:
1351            # too short to go wrong (and simplifies code below)
1352            return value
1353        neg_sign = ''
1354        if value[0] == '-':
1355            neg_sign = '-'
1356            value = value[1:]
1357        if value[0] == '0':
1358            literal_type = value[1]  # 0'o' - 0'b' - 0'x'
1359            # 0x123 hex literals and 0123 octal literals work nicely in C
1360            # but C-incompatible Py3 oct/bin notations need conversion
1361            if neg_sign and literal_type in 'oOxX0123456789' and value[2:].isdigit():
1362                # negative hex/octal literal => prevent C compiler from using
1363                # unsigned integer types by converting to decimal (see C standard 6.4.4.1)
1364                value = str(Utils.str_to_number(value))
1365            elif literal_type in 'oO':
1366                value = '0' + value[2:]  # '0o123' => '0123'
1367            elif literal_type in 'bB':
1368                value = str(int(value[2:], 2))
1369        elif value.isdigit() and not self.unsigned and not self.longness:
1370            if not neg_sign:
1371                # C compilers do not consider unsigned types for decimal literals,
1372                # but they do for hex (see C standard 6.4.4.1)
1373                value = '0x%X' % int(value)
1374        return neg_sign + value
1375
1376    def calculate_result_code(self):
1377        return self.result_code
1378
1379    def calculate_constant_result(self):
1380        self.constant_result = Utils.str_to_number(self.value)
1381
1382    def compile_time_value(self, denv):
1383        return Utils.str_to_number(self.value)
1384
1385class FloatNode(ConstNode):
1386    type = PyrexTypes.c_double_type
1387
1388    def calculate_constant_result(self):
1389        self.constant_result = float(self.value)
1390
1391    def compile_time_value(self, denv):
1392        return float(self.value)
1393
1394    def coerce_to(self, dst_type, env):
1395        if dst_type.is_pyobject and self.type.is_float:
1396            return FloatNode(
1397                self.pos, value=self.value,
1398                constant_result=self.constant_result,
1399                type=Builtin.float_type)
1400        if dst_type.is_float and self.type.is_pyobject:
1401            return FloatNode(
1402                self.pos, value=self.value,
1403                constant_result=self.constant_result,
1404                type=dst_type)
1405        return ConstNode.coerce_to(self, dst_type, env)
1406
1407    def calculate_result_code(self):
1408        return self.result_code
1409
1410    def get_constant_c_result_code(self):
1411        strval = self.value
1412        assert isinstance(strval, basestring)
1413        cmpval = repr(float(strval))
1414        if cmpval == 'nan':
1415            return "(Py_HUGE_VAL * 0)"
1416        elif cmpval == 'inf':
1417            return "Py_HUGE_VAL"
1418        elif cmpval == '-inf':
1419            return "(-Py_HUGE_VAL)"
1420        else:
1421            return strval
1422
1423    def generate_evaluation_code(self, code):
1424        c_value = self.get_constant_c_result_code()
1425        if self.type.is_pyobject:
1426            self.result_code = code.get_py_float(self.value, c_value)
1427        else:
1428            self.result_code = c_value
1429
1430
1431def _analyse_name_as_type(name, pos, env):
1432    type = PyrexTypes.parse_basic_type(name)
1433    if type is not None:
1434        return type
1435
1436    global_entry = env.global_scope().lookup(name)
1437    if global_entry and global_entry.type and (
1438            global_entry.type.is_extension_type
1439            or global_entry.type.is_struct_or_union
1440            or global_entry.type.is_builtin_type
1441            or global_entry.type.is_cpp_class):
1442        return global_entry.type
1443
1444    from .TreeFragment import TreeFragment
1445    with local_errors(ignore=True):
1446        pos = (pos[0], pos[1], pos[2]-7)
1447        try:
1448            declaration = TreeFragment(u"sizeof(%s)" % name, name=pos[0].filename, initial_pos=pos)
1449        except CompileError:
1450            pass
1451        else:
1452            sizeof_node = declaration.root.stats[0].expr
1453            if isinstance(sizeof_node, SizeofTypeNode):
1454                sizeof_node = sizeof_node.analyse_types(env)
1455                if isinstance(sizeof_node, SizeofTypeNode):
1456                    return sizeof_node.arg_type
1457    return None
1458
1459
1460class BytesNode(ConstNode):
1461    # A char* or bytes literal
1462    #
1463    # value      BytesLiteral
1464
1465    is_string_literal = True
1466    # start off as Python 'bytes' to support len() in O(1)
1467    type = bytes_type
1468
1469    def calculate_constant_result(self):
1470        self.constant_result = self.value
1471
1472    def as_sliced_node(self, start, stop, step=None):
1473        value = StringEncoding.bytes_literal(self.value[start:stop:step], self.value.encoding)
1474        return BytesNode(self.pos, value=value, constant_result=value)
1475
1476    def compile_time_value(self, denv):
1477        return self.value.byteencode()
1478
1479    def analyse_as_type(self, env):
1480        return _analyse_name_as_type(self.value.decode('ISO8859-1'), self.pos, env)
1481
1482    def can_coerce_to_char_literal(self):
1483        return len(self.value) == 1
1484
1485    def coerce_to_boolean(self, env):
1486        # This is special because testing a C char* for truth directly
1487        # would yield the wrong result.
1488        bool_value = bool(self.value)
1489        return BoolNode(self.pos, value=bool_value, constant_result=bool_value)
1490
1491    def coerce_to(self, dst_type, env):
1492        if self.type == dst_type:
1493            return self
1494        if dst_type.is_int:
1495            if not self.can_coerce_to_char_literal():
1496                error(self.pos, "Only single-character string literals can be coerced into ints.")
1497                return self
1498            if dst_type.is_unicode_char:
1499                error(self.pos, "Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead.")
1500                return self
1501            return CharNode(self.pos, value=self.value,
1502                            constant_result=ord(self.value))
1503
1504        node = BytesNode(self.pos, value=self.value, constant_result=self.constant_result)
1505        if dst_type.is_pyobject:
1506            if dst_type in (py_object_type, Builtin.bytes_type):
1507                node.type = Builtin.bytes_type
1508            else:
1509                self.check_for_coercion_error(dst_type, env, fail=True)
1510            return node
1511        elif dst_type in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_const_char_ptr_type):
1512            node.type = dst_type
1513            return node
1514        elif dst_type in (PyrexTypes.c_uchar_ptr_type, PyrexTypes.c_const_uchar_ptr_type, PyrexTypes.c_void_ptr_type):
1515            node.type = (PyrexTypes.c_const_char_ptr_type if dst_type == PyrexTypes.c_const_uchar_ptr_type
1516                         else PyrexTypes.c_char_ptr_type)
1517            return CastNode(node, dst_type)
1518        elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
1519            # Exclude the case of passing a C string literal into a non-const C++ string.
1520            if not dst_type.is_cpp_class or dst_type.is_const:
1521                node.type = dst_type
1522                return node
1523
1524        # We still need to perform normal coerce_to processing on the
1525        # result, because we might be coercing to an extension type,
1526        # in which case a type test node will be needed.
1527        return ConstNode.coerce_to(node, dst_type, env)
1528
1529    def generate_evaluation_code(self, code):
1530        if self.type.is_pyobject:
1531            result = code.get_py_string_const(self.value)
1532        elif self.type.is_const:
1533            result = code.get_string_const(self.value)
1534        else:
1535            # not const => use plain C string literal and cast to mutable type
1536            literal = self.value.as_c_string_literal()
1537            # C++ may require a cast
1538            result = typecast(self.type, PyrexTypes.c_void_ptr_type, literal)
1539        self.result_code = result
1540
1541    def get_constant_c_result_code(self):
1542        return None # FIXME
1543
1544    def calculate_result_code(self):
1545        return self.result_code
1546
1547
1548class UnicodeNode(ConstNode):
1549    # A Py_UNICODE* or unicode literal
1550    #
1551    # value        EncodedString
1552    # bytes_value  BytesLiteral    the literal parsed as bytes string
1553    #                              ('-3' unicode literals only)
1554
1555    is_string_literal = True
1556    bytes_value = None
1557    type = unicode_type
1558
1559    def calculate_constant_result(self):
1560        self.constant_result = self.value
1561
1562    def analyse_as_type(self, env):
1563        return _analyse_name_as_type(self.value, self.pos, env)
1564
1565    def as_sliced_node(self, start, stop, step=None):
1566        if StringEncoding.string_contains_surrogates(self.value[:stop]):
1567            # this is unsafe as it may give different results
1568            # in different runtimes
1569            return None
1570        value = StringEncoding.EncodedString(self.value[start:stop:step])
1571        value.encoding = self.value.encoding
1572        if self.bytes_value is not None:
1573            bytes_value = StringEncoding.bytes_literal(
1574                self.bytes_value[start:stop:step], self.bytes_value.encoding)
1575        else:
1576            bytes_value = None
1577        return UnicodeNode(
1578            self.pos, value=value, bytes_value=bytes_value,
1579            constant_result=value)
1580
1581    def coerce_to(self, dst_type, env):
1582        if dst_type is self.type:
1583            pass
1584        elif dst_type.is_unicode_char:
1585            if not self.can_coerce_to_char_literal():
1586                error(self.pos,
1587                      "Only single-character Unicode string literals or "
1588                      "surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.")
1589                return self
1590            int_value = ord(self.value)
1591            return IntNode(self.pos, type=dst_type, value=str(int_value),
1592                           constant_result=int_value)
1593        elif not dst_type.is_pyobject:
1594            if dst_type.is_string and self.bytes_value is not None:
1595                # special case: '-3' enforced unicode literal used in a
1596                # C char* context
1597                return BytesNode(self.pos, value=self.bytes_value
1598                    ).coerce_to(dst_type, env)
1599            if dst_type.is_pyunicode_ptr:
1600                node = UnicodeNode(self.pos, value=self.value)
1601                node.type = dst_type
1602                return node
1603            error(self.pos,
1604                  "Unicode literals do not support coercion to C types other "
1605                  "than Py_UNICODE/Py_UCS4 (for characters) or Py_UNICODE* "
1606                  "(for strings).")
1607        elif dst_type not in (py_object_type, Builtin.basestring_type):
1608            self.check_for_coercion_error(dst_type, env, fail=True)
1609        return self
1610
1611    def can_coerce_to_char_literal(self):
1612        return len(self.value) == 1
1613            ## or (len(self.value) == 2
1614            ##     and (0xD800 <= self.value[0] <= 0xDBFF)
1615            ##     and (0xDC00 <= self.value[1] <= 0xDFFF))
1616
1617    def coerce_to_boolean(self, env):
1618        bool_value = bool(self.value)
1619        return BoolNode(self.pos, value=bool_value, constant_result=bool_value)
1620
1621    def contains_surrogates(self):
1622        return StringEncoding.string_contains_surrogates(self.value)
1623
1624    def generate_evaluation_code(self, code):
1625        if self.type.is_pyobject:
1626            # FIXME: this should go away entirely!
1627            # Since string_contains_lone_surrogates() returns False for surrogate pairs in Py2/UCS2,
1628            # Py2 can generate different code from Py3 here.  Let's hope we get away with claiming that
1629            # the processing of surrogate pairs in code was always ambiguous and lead to different results
1630            # on P16/32bit Unicode platforms.
1631            if StringEncoding.string_contains_lone_surrogates(self.value):
1632                # lone (unpaired) surrogates are not really portable and cannot be
1633                # decoded by the UTF-8 codec in Py3.3
1634                self.result_code = code.get_py_const(py_object_type, 'ustring')
1635                data_cname = code.get_string_const(
1636                    StringEncoding.BytesLiteral(self.value.encode('unicode_escape')))
1637                const_code = code.get_cached_constants_writer(self.result_code)
1638                if const_code is None:
1639                    return  # already initialised
1640                const_code.mark_pos(self.pos)
1641                const_code.putln(
1642                    "%s = PyUnicode_DecodeUnicodeEscape(%s, sizeof(%s) - 1, NULL); %s" % (
1643                        self.result_code,
1644                        data_cname,
1645                        data_cname,
1646                        const_code.error_goto_if_null(self.result_code, self.pos)))
1647                const_code.put_error_if_neg(
1648                    self.pos, "__Pyx_PyUnicode_READY(%s)" % self.result_code)
1649            else:
1650                self.result_code = code.get_py_string_const(self.value)
1651        else:
1652            self.result_code = code.get_pyunicode_ptr_const(self.value)
1653
1654    def calculate_result_code(self):
1655        return self.result_code
1656
1657    def compile_time_value(self, env):
1658        return self.value
1659
1660
1661class StringNode(PyConstNode):
1662    # A Python str object, i.e. a byte string in Python 2.x and a
1663    # unicode string in Python 3.x
1664    #
1665    # value          BytesLiteral (or EncodedString with ASCII content)
1666    # unicode_value  EncodedString or None
1667    # is_identifier  boolean
1668
1669    type = str_type
1670    is_string_literal = True
1671    is_identifier = None
1672    unicode_value = None
1673
1674    def calculate_constant_result(self):
1675        if self.unicode_value is not None:
1676            # only the Unicode value is portable across Py2/3
1677            self.constant_result = self.unicode_value
1678
1679    def analyse_as_type(self, env):
1680        return _analyse_name_as_type(self.unicode_value or self.value.decode('ISO8859-1'), self.pos, env)
1681
1682    def as_sliced_node(self, start, stop, step=None):
1683        value = type(self.value)(self.value[start:stop:step])
1684        value.encoding = self.value.encoding
1685        if self.unicode_value is not None:
1686            if StringEncoding.string_contains_surrogates(self.unicode_value[:stop]):
1687                # this is unsafe as it may give different results in different runtimes
1688                return None
1689            unicode_value = StringEncoding.EncodedString(
1690                self.unicode_value[start:stop:step])
1691        else:
1692            unicode_value = None
1693        return StringNode(
1694            self.pos, value=value, unicode_value=unicode_value,
1695            constant_result=value, is_identifier=self.is_identifier)
1696
1697    def coerce_to(self, dst_type, env):
1698        if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1699#            if dst_type is Builtin.bytes_type:
1700#                # special case: bytes = 'str literal'
1701#                return BytesNode(self.pos, value=self.value)
1702            if not dst_type.is_pyobject:
1703                return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1704            if dst_type is not Builtin.basestring_type:
1705                self.check_for_coercion_error(dst_type, env, fail=True)
1706        return self
1707
1708    def can_coerce_to_char_literal(self):
1709        return not self.is_identifier and len(self.value) == 1
1710
1711    def generate_evaluation_code(self, code):
1712        self.result_code = code.get_py_string_const(
1713            self.value, identifier=self.is_identifier, is_str=True,
1714            unicode_value=self.unicode_value)
1715
1716    def get_constant_c_result_code(self):
1717        return None
1718
1719    def calculate_result_code(self):
1720        return self.result_code
1721
1722    def compile_time_value(self, env):
1723        if self.value.is_unicode:
1724            return self.value
1725        if not IS_PYTHON3:
1726            # use plain str/bytes object in Py2
1727            return self.value.byteencode()
1728        # in Py3, always return a Unicode string
1729        if self.unicode_value is not None:
1730            return self.unicode_value
1731        return self.value.decode('iso8859-1')
1732
1733
1734class IdentifierStringNode(StringNode):
1735    # A special str value that represents an identifier (bytes in Py2,
1736    # unicode in Py3).
1737    is_identifier = True
1738
1739
1740class ImagNode(AtomicExprNode):
1741    #  Imaginary number literal
1742    #
1743    #  value   string    imaginary part (float value)
1744
1745    type = PyrexTypes.c_double_complex_type
1746
1747    def calculate_constant_result(self):
1748        self.constant_result = complex(0.0, float(self.value))
1749
1750    def compile_time_value(self, denv):
1751        return complex(0.0, float(self.value))
1752
1753    def analyse_types(self, env):
1754        self.type.create_declaration_utility_code(env)
1755        return self
1756
1757    def may_be_none(self):
1758        return False
1759
1760    def coerce_to(self, dst_type, env):
1761        if self.type is dst_type:
1762            return self
1763        node = ImagNode(self.pos, value=self.value)
1764        if dst_type.is_pyobject:
1765            node.is_temp = 1
1766            node.type = Builtin.complex_type
1767        # We still need to perform normal coerce_to processing on the
1768        # result, because we might be coercing to an extension type,
1769        # in which case a type test node will be needed.
1770        return AtomicExprNode.coerce_to(node, dst_type, env)
1771
1772    gil_message = "Constructing complex number"
1773
1774    def calculate_result_code(self):
1775        if self.type.is_pyobject:
1776            return self.result()
1777        else:
1778            return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1779
1780    def generate_result_code(self, code):
1781        if self.type.is_pyobject:
1782            code.putln(
1783                "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1784                    self.result(),
1785                    float(self.value),
1786                    code.error_goto_if_null(self.result(), self.pos)))
1787            code.put_gotref(self.py_result())
1788
1789
1790class NewExprNode(AtomicExprNode):
1791
1792    # C++ new statement
1793    #
1794    # cppclass              node                 c++ class to create
1795
1796    type = None
1797
1798    def infer_type(self, env):
1799        type = self.cppclass.analyse_as_type(env)
1800        if type is None or not type.is_cpp_class:
1801            error(self.pos, "new operator can only be applied to a C++ class")
1802            self.type = error_type
1803            return
1804        self.cpp_check(env)
1805        constructor = type.get_constructor(self.pos)
1806        self.class_type = type
1807        self.entry = constructor
1808        self.type = constructor.type
1809        return self.type
1810
1811    def analyse_types(self, env):
1812        if self.type is None:
1813            self.infer_type(env)
1814        return self
1815
1816    def may_be_none(self):
1817        return False
1818
1819    def generate_result_code(self, code):
1820        pass
1821
1822    def calculate_result_code(self):
1823        return "new " + self.class_type.empty_declaration_code()
1824
1825
1826class NameNode(AtomicExprNode):
1827    #  Reference to a local or global variable name.
1828    #
1829    #  name            string    Python name of the variable
1830    #  entry           Entry     Symbol table entry
1831    #  type_entry      Entry     For extension type names, the original type entry
1832    #  cf_is_null      boolean   Is uninitialized before this node
1833    #  cf_maybe_null   boolean   Maybe uninitialized before this node
1834    #  allow_null      boolean   Don't raise UnboundLocalError
1835    #  nogil           boolean   Whether it is used in a nogil context
1836
1837    is_name = True
1838    is_cython_module = False
1839    cython_attribute = None
1840    lhs_of_first_assignment = False # TODO: remove me
1841    is_used_as_rvalue = 0
1842    entry = None
1843    type_entry = None
1844    cf_maybe_null = True
1845    cf_is_null = False
1846    allow_null = False
1847    nogil = False
1848    inferred_type = None
1849
1850    def as_cython_attribute(self):
1851        return self.cython_attribute
1852
1853    def type_dependencies(self, env):
1854        if self.entry is None:
1855            self.entry = env.lookup(self.name)
1856        if self.entry is not None and self.entry.type.is_unspecified:
1857            return (self,)
1858        else:
1859            return ()
1860
1861    def infer_type(self, env):
1862        if self.entry is None:
1863            self.entry = env.lookup(self.name)
1864        if self.entry is None or self.entry.type is unspecified_type:
1865            if self.inferred_type is not None:
1866                return self.inferred_type
1867            return py_object_type
1868        elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1869                self.name == self.entry.type.name:
1870            # Unfortunately the type attribute of type objects
1871            # is used for the pointer to the type they represent.
1872            return type_type
1873        elif self.entry.type.is_cfunction:
1874            if self.entry.scope.is_builtin_scope:
1875                # special case: optimised builtin functions must be treated as Python objects
1876                return py_object_type
1877            else:
1878                # special case: referring to a C function must return its pointer
1879                return PyrexTypes.CPtrType(self.entry.type)
1880        else:
1881            # If entry is inferred as pyobject it's safe to use local
1882            # NameNode's inferred_type.
1883            if self.entry.type.is_pyobject and self.inferred_type:
1884                # Overflow may happen if integer
1885                if not (self.inferred_type.is_int and self.entry.might_overflow):
1886                    return self.inferred_type
1887            return self.entry.type
1888
1889    def compile_time_value(self, denv):
1890        try:
1891            return denv.lookup(self.name)
1892        except KeyError:
1893            error(self.pos, "Compile-time name '%s' not defined" % self.name)
1894
1895    def get_constant_c_result_code(self):
1896        if not self.entry or self.entry.type.is_pyobject:
1897            return None
1898        return self.entry.cname
1899
1900    def coerce_to(self, dst_type, env):
1901        #  If coercing to a generic pyobject and this is a builtin
1902        #  C function with a Python equivalent, manufacture a NameNode
1903        #  referring to the Python builtin.
1904        #print "NameNode.coerce_to:", self.name, dst_type ###
1905        if dst_type is py_object_type:
1906            entry = self.entry
1907            if entry and entry.is_cfunction:
1908                var_entry = entry.as_variable
1909                if var_entry:
1910                    if var_entry.is_builtin and var_entry.is_const:
1911                        var_entry = env.declare_builtin(var_entry.name, self.pos)
1912                    node = NameNode(self.pos, name = self.name)
1913                    node.entry = var_entry
1914                    node.analyse_rvalue_entry(env)
1915                    return node
1916
1917        return super(NameNode, self).coerce_to(dst_type, env)
1918
1919    def declare_from_annotation(self, env, as_target=False):
1920        """Implements PEP 526 annotation typing in a fairly relaxed way.
1921
1922        Annotations are ignored for global variables, Python class attributes and already declared variables.
1923        String literals are allowed and ignored.
1924        The ambiguous Python types 'int' and 'long' are ignored and the 'cython.int' form must be used instead.
1925        """
1926        if not env.directives['annotation_typing']:
1927            return
1928        if env.is_module_scope or env.is_py_class_scope:
1929            # annotations never create global cdef names and Python classes don't support them anyway
1930            return
1931        name = self.name
1932        if self.entry or env.lookup_here(name) is not None:
1933            # already declared => ignore annotation
1934            return
1935
1936        annotation = self.annotation
1937        if annotation.is_string_literal:
1938            # name: "description" => not a type, but still a declared variable or attribute
1939            atype = None
1940        else:
1941            _, atype = analyse_type_annotation(annotation, env)
1942        if atype is None:
1943            atype = unspecified_type if as_target and env.directives['infer_types'] != False else py_object_type
1944        self.entry = env.declare_var(name, atype, self.pos, is_cdef=not as_target)
1945        self.entry.annotation = annotation
1946
1947    def analyse_as_module(self, env):
1948        # Try to interpret this as a reference to a cimported module.
1949        # Returns the module scope, or None.
1950        entry = self.entry
1951        if not entry:
1952            entry = env.lookup(self.name)
1953        if entry and entry.as_module:
1954            return entry.as_module
1955        return None
1956
1957    def analyse_as_type(self, env):
1958        if self.cython_attribute:
1959            type = PyrexTypes.parse_basic_type(self.cython_attribute)
1960        else:
1961            type = PyrexTypes.parse_basic_type(self.name)
1962        if type:
1963            return type
1964        entry = self.entry
1965        if not entry:
1966            entry = env.lookup(self.name)
1967        if entry and entry.is_type:
1968            return entry.type
1969        else:
1970            return None
1971
1972    def analyse_as_extension_type(self, env):
1973        # Try to interpret this as a reference to an extension type.
1974        # Returns the extension type, or None.
1975        entry = self.entry
1976        if not entry:
1977            entry = env.lookup(self.name)
1978        if entry and entry.is_type:
1979            if entry.type.is_extension_type or entry.type.is_builtin_type:
1980                return entry.type
1981        return None
1982
1983    def analyse_target_declaration(self, env):
1984        if not self.entry:
1985            self.entry = env.lookup_here(self.name)
1986        if not self.entry and self.annotation is not None:
1987            # name : type = ...
1988            self.declare_from_annotation(env, as_target=True)
1989        if not self.entry:
1990            if env.directives['warn.undeclared']:
1991                warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1992            if env.directives['infer_types'] != False:
1993                type = unspecified_type
1994            else:
1995                type = py_object_type
1996            self.entry = env.declare_var(self.name, type, self.pos)
1997        if self.entry.is_declared_generic:
1998            self.result_ctype = py_object_type
1999        if self.entry.as_module:
2000            # cimported modules namespace can shadow actual variables
2001            self.entry.is_variable = 1
2002
2003    def analyse_types(self, env):
2004        self.initialized_check = env.directives['initializedcheck']
2005        entry = self.entry
2006        if entry is None:
2007            entry = env.lookup(self.name)
2008            if not entry:
2009                entry = env.declare_builtin(self.name, self.pos)
2010                if entry and entry.is_builtin and entry.is_const:
2011                    self.is_literal = True
2012            if not entry:
2013                self.type = PyrexTypes.error_type
2014                return self
2015            self.entry = entry
2016        entry.used = 1
2017        if entry.type.is_buffer:
2018            from . import Buffer
2019            Buffer.used_buffer_aux_vars(entry)
2020        self.analyse_rvalue_entry(env)
2021        return self
2022
2023    def analyse_target_types(self, env):
2024        self.analyse_entry(env, is_target=True)
2025
2026        entry = self.entry
2027        if entry.is_cfunction and entry.as_variable:
2028            # FIXME: unify "is_overridable" flags below
2029            if (entry.is_overridable or entry.type.is_overridable) or not self.is_lvalue() and entry.fused_cfunction:
2030                # We need this for assigning to cpdef names and for the fused 'def' TreeFragment
2031                entry = self.entry = entry.as_variable
2032                self.type = entry.type
2033
2034        if self.type.is_const:
2035            error(self.pos, "Assignment to const '%s'" % self.name)
2036        if self.type.is_reference:
2037            error(self.pos, "Assignment to reference '%s'" % self.name)
2038        if not self.is_lvalue():
2039            error(self.pos, "Assignment to non-lvalue '%s'" % self.name)
2040            self.type = PyrexTypes.error_type
2041        entry.used = 1
2042        if entry.type.is_buffer:
2043            from . import Buffer
2044            Buffer.used_buffer_aux_vars(entry)
2045        return self
2046
2047    def analyse_rvalue_entry(self, env):
2048        #print "NameNode.analyse_rvalue_entry:", self.name ###
2049        #print "Entry:", self.entry.__dict__ ###
2050        self.analyse_entry(env)
2051        entry = self.entry
2052
2053        if entry.is_declared_generic:
2054            self.result_ctype = py_object_type
2055
2056        if entry.is_pyglobal or entry.is_builtin:
2057            if entry.is_builtin and entry.is_const:
2058                self.is_temp = 0
2059            else:
2060                self.is_temp = 1
2061
2062            self.is_used_as_rvalue = 1
2063        elif entry.type.is_memoryviewslice:
2064            self.is_temp = False
2065            self.is_used_as_rvalue = True
2066            self.use_managed_ref = True
2067        return self
2068
2069    def nogil_check(self, env):
2070        self.nogil = True
2071        if self.is_used_as_rvalue:
2072            entry = self.entry
2073            if entry.is_builtin:
2074                if not entry.is_const: # cached builtins are ok
2075                    self.gil_error()
2076            elif entry.is_pyglobal:
2077                self.gil_error()
2078
2079    gil_message = "Accessing Python global or builtin"
2080
2081    def analyse_entry(self, env, is_target=False):
2082        #print "NameNode.analyse_entry:", self.name ###
2083        self.check_identifier_kind()
2084        entry = self.entry
2085        type = entry.type
2086        if (not is_target and type.is_pyobject and self.inferred_type and
2087                self.inferred_type.is_builtin_type):
2088            # assume that type inference is smarter than the static entry
2089            type = self.inferred_type
2090        self.type = type
2091
2092    def check_identifier_kind(self):
2093        # Check that this is an appropriate kind of name for use in an
2094        # expression.  Also finds the variable entry associated with
2095        # an extension type.
2096        entry = self.entry
2097        if entry.is_type and entry.type.is_extension_type:
2098            self.type_entry = entry
2099        if entry.is_type and entry.type.is_enum:
2100            py_entry = Symtab.Entry(self.name, None, py_object_type)
2101            py_entry.is_pyglobal = True
2102            py_entry.scope = self.entry.scope
2103            self.entry = py_entry
2104        elif not (entry.is_const or entry.is_variable or
2105                  entry.is_builtin or entry.is_cfunction or
2106                  entry.is_cpp_class):
2107            if self.entry.as_variable:
2108                self.entry = self.entry.as_variable
2109            elif not self.is_cython_module:
2110                error(self.pos, "'%s' is not a constant, variable or function identifier" % self.name)
2111
2112    def is_cimported_module_without_shadow(self, env):
2113        if self.is_cython_module or self.cython_attribute:
2114            return False
2115        entry = self.entry or env.lookup(self.name)
2116        return entry.as_module and not entry.is_variable
2117
2118    def is_simple(self):
2119        #  If it's not a C variable, it'll be in a temp.
2120        return 1
2121
2122    def may_be_none(self):
2123        if self.cf_state and self.type and (self.type.is_pyobject or
2124                                            self.type.is_memoryviewslice):
2125            # gard against infinite recursion on self-dependencies
2126            if getattr(self, '_none_checking', False):
2127                # self-dependency - either this node receives a None
2128                # value from *another* node, or it can not reference
2129                # None at this point => safe to assume "not None"
2130                return False
2131            self._none_checking = True
2132            # evaluate control flow state to see if there were any
2133            # potential None values assigned to the node so far
2134            may_be_none = False
2135            for assignment in self.cf_state:
2136                if assignment.rhs.may_be_none():
2137                    may_be_none = True
2138                    break
2139            del self._none_checking
2140            return may_be_none
2141        return super(NameNode, self).may_be_none()
2142
2143    def nonlocally_immutable(self):
2144        if ExprNode.nonlocally_immutable(self):
2145            return True
2146        entry = self.entry
2147        if not entry or entry.in_closure:
2148            return False
2149        return entry.is_local or entry.is_arg or entry.is_builtin or entry.is_readonly
2150
2151    def calculate_target_results(self, env):
2152        pass
2153
2154    def check_const(self):
2155        entry = self.entry
2156        if entry is not None and not (
2157                entry.is_const or
2158                entry.is_cfunction or
2159                entry.is_builtin or
2160                entry.type.is_const):
2161            self.not_const()
2162            return False
2163        return True
2164
2165    def check_const_addr(self):
2166        entry = self.entry
2167        if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
2168            self.addr_not_const()
2169            return False
2170        return True
2171
2172    def is_lvalue(self):
2173        return (
2174            self.entry.is_variable and
2175            not self.entry.is_readonly
2176        ) or (
2177            self.entry.is_cfunction and
2178            self.entry.is_overridable
2179        )
2180
2181    def is_addressable(self):
2182        return self.entry.is_variable and not self.type.is_memoryviewslice
2183
2184    def is_ephemeral(self):
2185        #  Name nodes are never ephemeral, even if the
2186        #  result is in a temporary.
2187        return 0
2188
2189    def calculate_result_code(self):
2190        entry = self.entry
2191        if not entry:
2192            return "<error>" # There was an error earlier
2193        return entry.cname
2194
2195    def generate_result_code(self, code):
2196        assert hasattr(self, 'entry')
2197        entry = self.entry
2198        if entry is None:
2199            return # There was an error earlier
2200        if entry.utility_code:
2201            code.globalstate.use_utility_code(entry.utility_code)
2202        if entry.is_builtin and entry.is_const:
2203            return # Lookup already cached
2204        elif entry.is_pyclass_attr:
2205            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
2206            interned_cname = code.intern_identifier(self.entry.name)
2207            if entry.is_builtin:
2208                namespace = Naming.builtins_cname
2209            else: # entry.is_pyglobal
2210                namespace = entry.scope.namespace_cname
2211            if not self.cf_is_null:
2212                code.putln(
2213                    '%s = PyObject_GetItem(%s, %s);' % (
2214                        self.result(),
2215                        namespace,
2216                        interned_cname))
2217                code.putln('if (unlikely(!%s)) {' % self.result())
2218                code.putln('PyErr_Clear();')
2219            code.globalstate.use_utility_code(
2220                UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
2221            code.putln(
2222                '__Pyx_GetModuleGlobalName(%s, %s);' % (
2223                    self.result(),
2224                    interned_cname))
2225            if not self.cf_is_null:
2226                code.putln("}")
2227            code.putln(code.error_goto_if_null(self.result(), self.pos))
2228            code.put_gotref(self.py_result())
2229
2230        elif entry.is_builtin and not entry.scope.is_module_scope:
2231            # known builtin
2232            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
2233            interned_cname = code.intern_identifier(self.entry.name)
2234            code.globalstate.use_utility_code(
2235                UtilityCode.load_cached("GetBuiltinName", "ObjectHandling.c"))
2236            code.putln(
2237                '%s = __Pyx_GetBuiltinName(%s); %s' % (
2238                self.result(),
2239                interned_cname,
2240                code.error_goto_if_null(self.result(), self.pos)))
2241            code.put_gotref(self.py_result())
2242
2243        elif entry.is_pyglobal or (entry.is_builtin and entry.scope.is_module_scope):
2244            # name in class body, global name or unknown builtin
2245            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
2246            interned_cname = code.intern_identifier(self.entry.name)
2247            if entry.scope.is_module_scope:
2248                code.globalstate.use_utility_code(
2249                    UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
2250                code.putln(
2251                    '__Pyx_GetModuleGlobalName(%s, %s); %s' % (
2252                        self.result(),
2253                        interned_cname,
2254                        code.error_goto_if_null(self.result(), self.pos)))
2255            else:
2256                # FIXME: is_pyglobal is also used for class namespace
2257                code.globalstate.use_utility_code(
2258                    UtilityCode.load_cached("GetNameInClass", "ObjectHandling.c"))
2259                code.putln(
2260                    '__Pyx_GetNameInClass(%s, %s, %s); %s' % (
2261                        self.result(),
2262                        entry.scope.namespace_cname,
2263                        interned_cname,
2264                        code.error_goto_if_null(self.result(), self.pos)))
2265            code.put_gotref(self.py_result())
2266
2267        elif entry.is_local or entry.in_closure or entry.from_closure or entry.type.is_memoryviewslice:
2268            # Raise UnboundLocalError for objects and memoryviewslices
2269            raise_unbound = (
2270                (self.cf_maybe_null or self.cf_is_null) and not self.allow_null)
2271            null_code = entry.type.check_for_null_code(entry.cname)
2272
2273            memslice_check = entry.type.is_memoryviewslice and self.initialized_check
2274
2275            if null_code and raise_unbound and (entry.type.is_pyobject or memslice_check):
2276                code.put_error_if_unbound(self.pos, entry, self.in_nogil_context)
2277
2278    def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
2279        exception_check=None, exception_value=None):
2280        #print "NameNode.generate_assignment_code:", self.name ###
2281        entry = self.entry
2282        if entry is None:
2283            return # There was an error earlier
2284
2285        if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
2286                and not self.lhs_of_first_assignment and not rhs.in_module_scope):
2287            error(self.pos, "Literal list must be assigned to pointer at time of declaration")
2288
2289        # is_pyglobal seems to be True for module level-globals only.
2290        # We use this to access class->tp_dict if necessary.
2291        if entry.is_pyglobal:
2292            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
2293            interned_cname = code.intern_identifier(self.entry.name)
2294            namespace = self.entry.scope.namespace_cname
2295            if entry.is_member:
2296                # if the entry is a member we have to cheat: SetAttr does not work
2297                # on types, so we create a descriptor which is then added to tp_dict
2298                setter = 'PyDict_SetItem'
2299                namespace = '%s->tp_dict' % namespace
2300            elif entry.scope.is_module_scope:
2301                setter = 'PyDict_SetItem'
2302                namespace = Naming.moddict_cname
2303            elif entry.is_pyclass_attr:
2304                code.globalstate.use_utility_code(UtilityCode.load_cached("SetNameInClass", "ObjectHandling.c"))
2305                setter = '__Pyx_SetNameInClass'
2306            else:
2307                assert False, repr(entry)
2308            code.put_error_if_neg(
2309                self.pos,
2310                '%s(%s, %s, %s)' % (
2311                    setter,
2312                    namespace,
2313                    interned_cname,
2314                    rhs.py_result()))
2315            if debug_disposal_code:
2316                print("NameNode.generate_assignment_code:")
2317                print("...generating disposal code for %s" % rhs)
2318            rhs.generate_disposal_code(code)
2319            rhs.free_temps(code)
2320            if entry.is_member:
2321                # in Py2.6+, we need to invalidate the method cache
2322                code.putln("PyType_Modified(%s);" %
2323                           entry.scope.parent_type.typeptr_cname)
2324        else:
2325            if self.type.is_memoryviewslice:
2326                self.generate_acquire_memoryviewslice(rhs, code)
2327
2328            elif self.type.is_buffer:
2329                # Generate code for doing the buffer release/acquisition.
2330                # This might raise an exception in which case the assignment (done
2331                # below) will not happen.
2332                #
2333                # The reason this is not in a typetest-like node is because the
2334                # variables that the acquired buffer info is stored to is allocated
2335                # per entry and coupled with it.
2336                self.generate_acquire_buffer(rhs, code)
2337            assigned = False
2338            if self.type.is_pyobject:
2339                #print "NameNode.generate_assignment_code: to", self.name ###
2340                #print "...from", rhs ###
2341                #print "...LHS type", self.type, "ctype", self.ctype() ###
2342                #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
2343                if self.use_managed_ref:
2344                    rhs.make_owned_reference(code)
2345                    is_external_ref = entry.is_cglobal or self.entry.in_closure or self.entry.from_closure
2346                    if is_external_ref:
2347                        if not self.cf_is_null:
2348                            if self.cf_maybe_null:
2349                                code.put_xgotref(self.py_result())
2350                            else:
2351                                code.put_gotref(self.py_result())
2352                    assigned = True
2353                    if entry.is_cglobal:
2354                        code.put_decref_set(
2355                            self.result(), rhs.result_as(self.ctype()))
2356                    else:
2357                        if not self.cf_is_null:
2358                            if self.cf_maybe_null:
2359                                code.put_xdecref_set(
2360                                    self.result(), rhs.result_as(self.ctype()))
2361                            else:
2362                                code.put_decref_set(
2363                                    self.result(), rhs.result_as(self.ctype()))
2364                        else:
2365                            assigned = False
2366                    if is_external_ref:
2367                        code.put_giveref(rhs.py_result())
2368            if not self.type.is_memoryviewslice:
2369                if not assigned:
2370                    if overloaded_assignment:
2371                        result = rhs.result()
2372                        if exception_check == '+':
2373                            translate_cpp_exception(
2374                                code, self.pos,
2375                                '%s = %s;' % (self.result(), result),
2376                                self.result() if self.type.is_pyobject else None,
2377                                exception_value, self.in_nogil_context)
2378                        else:
2379                            code.putln('%s = %s;' % (self.result(), result))
2380                    else:
2381                        result = rhs.result_as(self.ctype())
2382
2383                        if is_pythran_expr(self.type):
2384                            code.putln('new (&%s) decltype(%s){%s};' % (self.result(), self.result(), result))
2385                        elif result != self.result():
2386                            code.putln('%s = %s;' % (self.result(), result))
2387                if debug_disposal_code:
2388                    print("NameNode.generate_assignment_code:")
2389                    print("...generating post-assignment code for %s" % rhs)
2390                rhs.generate_post_assignment_code(code)
2391            elif rhs.result_in_temp():
2392                rhs.generate_post_assignment_code(code)
2393
2394            rhs.free_temps(code)
2395
2396    def generate_acquire_memoryviewslice(self, rhs, code):
2397        """
2398        Slices, coercions from objects, return values etc are new references.
2399        We have a borrowed reference in case of dst = src
2400        """
2401        from . import MemoryView
2402
2403        MemoryView.put_acquire_memoryviewslice(
2404            lhs_cname=self.result(),
2405            lhs_type=self.type,
2406            lhs_pos=self.pos,
2407            rhs=rhs,
2408            code=code,
2409            have_gil=not self.in_nogil_context,
2410            first_assignment=self.cf_is_null)
2411
2412    def generate_acquire_buffer(self, rhs, code):
2413        # rhstmp is only used in case the rhs is a complicated expression leading to
2414        # the object, to avoid repeating the same C expression for every reference
2415        # to the rhs. It does NOT hold a reference.
2416        pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
2417        if pretty_rhs:
2418            rhstmp = rhs.result_as(self.ctype())
2419        else:
2420            rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
2421            code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
2422
2423        from . import Buffer
2424        Buffer.put_assign_to_buffer(self.result(), rhstmp, self.entry,
2425                                    is_initialized=not self.lhs_of_first_assignment,
2426                                    pos=self.pos, code=code)
2427
2428        if not pretty_rhs:
2429            code.putln("%s = 0;" % rhstmp)
2430            code.funcstate.release_temp(rhstmp)
2431
2432    def generate_deletion_code(self, code, ignore_nonexisting=False):
2433        if self.entry is None:
2434            return # There was an error earlier
2435        elif self.entry.is_pyclass_attr:
2436            namespace = self.entry.scope.namespace_cname
2437            interned_cname = code.intern_identifier(self.entry.name)
2438            if ignore_nonexisting:
2439                key_error_code = 'PyErr_Clear(); else'
2440            else:
2441                # minor hack: fake a NameError on KeyError
2442                key_error_code = (
2443                    '{ PyErr_Clear(); PyErr_Format(PyExc_NameError, "name \'%%s\' is not defined", "%s"); }' %
2444                    self.entry.name)
2445            code.putln(
2446                'if (unlikely(PyObject_DelItem(%s, %s) < 0)) {'
2447                ' if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) %s'
2448                ' %s '
2449                '}' % (namespace, interned_cname,
2450                       key_error_code,
2451                       code.error_goto(self.pos)))
2452        elif self.entry.is_pyglobal:
2453            code.globalstate.use_utility_code(
2454                UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
2455            interned_cname = code.intern_identifier(self.entry.name)
2456            del_code = '__Pyx_PyObject_DelAttrStr(%s, %s)' % (
2457                Naming.module_cname, interned_cname)
2458            if ignore_nonexisting:
2459                code.putln(
2460                    'if (unlikely(%s < 0)) {'
2461                    ' if (likely(PyErr_ExceptionMatches(PyExc_AttributeError))) PyErr_Clear(); else %s '
2462                    '}' % (del_code, code.error_goto(self.pos)))
2463            else:
2464                code.put_error_if_neg(self.pos, del_code)
2465        elif self.entry.type.is_pyobject or self.entry.type.is_memoryviewslice:
2466            if not self.cf_is_null:
2467                if self.cf_maybe_null and not ignore_nonexisting:
2468                    code.put_error_if_unbound(self.pos, self.entry)
2469
2470                if self.entry.type.is_pyobject:
2471                    if self.entry.in_closure:
2472                        # generator
2473                        if ignore_nonexisting and self.cf_maybe_null:
2474                            code.put_xgotref(self.result())
2475                        else:
2476                            code.put_gotref(self.result())
2477                    if ignore_nonexisting and self.cf_maybe_null:
2478                        code.put_xdecref(self.result(), self.ctype())
2479                    else:
2480                        code.put_decref(self.result(), self.ctype())
2481                    code.putln('%s = NULL;' % self.result())
2482                else:
2483                    code.put_xdecref_memoryviewslice(self.entry.cname,
2484                                                     have_gil=not self.nogil)
2485        else:
2486            error(self.pos, "Deletion of C names not supported")
2487
2488    def annotate(self, code):
2489        if hasattr(self, 'is_called') and self.is_called:
2490            pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
2491            if self.type.is_pyobject:
2492                style, text = 'py_call', 'python function (%s)'
2493            else:
2494                style, text = 'c_call', 'c function (%s)'
2495            code.annotate(pos, AnnotationItem(style, text % self.type, size=len(self.name)))
2496
2497class BackquoteNode(ExprNode):
2498    #  `expr`
2499    #
2500    #  arg    ExprNode
2501
2502    type = py_object_type
2503
2504    subexprs = ['arg']
2505
2506    def analyse_types(self, env):
2507        self.arg = self.arg.analyse_types(env)
2508        self.arg = self.arg.coerce_to_pyobject(env)
2509        self.is_temp = 1
2510        return self
2511
2512    gil_message = "Backquote expression"
2513
2514    def calculate_constant_result(self):
2515        self.constant_result = repr(self.arg.constant_result)
2516
2517    def generate_result_code(self, code):
2518        code.putln(
2519            "%s = PyObject_Repr(%s); %s" % (
2520                self.result(),
2521                self.arg.py_result(),
2522                code.error_goto_if_null(self.result(), self.pos)))
2523        code.put_gotref(self.py_result())
2524
2525
2526class ImportNode(ExprNode):
2527    #  Used as part of import statement implementation.
2528    #  Implements result =
2529    #    __import__(module_name, globals(), None, name_list, level)
2530    #
2531    #  module_name   StringNode            dotted name of module. Empty module
2532    #                       name means importing the parent package according
2533    #                       to level
2534    #  name_list     ListNode or None      list of names to be imported
2535    #  level         int                   relative import level:
2536    #                       -1: attempt both relative import and absolute import;
2537    #                        0: absolute import;
2538    #                       >0: the number of parent directories to search
2539    #                           relative to the current module.
2540    #                     None: decide the level according to language level and
2541    #                           directives
2542
2543    type = py_object_type
2544
2545    subexprs = ['module_name', 'name_list']
2546
2547    def analyse_types(self, env):
2548        if self.level is None:
2549            if (env.directives['py2_import'] or
2550                Future.absolute_import not in env.global_scope().context.future_directives):
2551                self.level = -1
2552            else:
2553                self.level = 0
2554        module_name = self.module_name.analyse_types(env)
2555        self.module_name = module_name.coerce_to_pyobject(env)
2556        if self.name_list:
2557            name_list = self.name_list.analyse_types(env)
2558            self.name_list = name_list.coerce_to_pyobject(env)
2559        self.is_temp = 1
2560        return self
2561
2562    gil_message = "Python import"
2563
2564    def generate_result_code(self, code):
2565        if self.name_list:
2566            name_list_code = self.name_list.py_result()
2567        else:
2568            name_list_code = "0"
2569
2570        code.globalstate.use_utility_code(UtilityCode.load_cached("Import", "ImportExport.c"))
2571        import_code = "__Pyx_Import(%s, %s, %d)" % (
2572            self.module_name.py_result(),
2573            name_list_code,
2574            self.level)
2575
2576        if (self.level <= 0 and
2577                self.module_name.is_string_literal and
2578                self.module_name.value in utility_code_for_imports):
2579            helper_func, code_name, code_file = utility_code_for_imports[self.module_name.value]
2580            code.globalstate.use_utility_code(UtilityCode.load_cached(code_name, code_file))
2581            import_code = '%s(%s)' % (helper_func, import_code)
2582
2583        code.putln("%s = %s; %s" % (
2584            self.result(),
2585            import_code,
2586            code.error_goto_if_null(self.result(), self.pos)))
2587        code.put_gotref(self.py_result())
2588
2589
2590class IteratorNode(ExprNode):
2591    #  Used as part of for statement implementation.
2592    #
2593    #  Implements result = iter(sequence)
2594    #
2595    #  sequence   ExprNode
2596
2597    type = py_object_type
2598    iter_func_ptr = None
2599    counter_cname = None
2600    cpp_iterator_cname = None
2601    reversed = False      # currently only used for list/tuple types (see Optimize.py)
2602    is_async = False
2603
2604    subexprs = ['sequence']
2605
2606    def analyse_types(self, env):
2607        self.sequence = self.sequence.analyse_types(env)
2608        if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
2609                not self.sequence.type.is_string:
2610            # C array iteration will be transformed later on
2611            self.type = self.sequence.type
2612        elif self.sequence.type.is_cpp_class:
2613            self.analyse_cpp_types(env)
2614        else:
2615            self.sequence = self.sequence.coerce_to_pyobject(env)
2616            if self.sequence.type in (list_type, tuple_type):
2617                self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
2618        self.is_temp = 1
2619        return self
2620
2621    gil_message = "Iterating over Python object"
2622
2623    _func_iternext_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
2624        PyrexTypes.py_object_type, [
2625            PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None),
2626            ]))
2627
2628    def type_dependencies(self, env):
2629        return self.sequence.type_dependencies(env)
2630
2631    def infer_type(self, env):
2632        sequence_type = self.sequence.infer_type(env)
2633        if sequence_type.is_array or sequence_type.is_ptr:
2634            return sequence_type
2635        elif sequence_type.is_cpp_class:
2636            begin = sequence_type.scope.lookup("begin")
2637            if begin is not None:
2638                return begin.type.return_type
2639        elif sequence_type.is_pyobject:
2640            return sequence_type
2641        return py_object_type
2642
2643    def analyse_cpp_types(self, env):
2644        sequence_type = self.sequence.type
2645        if sequence_type.is_ptr:
2646            sequence_type = sequence_type.base_type
2647        begin = sequence_type.scope.lookup("begin")
2648        end = sequence_type.scope.lookup("end")
2649        if (begin is None
2650            or not begin.type.is_cfunction
2651            or begin.type.args):
2652            error(self.pos, "missing begin() on %s" % self.sequence.type)
2653            self.type = error_type
2654            return
2655        if (end is None
2656            or not end.type.is_cfunction
2657            or end.type.args):
2658            error(self.pos, "missing end() on %s" % self.sequence.type)
2659            self.type = error_type
2660            return
2661        iter_type = begin.type.return_type
2662        if iter_type.is_cpp_class:
2663            if env.lookup_operator_for_types(
2664                    self.pos,
2665                    "!=",
2666                    [iter_type, end.type.return_type]) is None:
2667                error(self.pos, "missing operator!= on result of begin() on %s" % self.sequence.type)
2668                self.type = error_type
2669                return
2670            if env.lookup_operator_for_types(self.pos, '++', [iter_type]) is None:
2671                error(self.pos, "missing operator++ on result of begin() on %s" % self.sequence.type)
2672                self.type = error_type
2673                return
2674            if env.lookup_operator_for_types(self.pos, '*', [iter_type]) is None:
2675                error(self.pos, "missing operator* on result of begin() on %s" % self.sequence.type)
2676                self.type = error_type
2677                return
2678            self.type = iter_type
2679        elif iter_type.is_ptr:
2680            if not (iter_type == end.type.return_type):
2681                error(self.pos, "incompatible types for begin() and end()")
2682            self.type = iter_type
2683        else:
2684            error(self.pos, "result type of begin() on %s must be a C++ class or pointer" % self.sequence.type)
2685            self.type = error_type
2686            return
2687
2688    def generate_result_code(self, code):
2689        sequence_type = self.sequence.type
2690        if sequence_type.is_cpp_class:
2691            if self.sequence.is_name:
2692                # safe: C++ won't allow you to reassign to class references
2693                begin_func = "%s.begin" % self.sequence.result()
2694            else:
2695                sequence_type = PyrexTypes.c_ptr_type(sequence_type)
2696                self.cpp_iterator_cname = code.funcstate.allocate_temp(sequence_type, manage_ref=False)
2697                code.putln("%s = &%s;" % (self.cpp_iterator_cname, self.sequence.result()))
2698                begin_func = "%s->begin" % self.cpp_iterator_cname
2699            # TODO: Limit scope.
2700            code.putln("%s = %s();" % (self.result(), begin_func))
2701            return
2702        if sequence_type.is_array or sequence_type.is_ptr:
2703            raise InternalError("for in carray slice not transformed")
2704
2705        is_builtin_sequence = sequence_type in (list_type, tuple_type)
2706        if not is_builtin_sequence:
2707            # reversed() not currently optimised (see Optimize.py)
2708            assert not self.reversed, "internal error: reversed() only implemented for list/tuple objects"
2709        self.may_be_a_sequence = not sequence_type.is_builtin_type
2710        if self.may_be_a_sequence:
2711            code.putln(
2712                "if (likely(PyList_CheckExact(%s)) || PyTuple_CheckExact(%s)) {" % (
2713                    self.sequence.py_result(),
2714                    self.sequence.py_result()))
2715
2716        if is_builtin_sequence or self.may_be_a_sequence:
2717            self.counter_cname = code.funcstate.allocate_temp(
2718                PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2719            if self.reversed:
2720                if sequence_type is list_type:
2721                    init_value = 'PyList_GET_SIZE(%s) - 1' % self.result()
2722                else:
2723                    init_value = 'PyTuple_GET_SIZE(%s) - 1' % self.result()
2724            else:
2725                init_value = '0'
2726            code.putln("%s = %s; __Pyx_INCREF(%s); %s = %s;" % (
2727                self.result(),
2728                self.sequence.py_result(),
2729                self.result(),
2730                self.counter_cname,
2731                init_value))
2732        if not is_builtin_sequence:
2733            self.iter_func_ptr = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
2734            if self.may_be_a_sequence:
2735                code.putln("%s = NULL;" % self.iter_func_ptr)
2736                code.putln("} else {")
2737                code.put("%s = -1; " % self.counter_cname)
2738
2739            code.putln("%s = PyObject_GetIter(%s); %s" % (
2740                self.result(),
2741                self.sequence.py_result(),
2742                code.error_goto_if_null(self.result(), self.pos)))
2743            code.put_gotref(self.py_result())
2744
2745            # PyObject_GetIter() fails if "tp_iternext" is not set, but the check below
2746            # makes it visible to the C compiler that the pointer really isn't NULL, so that
2747            # it can distinguish between the special cases and the generic case
2748            code.putln("%s = Py_TYPE(%s)->tp_iternext; %s" % (
2749                self.iter_func_ptr, self.py_result(),
2750                code.error_goto_if_null(self.iter_func_ptr, self.pos)))
2751        if self.may_be_a_sequence:
2752            code.putln("}")
2753
2754    def generate_next_sequence_item(self, test_name, result_name, code):
2755        assert self.counter_cname, "internal error: counter_cname temp not prepared"
2756        final_size = 'Py%s_GET_SIZE(%s)' % (test_name, self.py_result())
2757        if self.sequence.is_sequence_constructor:
2758            item_count = len(self.sequence.args)
2759            if self.sequence.mult_factor is None:
2760                final_size = item_count
2761            elif isinstance(self.sequence.mult_factor.constant_result, _py_int_types):
2762                final_size = item_count * self.sequence.mult_factor.constant_result
2763        code.putln("if (%s >= %s) break;" % (self.counter_cname, final_size))
2764        if self.reversed:
2765            inc_dec = '--'
2766        else:
2767            inc_dec = '++'
2768        code.putln("#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS")
2769        code.putln(
2770            "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s%s; %s" % (
2771                result_name,
2772                test_name,
2773                self.py_result(),
2774                self.counter_cname,
2775                result_name,
2776                self.counter_cname,
2777                inc_dec,
2778                # use the error label to avoid C compiler warnings if we only use it below
2779                code.error_goto_if_neg('0', self.pos)
2780                ))
2781        code.putln("#else")
2782        code.putln(
2783            "%s = PySequence_ITEM(%s, %s); %s%s; %s" % (
2784                result_name,
2785                self.py_result(),
2786                self.counter_cname,
2787                self.counter_cname,
2788                inc_dec,
2789                code.error_goto_if_null(result_name, self.pos)))
2790        code.put_gotref(result_name)
2791        code.putln("#endif")
2792
2793    def generate_iter_next_result_code(self, result_name, code):
2794        sequence_type = self.sequence.type
2795        if self.reversed:
2796            code.putln("if (%s < 0) break;" % self.counter_cname)
2797        if sequence_type.is_cpp_class:
2798            if self.cpp_iterator_cname:
2799                end_func = "%s->end" % self.cpp_iterator_cname
2800            else:
2801                end_func = "%s.end" % self.sequence.result()
2802            # TODO: Cache end() call?
2803            code.putln("if (!(%s != %s())) break;" % (
2804                            self.result(),
2805                            end_func))
2806            code.putln("%s = *%s;" % (
2807                            result_name,
2808                            self.result()))
2809            code.putln("++%s;" % self.result())
2810            return
2811        elif sequence_type is list_type:
2812            self.generate_next_sequence_item('List', result_name, code)
2813            return
2814        elif sequence_type is tuple_type:
2815            self.generate_next_sequence_item('Tuple', result_name, code)
2816            return
2817
2818        if self.may_be_a_sequence:
2819            code.putln("if (likely(!%s)) {" % self.iter_func_ptr)
2820            code.putln("if (likely(PyList_CheckExact(%s))) {" % self.py_result())
2821            self.generate_next_sequence_item('List', result_name, code)
2822            code.putln("} else {")
2823            self.generate_next_sequence_item('Tuple', result_name, code)
2824            code.putln("}")
2825            code.put("} else ")
2826
2827        code.putln("{")
2828        code.putln(
2829            "%s = %s(%s);" % (
2830                result_name,
2831                self.iter_func_ptr,
2832                self.py_result()))
2833        code.putln("if (unlikely(!%s)) {" % result_name)
2834        code.putln("PyObject* exc_type = PyErr_Occurred();")
2835        code.putln("if (exc_type) {")
2836        code.putln("if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();")
2837        code.putln("else %s" % code.error_goto(self.pos))
2838        code.putln("}")
2839        code.putln("break;")
2840        code.putln("}")
2841        code.put_gotref(result_name)
2842        code.putln("}")
2843
2844    def free_temps(self, code):
2845        if self.counter_cname:
2846            code.funcstate.release_temp(self.counter_cname)
2847        if self.iter_func_ptr:
2848            code.funcstate.release_temp(self.iter_func_ptr)
2849            self.iter_func_ptr = None
2850        if self.cpp_iterator_cname:
2851            code.funcstate.release_temp(self.cpp_iterator_cname)
2852        ExprNode.free_temps(self, code)
2853
2854
2855class NextNode(AtomicExprNode):
2856    #  Used as part of for statement implementation.
2857    #  Implements result = next(iterator)
2858    #  Created during analyse_types phase.
2859    #  The iterator is not owned by this node.
2860    #
2861    #  iterator   IteratorNode
2862
2863    def __init__(self, iterator):
2864        AtomicExprNode.__init__(self, iterator.pos)
2865        self.iterator = iterator
2866
2867    def nogil_check(self, env):
2868        # ignore - errors (if any) are already handled by IteratorNode
2869        pass
2870
2871    def type_dependencies(self, env):
2872        return self.iterator.type_dependencies(env)
2873
2874    def infer_type(self, env, iterator_type=None):
2875        if iterator_type is None:
2876            iterator_type = self.iterator.infer_type(env)
2877        if iterator_type.is_ptr or iterator_type.is_array:
2878            return iterator_type.base_type
2879        elif iterator_type.is_cpp_class:
2880            item_type = env.lookup_operator_for_types(self.pos, "*", [iterator_type]).type.return_type
2881            if item_type.is_reference:
2882                item_type = item_type.ref_base_type
2883            if item_type.is_const:
2884                item_type = item_type.const_base_type
2885            return item_type
2886        else:
2887            # Avoid duplication of complicated logic.
2888            fake_index_node = IndexNode(
2889                self.pos,
2890                base=self.iterator.sequence,
2891                index=IntNode(self.pos, value='PY_SSIZE_T_MAX',
2892                              type=PyrexTypes.c_py_ssize_t_type))
2893            return fake_index_node.infer_type(env)
2894
2895    def analyse_types(self, env):
2896        self.type = self.infer_type(env, self.iterator.type)
2897        self.is_temp = 1
2898        return self
2899
2900    def generate_result_code(self, code):
2901        self.iterator.generate_iter_next_result_code(self.result(), code)
2902
2903
2904class AsyncIteratorNode(ExprNode):
2905    #  Used as part of 'async for' statement implementation.
2906    #
2907    #  Implements result = sequence.__aiter__()
2908    #
2909    #  sequence   ExprNode
2910
2911    subexprs = ['sequence']
2912
2913    is_async = True
2914    type = py_object_type
2915    is_temp = 1
2916
2917    def infer_type(self, env):
2918        return py_object_type
2919
2920    def analyse_types(self, env):
2921        self.sequence = self.sequence.analyse_types(env)
2922        if not self.sequence.type.is_pyobject:
2923            error(self.pos, "async for loops not allowed on C/C++ types")
2924            self.sequence = self.sequence.coerce_to_pyobject(env)
2925        return self
2926
2927    def generate_result_code(self, code):
2928        code.globalstate.use_utility_code(UtilityCode.load_cached("AsyncIter", "Coroutine.c"))
2929        code.putln("%s = __Pyx_Coroutine_GetAsyncIter(%s); %s" % (
2930            self.result(),
2931            self.sequence.py_result(),
2932            code.error_goto_if_null(self.result(), self.pos)))
2933        code.put_gotref(self.result())
2934
2935
2936class AsyncNextNode(AtomicExprNode):
2937    #  Used as part of 'async for' statement implementation.
2938    #  Implements result = iterator.__anext__()
2939    #  Created during analyse_types phase.
2940    #  The iterator is not owned by this node.
2941    #
2942    #  iterator   IteratorNode
2943
2944    type = py_object_type
2945    is_temp = 1
2946
2947    def __init__(self, iterator):
2948        AtomicExprNode.__init__(self, iterator.pos)
2949        self.iterator = iterator
2950
2951    def infer_type(self, env):
2952        return py_object_type
2953
2954    def analyse_types(self, env):
2955        return self
2956
2957    def generate_result_code(self, code):
2958        code.globalstate.use_utility_code(UtilityCode.load_cached("AsyncIter", "Coroutine.c"))
2959        code.putln("%s = __Pyx_Coroutine_AsyncIterNext(%s); %s" % (
2960            self.result(),
2961            self.iterator.py_result(),
2962            code.error_goto_if_null(self.result(), self.pos)))
2963        code.put_gotref(self.result())
2964
2965
2966class WithExitCallNode(ExprNode):
2967    # The __exit__() call of a 'with' statement.  Used in both the
2968    # except and finally clauses.
2969
2970    # with_stat   WithStatNode                the surrounding 'with' statement
2971    # args        TupleNode or ResultStatNode the exception info tuple
2972    # await_expr  AwaitExprNode               the await expression of an 'async with' statement
2973
2974    subexprs = ['args', 'await_expr']
2975    test_if_run = True
2976    await_expr = None
2977
2978    def analyse_types(self, env):
2979        self.args = self.args.analyse_types(env)
2980        if self.await_expr:
2981            self.await_expr = self.await_expr.analyse_types(env)
2982        self.type = PyrexTypes.c_bint_type
2983        self.is_temp = True
2984        return self
2985
2986    def generate_evaluation_code(self, code):
2987        if self.test_if_run:
2988            # call only if it was not already called (and decref-cleared)
2989            code.putln("if (%s) {" % self.with_stat.exit_var)
2990
2991        self.args.generate_evaluation_code(code)
2992        result_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
2993
2994        code.mark_pos(self.pos)
2995        code.globalstate.use_utility_code(UtilityCode.load_cached(
2996            "PyObjectCall", "ObjectHandling.c"))
2997        code.putln("%s = __Pyx_PyObject_Call(%s, %s, NULL);" % (
2998            result_var,
2999            self.with_stat.exit_var,
3000            self.args.result()))
3001        code.put_decref_clear(self.with_stat.exit_var, type=py_object_type)
3002        self.args.generate_disposal_code(code)
3003        self.args.free_temps(code)
3004
3005        code.putln(code.error_goto_if_null(result_var, self.pos))
3006        code.put_gotref(result_var)
3007
3008        if self.await_expr:
3009            # FIXME: result_var temp currently leaks into the closure
3010            self.await_expr.generate_evaluation_code(code, source_cname=result_var, decref_source=True)
3011            code.putln("%s = %s;" % (result_var, self.await_expr.py_result()))
3012            self.await_expr.generate_post_assignment_code(code)
3013            self.await_expr.free_temps(code)
3014
3015        if self.result_is_used:
3016            self.allocate_temp_result(code)
3017            code.putln("%s = __Pyx_PyObject_IsTrue(%s);" % (self.result(), result_var))
3018        code.put_decref_clear(result_var, type=py_object_type)
3019        if self.result_is_used:
3020            code.put_error_if_neg(self.pos, self.result())
3021        code.funcstate.release_temp(result_var)
3022        if self.test_if_run:
3023            code.putln("}")
3024
3025
3026class ExcValueNode(AtomicExprNode):
3027    #  Node created during analyse_types phase
3028    #  of an ExceptClauseNode to fetch the current
3029    #  exception value.
3030
3031    type = py_object_type
3032
3033    def __init__(self, pos):
3034        ExprNode.__init__(self, pos)
3035
3036    def set_var(self, var):
3037        self.var = var
3038
3039    def calculate_result_code(self):
3040        return self.var
3041
3042    def generate_result_code(self, code):
3043        pass
3044
3045    def analyse_types(self, env):
3046        return self
3047
3048
3049class TempNode(ExprNode):
3050    # Node created during analyse_types phase
3051    # of some nodes to hold a temporary value.
3052    #
3053    # Note: One must call "allocate" and "release" on
3054    # the node during code generation to get/release the temp.
3055    # This is because the temp result is often used outside of
3056    # the regular cycle.
3057
3058    subexprs = []
3059
3060    def __init__(self, pos, type, env=None):
3061        ExprNode.__init__(self, pos)
3062        self.type = type
3063        if type.is_pyobject:
3064            self.result_ctype = py_object_type
3065        self.is_temp = 1
3066
3067    def analyse_types(self, env):
3068        return self
3069
3070    def analyse_target_declaration(self, env):
3071        pass
3072
3073    def generate_result_code(self, code):
3074        pass
3075
3076    def allocate(self, code):
3077        self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
3078
3079    def release(self, code):
3080        code.funcstate.release_temp(self.temp_cname)
3081        self.temp_cname = None
3082
3083    def result(self):
3084        try:
3085            return self.temp_cname
3086        except:
3087            assert False, "Remember to call allocate/release on TempNode"
3088            raise
3089
3090    # Do not participate in normal temp alloc/dealloc:
3091    def allocate_temp_result(self, code):
3092        pass
3093
3094    def release_temp_result(self, code):
3095        pass
3096
3097class PyTempNode(TempNode):
3098    #  TempNode holding a Python value.
3099
3100    def __init__(self, pos, env):
3101        TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
3102
3103class RawCNameExprNode(ExprNode):
3104    subexprs = []
3105
3106    def __init__(self, pos, type=None, cname=None):
3107        ExprNode.__init__(self, pos, type=type)
3108        if cname is not None:
3109            self.cname = cname
3110
3111    def analyse_types(self, env):
3112        return self
3113
3114    def set_cname(self, cname):
3115        self.cname = cname
3116
3117    def result(self):
3118        return self.cname
3119
3120    def generate_result_code(self, code):
3121        pass
3122
3123
3124#-------------------------------------------------------------------
3125#
3126#  F-strings
3127#
3128#-------------------------------------------------------------------
3129
3130
3131class JoinedStrNode(ExprNode):
3132    # F-strings
3133    #
3134    # values   [UnicodeNode|FormattedValueNode]   Substrings of the f-string
3135    #
3136    type = unicode_type
3137    is_temp = True
3138
3139    subexprs = ['values']
3140
3141    def analyse_types(self, env):
3142        self.values = [v.analyse_types(env).coerce_to_pyobject(env) for v in self.values]
3143        return self
3144
3145    def may_be_none(self):
3146        # PyUnicode_Join() always returns a Unicode string or raises an exception
3147        return False
3148
3149    def generate_evaluation_code(self, code):
3150        code.mark_pos(self.pos)
3151        num_items = len(self.values)
3152        list_var = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3153        ulength_var = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
3154        max_char_var = code.funcstate.allocate_temp(PyrexTypes.c_py_ucs4_type, manage_ref=False)
3155
3156        code.putln('%s = PyTuple_New(%s); %s' % (
3157            list_var,
3158            num_items,
3159            code.error_goto_if_null(list_var, self.pos)))
3160        code.put_gotref(list_var)
3161        code.putln("%s = 0;" % ulength_var)
3162        code.putln("%s = 127;" % max_char_var)  # at least ASCII character range
3163
3164        for i, node in enumerate(self.values):
3165            node.generate_evaluation_code(code)
3166            node.make_owned_reference(code)
3167
3168            ulength = "__Pyx_PyUnicode_GET_LENGTH(%s)" % node.py_result()
3169            max_char_value = "__Pyx_PyUnicode_MAX_CHAR_VALUE(%s)" % node.py_result()
3170            is_ascii = False
3171            if isinstance(node, UnicodeNode):
3172                try:
3173                    # most strings will be ASCII or at least Latin-1
3174                    node.value.encode('iso8859-1')
3175                    max_char_value = '255'
3176                    node.value.encode('us-ascii')
3177                    is_ascii = True
3178                except UnicodeEncodeError:
3179                    if max_char_value != '255':
3180                        # not ISO8859-1 => check BMP limit
3181                        max_char = max(map(ord, node.value))
3182                        if max_char < 0xD800:
3183                            # BMP-only, no surrogate pairs used
3184                            max_char_value = '65535'
3185                            ulength = str(len(node.value))
3186                        elif max_char >= 65536:
3187                            # cleary outside of BMP, and not on a 16-bit Unicode system
3188                            max_char_value = '1114111'
3189                            ulength = str(len(node.value))
3190                        else:
3191                            # not really worth implementing a check for surrogate pairs here
3192                            # drawback: C code can differ when generating on Py2 with 2-byte Unicode
3193                            pass
3194                else:
3195                    ulength = str(len(node.value))
3196            elif isinstance(node, FormattedValueNode) and node.value.type.is_numeric:
3197                is_ascii = True  # formatted C numbers are always ASCII
3198
3199            if not is_ascii:
3200                code.putln("%s = (%s > %s) ? %s : %s;" % (
3201                    max_char_var, max_char_value, max_char_var, max_char_value, max_char_var))
3202            code.putln("%s += %s;" % (ulength_var, ulength))
3203
3204            code.put_giveref(node.py_result())
3205            code.putln('PyTuple_SET_ITEM(%s, %s, %s);' % (list_var, i, node.py_result()))
3206            node.generate_post_assignment_code(code)
3207            node.free_temps(code)
3208
3209        code.mark_pos(self.pos)
3210        self.allocate_temp_result(code)
3211        code.globalstate.use_utility_code(UtilityCode.load_cached("JoinPyUnicode", "StringTools.c"))
3212        code.putln('%s = __Pyx_PyUnicode_Join(%s, %d, %s, %s); %s' % (
3213            self.result(),
3214            list_var,
3215            num_items,
3216            ulength_var,
3217            max_char_var,
3218            code.error_goto_if_null(self.py_result(), self.pos)))
3219        code.put_gotref(self.py_result())
3220
3221        code.put_decref_clear(list_var, py_object_type)
3222        code.funcstate.release_temp(list_var)
3223        code.funcstate.release_temp(ulength_var)
3224        code.funcstate.release_temp(max_char_var)
3225
3226
3227class FormattedValueNode(ExprNode):
3228    # {}-delimited portions of an f-string
3229    #
3230    # value           ExprNode                The expression itself
3231    # conversion_char str or None             Type conversion (!s, !r, !a, or none, or 'd' for integer conversion)
3232    # format_spec     JoinedStrNode or None   Format string passed to __format__
3233    # c_format_spec   str or None             If not None, formatting can be done at the C level
3234
3235    subexprs = ['value', 'format_spec']
3236
3237    type = unicode_type
3238    is_temp = True
3239    c_format_spec = None
3240
3241    find_conversion_func = {
3242        's': 'PyObject_Unicode',
3243        'r': 'PyObject_Repr',
3244        'a': 'PyObject_ASCII',  # NOTE: mapped to PyObject_Repr() in Py2
3245        'd': '__Pyx_PyNumber_IntOrLong',  # NOTE: internal mapping for '%d' formatting
3246    }.get
3247
3248    def may_be_none(self):
3249        # PyObject_Format() always returns a Unicode string or raises an exception
3250        return False
3251
3252    def analyse_types(self, env):
3253        self.value = self.value.analyse_types(env)
3254        if not self.format_spec or self.format_spec.is_string_literal:
3255            c_format_spec = self.format_spec.value if self.format_spec else self.value.type.default_format_spec
3256            if self.value.type.can_coerce_to_pystring(env, format_spec=c_format_spec):
3257                self.c_format_spec = c_format_spec
3258
3259        if self.format_spec:
3260            self.format_spec = self.format_spec.analyse_types(env).coerce_to_pyobject(env)
3261        if self.c_format_spec is None:
3262            self.value = self.value.coerce_to_pyobject(env)
3263            if not self.format_spec and (not self.conversion_char or self.conversion_char == 's'):
3264                if self.value.type is unicode_type and not self.value.may_be_none():
3265                    # value is definitely a unicode string and we don't format it any special
3266                    return self.value
3267        return self
3268
3269    def generate_result_code(self, code):
3270        if self.c_format_spec is not None and not self.value.type.is_pyobject:
3271            convert_func_call = self.value.type.convert_to_pystring(
3272                self.value.result(), code, self.c_format_spec)
3273            code.putln("%s = %s; %s" % (
3274                self.result(),
3275                convert_func_call,
3276                code.error_goto_if_null(self.result(), self.pos)))
3277            code.put_gotref(self.py_result())
3278            return
3279
3280        value_result = self.value.py_result()
3281        value_is_unicode = self.value.type is unicode_type and not self.value.may_be_none()
3282        if self.format_spec:
3283            format_func = '__Pyx_PyObject_Format'
3284            format_spec = self.format_spec.py_result()
3285        else:
3286            # common case: expect simple Unicode pass-through if no format spec
3287            format_func = '__Pyx_PyObject_FormatSimple'
3288            # passing a Unicode format string in Py2 forces PyObject_Format() to also return a Unicode string
3289            format_spec = Naming.empty_unicode
3290
3291        conversion_char = self.conversion_char
3292        if conversion_char == 's' and value_is_unicode:
3293            # no need to pipe unicode strings through str()
3294            conversion_char = None
3295
3296        if conversion_char:
3297            fn = self.find_conversion_func(conversion_char)
3298            assert fn is not None, "invalid conversion character found: '%s'" % conversion_char
3299            value_result = '%s(%s)' % (fn, value_result)
3300            code.globalstate.use_utility_code(
3301                UtilityCode.load_cached("PyObjectFormatAndDecref", "StringTools.c"))
3302            format_func += 'AndDecref'
3303        elif self.format_spec:
3304            code.globalstate.use_utility_code(
3305                UtilityCode.load_cached("PyObjectFormat", "StringTools.c"))
3306        else:
3307            code.globalstate.use_utility_code(
3308                UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c"))
3309
3310        code.putln("%s = %s(%s, %s); %s" % (
3311            self.result(),
3312            format_func,
3313            value_result,
3314            format_spec,
3315            code.error_goto_if_null(self.result(), self.pos)))
3316        code.put_gotref(self.py_result())
3317
3318
3319#-------------------------------------------------------------------
3320#
3321#  Parallel nodes (cython.parallel.thread(savailable|id))
3322#
3323#-------------------------------------------------------------------
3324
3325class ParallelThreadsAvailableNode(AtomicExprNode):
3326    """
3327    Note: this is disabled and not a valid directive at this moment
3328
3329    Implements cython.parallel.threadsavailable(). If we are called from the
3330    sequential part of the application, we need to call omp_get_max_threads(),
3331    and in the parallel part we can just call omp_get_num_threads()
3332    """
3333
3334    type = PyrexTypes.c_int_type
3335
3336    def analyse_types(self, env):
3337        self.is_temp = True
3338        # env.add_include_file("omp.h")
3339        return self
3340
3341    def generate_result_code(self, code):
3342        code.putln("#ifdef _OPENMP")
3343        code.putln("if (omp_in_parallel()) %s = omp_get_max_threads();" %
3344                                                            self.temp_code)
3345        code.putln("else %s = omp_get_num_threads();" % self.temp_code)
3346        code.putln("#else")
3347        code.putln("%s = 1;" % self.temp_code)
3348        code.putln("#endif")
3349
3350    def result(self):
3351        return self.temp_code
3352
3353
3354class ParallelThreadIdNode(AtomicExprNode): #, Nodes.ParallelNode):
3355    """
3356    Implements cython.parallel.threadid()
3357    """
3358
3359    type = PyrexTypes.c_int_type
3360
3361    def analyse_types(self, env):
3362        self.is_temp = True
3363        # env.add_include_file("omp.h")
3364        return self
3365
3366    def generate_result_code(self, code):
3367        code.putln("#ifdef _OPENMP")
3368        code.putln("%s = omp_get_thread_num();" % self.temp_code)
3369        code.putln("#else")
3370        code.putln("%s = 0;" % self.temp_code)
3371        code.putln("#endif")
3372
3373    def result(self):
3374        return self.temp_code
3375
3376
3377#-------------------------------------------------------------------
3378#
3379#  Trailer nodes
3380#
3381#-------------------------------------------------------------------
3382
3383
3384class _IndexingBaseNode(ExprNode):
3385    # Base class for indexing nodes.
3386    #
3387    # base   ExprNode   the value being indexed
3388
3389    def is_ephemeral(self):
3390        # in most cases, indexing will return a safe reference to an object in a container,
3391        # so we consider the result safe if the base object is
3392        return self.base.is_ephemeral() or self.base.type in (
3393            basestring_type, str_type, bytes_type, bytearray_type, unicode_type)
3394
3395    def check_const_addr(self):
3396        return self.base.check_const_addr() and self.index.check_const()
3397
3398    def is_lvalue(self):
3399        # NOTE: references currently have both is_reference and is_ptr
3400        # set.  Since pointers and references have different lvalue
3401        # rules, we must be careful to separate the two.
3402        if self.type.is_reference:
3403            if self.type.ref_base_type.is_array:
3404                # fixed-sized arrays aren't l-values
3405                return False
3406        elif self.type.is_ptr:
3407            # non-const pointers can always be reassigned
3408            return True
3409        # Just about everything else returned by the index operator
3410        # can be an lvalue.
3411        return True
3412
3413
3414class IndexNode(_IndexingBaseNode):
3415    #  Sequence indexing.
3416    #
3417    #  base     ExprNode
3418    #  index    ExprNode
3419    #  type_indices  [PyrexType]
3420    #
3421    #  is_fused_index boolean   Whether the index is used to specialize a
3422    #                           c(p)def function
3423
3424    subexprs = ['base', 'index']
3425    type_indices = None
3426
3427    is_subscript = True
3428    is_fused_index = False
3429
3430    def calculate_constant_result(self):
3431        self.constant_result = self.base.constant_result[self.index.constant_result]
3432
3433    def compile_time_value(self, denv):
3434        base = self.base.compile_time_value(denv)
3435        index = self.index.compile_time_value(denv)
3436        try:
3437            return base[index]
3438        except Exception as e:
3439            self.compile_time_value_error(e)
3440
3441    def is_simple(self):
3442        base = self.base
3443        return (base.is_simple() and self.index.is_simple()
3444                and base.type and (base.type.is_ptr or base.type.is_array))
3445
3446    def may_be_none(self):
3447        base_type = self.base.type
3448        if base_type:
3449            if base_type.is_string:
3450                return False
3451            if isinstance(self.index, SliceNode):
3452                # slicing!
3453                if base_type in (bytes_type, bytearray_type, str_type, unicode_type,
3454                                 basestring_type, list_type, tuple_type):
3455                    return False
3456        return ExprNode.may_be_none(self)
3457
3458    def analyse_target_declaration(self, env):
3459        pass
3460
3461    def analyse_as_type(self, env):
3462        base_type = self.base.analyse_as_type(env)
3463        if base_type and not base_type.is_pyobject:
3464            if base_type.is_cpp_class:
3465                if isinstance(self.index, TupleNode):
3466                    template_values = self.index.args
3467                else:
3468                    template_values = [self.index]
3469                type_node = Nodes.TemplatedTypeNode(
3470                    pos=self.pos,
3471                    positional_args=template_values,
3472                    keyword_args=None)
3473                return type_node.analyse(env, base_type=base_type)
3474            elif self.index.is_slice or self.index.is_sequence_constructor:
3475                # memory view
3476                from . import MemoryView
3477                env.use_utility_code(MemoryView.view_utility_code)
3478                axes = [self.index] if self.index.is_slice else list(self.index.args)
3479                return PyrexTypes.MemoryViewSliceType(base_type, MemoryView.get_axes_specs(env, axes))
3480            else:
3481                # C array
3482                index = self.index.compile_time_value(env)
3483                if index is not None:
3484                    try:
3485                        index = int(index)
3486                    except (ValueError, TypeError):
3487                        pass
3488                    else:
3489                        return PyrexTypes.CArrayType(base_type, index)
3490                error(self.pos, "Array size must be a compile time constant")
3491        return None
3492
3493    def type_dependencies(self, env):
3494        return self.base.type_dependencies(env) + self.index.type_dependencies(env)
3495
3496    def infer_type(self, env):
3497        base_type = self.base.infer_type(env)
3498        if self.index.is_slice:
3499            # slicing!
3500            if base_type.is_string:
3501                # sliced C strings must coerce to Python
3502                return bytes_type
3503            elif base_type.is_pyunicode_ptr:
3504                # sliced Py_UNICODE* strings must coerce to Python
3505                return unicode_type
3506            elif base_type in (unicode_type, bytes_type, str_type,
3507                               bytearray_type, list_type, tuple_type):
3508                # slicing these returns the same type
3509                return base_type
3510            else:
3511                # TODO: Handle buffers (hopefully without too much redundancy).
3512                return py_object_type
3513
3514        index_type = self.index.infer_type(env)
3515        if index_type and index_type.is_int or isinstance(self.index, IntNode):
3516            # indexing!
3517            if base_type is unicode_type:
3518                # Py_UCS4 will automatically coerce to a unicode string
3519                # if required, so this is safe.  We only infer Py_UCS4
3520                # when the index is a C integer type.  Otherwise, we may
3521                # need to use normal Python item access, in which case
3522                # it's faster to return the one-char unicode string than
3523                # to receive it, throw it away, and potentially rebuild it
3524                # on a subsequent PyObject coercion.
3525                return PyrexTypes.c_py_ucs4_type
3526            elif base_type is str_type:
3527                # always returns str - Py2: bytes, Py3: unicode
3528                return base_type
3529            elif base_type is bytearray_type:
3530                return PyrexTypes.c_uchar_type
3531            elif isinstance(self.base, BytesNode):
3532                #if env.global_scope().context.language_level >= 3:
3533                #    # inferring 'char' can be made to work in Python 3 mode
3534                #    return PyrexTypes.c_char_type
3535                # Py2/3 return different types on indexing bytes objects
3536                return py_object_type
3537            elif base_type in (tuple_type, list_type):
3538                # if base is a literal, take a look at its values
3539                item_type = infer_sequence_item_type(
3540                    env, self.base, self.index, seq_type=base_type)
3541                if item_type is not None:
3542                    return item_type
3543            elif base_type.is_ptr or base_type.is_array:
3544                return base_type.base_type
3545            elif base_type.is_ctuple and isinstance(self.index, IntNode):
3546                if self.index.has_constant_result():
3547                    index = self.index.constant_result
3548                    if index < 0:
3549                        index += base_type.size
3550                    if 0 <= index < base_type.size:
3551                        return base_type.components[index]
3552
3553        if base_type.is_cpp_class:
3554            class FakeOperand:
3555                def __init__(self, **kwds):
3556                    self.__dict__.update(kwds)
3557            operands = [
3558                FakeOperand(pos=self.pos, type=base_type),
3559                FakeOperand(pos=self.pos, type=index_type),
3560            ]
3561            index_func = env.lookup_operator('[]', operands)
3562            if index_func is not None:
3563                return index_func.type.return_type
3564
3565        if is_pythran_expr(base_type) and is_pythran_expr(index_type):
3566            index_with_type = (self.index, index_type)
3567            return PythranExpr(pythran_indexing_type(base_type, [index_with_type]))
3568
3569        # may be slicing or indexing, we don't know
3570        if base_type in (unicode_type, str_type):
3571            # these types always returns their own type on Python indexing/slicing
3572            return base_type
3573        else:
3574            # TODO: Handle buffers (hopefully without too much redundancy).
3575            return py_object_type
3576
3577    def analyse_types(self, env):
3578        return self.analyse_base_and_index_types(env, getting=True)
3579
3580    def analyse_target_types(self, env):
3581        node = self.analyse_base_and_index_types(env, setting=True)
3582        if node.type.is_const:
3583            error(self.pos, "Assignment to const dereference")
3584        if node is self and not node.is_lvalue():
3585            error(self.pos, "Assignment to non-lvalue of type '%s'" % node.type)
3586        return node
3587
3588    def analyse_base_and_index_types(self, env, getting=False, setting=False,
3589                                     analyse_base=True):
3590        # Note: This might be cleaned up by having IndexNode
3591        # parsed in a saner way and only construct the tuple if
3592        # needed.
3593        if analyse_base:
3594            self.base = self.base.analyse_types(env)
3595
3596        if self.base.type.is_error:
3597            # Do not visit child tree if base is undeclared to avoid confusing
3598            # error messages
3599            self.type = PyrexTypes.error_type
3600            return self
3601
3602        is_slice = self.index.is_slice
3603        if not env.directives['wraparound']:
3604            if is_slice:
3605                check_negative_indices(self.index.start, self.index.stop)
3606            else:
3607                check_negative_indices(self.index)
3608
3609        # Potentially overflowing index value.
3610        if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
3611            self.index = self.index.coerce_to_pyobject(env)
3612
3613        is_memslice = self.base.type.is_memoryviewslice
3614        # Handle the case where base is a literal char* (and we expect a string, not an int)
3615        if not is_memslice and (isinstance(self.base, BytesNode) or is_slice):
3616            if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
3617                self.base = self.base.coerce_to_pyobject(env)
3618
3619        replacement_node = self.analyse_as_buffer_operation(env, getting)
3620        if replacement_node is not None:
3621            return replacement_node
3622
3623        self.nogil = env.nogil
3624        base_type = self.base.type
3625
3626        if not base_type.is_cfunction:
3627            self.index = self.index.analyse_types(env)
3628            self.original_index_type = self.index.type
3629
3630            if base_type.is_unicode_char:
3631                # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
3632                # cases, but indexing must still work for them
3633                if setting:
3634                    warning(self.pos, "cannot assign to Unicode string index", level=1)
3635                elif self.index.constant_result in (0, -1):
3636                    # uchar[0] => uchar
3637                    return self.base
3638                self.base = self.base.coerce_to_pyobject(env)
3639                base_type = self.base.type
3640
3641        if base_type.is_pyobject:
3642            return self.analyse_as_pyobject(env, is_slice, getting, setting)
3643        elif base_type.is_ptr or base_type.is_array:
3644            return self.analyse_as_c_array(env, is_slice)
3645        elif base_type.is_cpp_class:
3646            return self.analyse_as_cpp(env, setting)
3647        elif base_type.is_cfunction:
3648            return self.analyse_as_c_function(env)
3649        elif base_type.is_ctuple:
3650            return self.analyse_as_c_tuple(env, getting, setting)
3651        else:
3652            error(self.pos,
3653                  "Attempting to index non-array type '%s'" %
3654                  base_type)
3655            self.type = PyrexTypes.error_type
3656            return self
3657
3658    def analyse_as_pyobject(self, env, is_slice, getting, setting):
3659        base_type = self.base.type
3660        if self.index.type.is_unicode_char and base_type is not dict_type:
3661            # TODO: eventually fold into case below and remove warning, once people have adapted their code
3662            warning(self.pos,
3663                    "Item lookup of unicode character codes now always converts to a Unicode string. "
3664                    "Use an explicit C integer cast to get back the previous integer lookup behaviour.", level=1)
3665            self.index = self.index.coerce_to_pyobject(env)
3666            self.is_temp = 1
3667        elif self.index.type.is_int and base_type is not dict_type:
3668            if (getting
3669                    and (base_type in (list_type, tuple_type, bytearray_type))
3670                    and (not self.index.type.signed
3671                         or not env.directives['wraparound']
3672                         or (isinstance(self.index, IntNode) and
3673                             self.index.has_constant_result() and self.index.constant_result >= 0))
3674                    and not env.directives['boundscheck']):
3675                self.is_temp = 0
3676            else:
3677                self.is_temp = 1
3678            self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
3679            self.original_index_type.create_to_py_utility_code(env)
3680        else:
3681            self.index = self.index.coerce_to_pyobject(env)
3682            self.is_temp = 1
3683
3684        if self.index.type.is_int and base_type is unicode_type:
3685            # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
3686            # if required, so this is fast and safe
3687            self.type = PyrexTypes.c_py_ucs4_type
3688        elif self.index.type.is_int and base_type is bytearray_type:
3689            if setting:
3690                self.type = PyrexTypes.c_uchar_type
3691            else:
3692                # not using 'uchar' to enable fast and safe error reporting as '-1'
3693                self.type = PyrexTypes.c_int_type
3694        elif is_slice and base_type in (bytes_type, bytearray_type, str_type, unicode_type, list_type, tuple_type):
3695            self.type = base_type
3696        else:
3697            item_type = None
3698            if base_type in (list_type, tuple_type) and self.index.type.is_int:
3699                item_type = infer_sequence_item_type(
3700                    env, self.base, self.index, seq_type=base_type)
3701            if item_type is None:
3702                item_type = py_object_type
3703            self.type = item_type
3704            if base_type in (list_type, tuple_type, dict_type):
3705                # do the None check explicitly (not in a helper) to allow optimising it away
3706                self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
3707
3708        self.wrap_in_nonecheck_node(env, getting)
3709        return self
3710
3711    def analyse_as_c_array(self, env, is_slice):
3712        base_type = self.base.type
3713        self.type = base_type.base_type
3714        if is_slice:
3715            self.type = base_type
3716        elif self.index.type.is_pyobject:
3717            self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env)
3718        elif not self.index.type.is_int:
3719            error(self.pos, "Invalid index type '%s'" % self.index.type)
3720        return self
3721
3722    def analyse_as_cpp(self, env, setting):
3723        base_type = self.base.type
3724        function = env.lookup_operator("[]", [self.base, self.index])
3725        if function is None:
3726            error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
3727            self.type = PyrexTypes.error_type
3728            self.result_code = "<error>"
3729            return self
3730        func_type = function.type
3731        if func_type.is_ptr:
3732            func_type = func_type.base_type
3733        self.exception_check = func_type.exception_check
3734        self.exception_value = func_type.exception_value
3735        if self.exception_check:
3736            if not setting:
3737                self.is_temp = True
3738            if self.exception_value is None:
3739                env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
3740        self.index = self.index.coerce_to(func_type.args[0].type, env)
3741        self.type = func_type.return_type
3742        if setting and not func_type.return_type.is_reference:
3743            error(self.pos, "Can't set non-reference result '%s'" % self.type)
3744        return self
3745
3746    def analyse_as_c_function(self, env):
3747        base_type = self.base.type
3748        if base_type.is_fused:
3749            self.parse_indexed_fused_cdef(env)
3750        else:
3751            self.type_indices = self.parse_index_as_types(env)
3752            self.index = None  # FIXME: use a dedicated Node class instead of generic IndexNode
3753            if base_type.templates is None:
3754                error(self.pos, "Can only parameterize template functions.")
3755                self.type = error_type
3756            elif self.type_indices is None:
3757                # Error recorded earlier.
3758                self.type = error_type
3759            elif len(base_type.templates) != len(self.type_indices):
3760                error(self.pos, "Wrong number of template arguments: expected %s, got %s" % (
3761                        (len(base_type.templates), len(self.type_indices))))
3762                self.type = error_type
3763            else:
3764                self.type = base_type.specialize(dict(zip(base_type.templates, self.type_indices)))
3765        # FIXME: use a dedicated Node class instead of generic IndexNode
3766        return self
3767
3768    def analyse_as_c_tuple(self, env, getting, setting):
3769        base_type = self.base.type
3770        if isinstance(self.index, IntNode) and self.index.has_constant_result():
3771            index = self.index.constant_result
3772            if -base_type.size <= index < base_type.size:
3773                if index < 0:
3774                    index += base_type.size
3775                self.type = base_type.components[index]
3776            else:
3777                error(self.pos,
3778                      "Index %s out of bounds for '%s'" %
3779                      (index, base_type))
3780                self.type = PyrexTypes.error_type
3781            return self
3782        else:
3783            self.base = self.base.coerce_to_pyobject(env)
3784            return self.analyse_base_and_index_types(env, getting=getting, setting=setting, analyse_base=False)
3785
3786    def analyse_as_buffer_operation(self, env, getting):
3787        """
3788        Analyse buffer indexing and memoryview indexing/slicing
3789        """
3790        if isinstance(self.index, TupleNode):
3791            indices = self.index.args
3792        else:
3793            indices = [self.index]
3794
3795        base = self.base
3796        base_type = base.type
3797        replacement_node = None
3798        if base_type.is_memoryviewslice:
3799            # memoryviewslice indexing or slicing
3800            from . import MemoryView
3801            if base.is_memview_slice:
3802                # For memory views, "view[i][j]" is the same as "view[i, j]" => use the latter for speed.
3803                merged_indices = base.merged_indices(indices)
3804                if merged_indices is not None:
3805                    base = base.base
3806                    base_type = base.type
3807                    indices = merged_indices
3808            have_slices, indices, newaxes = MemoryView.unellipsify(indices, base_type.ndim)
3809            if have_slices:
3810                replacement_node = MemoryViewSliceNode(self.pos, indices=indices, base=base)
3811            else:
3812                replacement_node = MemoryViewIndexNode(self.pos, indices=indices, base=base)
3813        elif base_type.is_buffer or base_type.is_pythran_expr:
3814            if base_type.is_pythran_expr or len(indices) == base_type.ndim:
3815                # Buffer indexing
3816                is_buffer_access = True
3817                indices = [index.analyse_types(env) for index in indices]
3818                if base_type.is_pythran_expr:
3819                    do_replacement = all(
3820                        index.type.is_int or index.is_slice or index.type.is_pythran_expr
3821                        for index in indices)
3822                    if do_replacement:
3823                        for i,index in enumerate(indices):
3824                            if index.is_slice:
3825                                index = SliceIntNode(index.pos, start=index.start, stop=index.stop, step=index.step)
3826                                index = index.analyse_types(env)
3827                                indices[i] = index
3828                else:
3829                    do_replacement = all(index.type.is_int for index in indices)
3830                if do_replacement:
3831                    replacement_node = BufferIndexNode(self.pos, indices=indices, base=base)
3832                    # On cloning, indices is cloned. Otherwise, unpack index into indices.
3833                    assert not isinstance(self.index, CloneNode)
3834
3835        if replacement_node is not None:
3836            replacement_node = replacement_node.analyse_types(env, getting)
3837        return replacement_node
3838
3839    def wrap_in_nonecheck_node(self, env, getting):
3840        if not env.directives['nonecheck'] or not self.base.may_be_none():
3841            return
3842        self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
3843
3844    def parse_index_as_types(self, env, required=True):
3845        if isinstance(self.index, TupleNode):
3846            indices = self.index.args
3847        else:
3848            indices = [self.index]
3849        type_indices = []
3850        for index in indices:
3851            type_indices.append(index.analyse_as_type(env))
3852            if type_indices[-1] is None:
3853                if required:
3854                    error(index.pos, "not parsable as a type")
3855                return None
3856        return type_indices
3857
3858    def parse_indexed_fused_cdef(self, env):
3859        """
3860        Interpret fused_cdef_func[specific_type1, ...]
3861
3862        Note that if this method is called, we are an indexed cdef function
3863        with fused argument types, and this IndexNode will be replaced by the
3864        NameNode with specific entry just after analysis of expressions by
3865        AnalyseExpressionsTransform.
3866        """
3867        self.type = PyrexTypes.error_type
3868
3869        self.is_fused_index = True
3870
3871        base_type = self.base.type
3872        positions = []
3873
3874        if self.index.is_name or self.index.is_attribute:
3875            positions.append(self.index.pos)
3876        elif isinstance(self.index, TupleNode):
3877            for arg in self.index.args:
3878                positions.append(arg.pos)
3879        specific_types = self.parse_index_as_types(env, required=False)
3880
3881        if specific_types is None:
3882            self.index = self.index.analyse_types(env)
3883
3884            if not self.base.entry.as_variable:
3885                error(self.pos, "Can only index fused functions with types")
3886            else:
3887                # A cpdef function indexed with Python objects
3888                self.base.entry = self.entry = self.base.entry.as_variable
3889                self.base.type = self.type = self.entry.type
3890
3891                self.base.is_temp = True
3892                self.is_temp = True
3893
3894                self.entry.used = True
3895
3896            self.is_fused_index = False
3897            return
3898
3899        for i, type in enumerate(specific_types):
3900            specific_types[i] = type.specialize_fused(env)
3901
3902        fused_types = base_type.get_fused_types()
3903        if len(specific_types) > len(fused_types):
3904            return error(self.pos, "Too many types specified")
3905        elif len(specific_types) < len(fused_types):
3906            t = fused_types[len(specific_types)]
3907            return error(self.pos, "Not enough types specified to specialize "
3908                                   "the function, %s is still fused" % t)
3909
3910        # See if our index types form valid specializations
3911        for pos, specific_type, fused_type in zip(positions,
3912                                                  specific_types,
3913                                                  fused_types):
3914            if not any([specific_type.same_as(t) for t in fused_type.types]):
3915                return error(pos, "Type not in fused type")
3916
3917            if specific_type is None or specific_type.is_error:
3918                return
3919
3920        fused_to_specific = dict(zip(fused_types, specific_types))
3921        type = base_type.specialize(fused_to_specific)
3922
3923        if type.is_fused:
3924            # Only partially specific, this is invalid
3925            error(self.pos,
3926                  "Index operation makes function only partially specific")
3927        else:
3928            # Fully specific, find the signature with the specialized entry
3929            for signature in self.base.type.get_all_specialized_function_types():
3930                if type.same_as(signature):
3931                    self.type = signature
3932
3933                    if self.base.is_attribute:
3934                        # Pretend to be a normal attribute, for cdef extension
3935                        # methods
3936                        self.entry = signature.entry
3937                        self.is_attribute = True
3938                        self.obj = self.base.obj
3939
3940                    self.type.entry.used = True
3941                    self.base.type = signature
3942                    self.base.entry = signature.entry
3943
3944                    break
3945            else:
3946                # This is a bug
3947                raise InternalError("Couldn't find the right signature")
3948
3949    gil_message = "Indexing Python object"
3950
3951    def calculate_result_code(self):
3952        if self.base.type in (list_type, tuple_type, bytearray_type):
3953            if self.base.type is list_type:
3954                index_code = "PyList_GET_ITEM(%s, %s)"
3955            elif self.base.type is tuple_type:
3956                index_code = "PyTuple_GET_ITEM(%s, %s)"
3957            elif self.base.type is bytearray_type:
3958                index_code = "((unsigned char)(PyByteArray_AS_STRING(%s)[%s]))"
3959            else:
3960                assert False, "unexpected base type in indexing: %s" % self.base.type
3961        elif self.base.type.is_cfunction:
3962            return "%s<%s>" % (
3963                self.base.result(),
3964                ",".join([param.empty_declaration_code() for param in self.type_indices]))
3965        elif self.base.type.is_ctuple:
3966            index = self.index.constant_result
3967            if index < 0:
3968                index += self.base.type.size
3969            return "%s.f%s" % (self.base.result(), index)
3970        else:
3971            if (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
3972                error(self.pos, "Invalid use of pointer slice")
3973                return
3974            index_code = "(%s[%s])"
3975        return index_code % (self.base.result(), self.index.result())
3976
3977    def extra_index_params(self, code):
3978        if self.index.type.is_int:
3979            is_list = self.base.type is list_type
3980            wraparound = (
3981                bool(code.globalstate.directives['wraparound']) and
3982                self.original_index_type.signed and
3983                not (isinstance(self.index.constant_result, _py_int_types)
3984                     and self.index.constant_result >= 0))
3985            boundscheck = bool(code.globalstate.directives['boundscheck'])
3986            return ", %s, %d, %s, %d, %d, %d" % (
3987                self.original_index_type.empty_declaration_code(),
3988                self.original_index_type.signed and 1 or 0,
3989                self.original_index_type.to_py_function,
3990                is_list, wraparound, boundscheck)
3991        else:
3992            return ""
3993
3994    def generate_result_code(self, code):
3995        if not self.is_temp:
3996            # all handled in self.calculate_result_code()
3997            return
3998
3999        utility_code = None
4000        if self.type.is_pyobject:
4001            error_value = 'NULL'
4002            if self.index.type.is_int:
4003                if self.base.type is list_type:
4004                    function = "__Pyx_GetItemInt_List"
4005                elif self.base.type is tuple_type:
4006                    function = "__Pyx_GetItemInt_Tuple"
4007                else:
4008                    function = "__Pyx_GetItemInt"
4009                utility_code = TempitaUtilityCode.load_cached("GetItemInt", "ObjectHandling.c")
4010            else:
4011                if self.base.type is dict_type:
4012                    function = "__Pyx_PyDict_GetItem"
4013                    utility_code = UtilityCode.load_cached("DictGetItem", "ObjectHandling.c")
4014                elif self.base.type is py_object_type and self.index.type in (str_type, unicode_type):
4015                    # obj[str] is probably doing a dict lookup
4016                    function = "__Pyx_PyObject_Dict_GetItem"
4017                    utility_code = UtilityCode.load_cached("DictGetItem", "ObjectHandling.c")
4018                else:
4019                    function = "__Pyx_PyObject_GetItem"
4020                    code.globalstate.use_utility_code(
4021                        TempitaUtilityCode.load_cached("GetItemInt", "ObjectHandling.c"))
4022                    utility_code = UtilityCode.load_cached("ObjectGetItem", "ObjectHandling.c")
4023        elif self.type.is_unicode_char and self.base.type is unicode_type:
4024            assert self.index.type.is_int
4025            function = "__Pyx_GetItemInt_Unicode"
4026            error_value = '(Py_UCS4)-1'
4027            utility_code = UtilityCode.load_cached("GetItemIntUnicode", "StringTools.c")
4028        elif self.base.type is bytearray_type:
4029            assert self.index.type.is_int
4030            assert self.type.is_int
4031            function = "__Pyx_GetItemInt_ByteArray"
4032            error_value = '-1'
4033            utility_code = UtilityCode.load_cached("GetItemIntByteArray", "StringTools.c")
4034        elif not (self.base.type.is_cpp_class and self.exception_check):
4035            assert False, "unexpected type %s and base type %s for indexing" % (
4036                self.type, self.base.type)
4037
4038        if utility_code is not None:
4039            code.globalstate.use_utility_code(utility_code)
4040
4041        if self.index.type.is_int:
4042            index_code = self.index.result()
4043        else:
4044            index_code = self.index.py_result()
4045
4046        if self.base.type.is_cpp_class and self.exception_check:
4047            translate_cpp_exception(code, self.pos,
4048                "%s = %s[%s];" % (self.result(), self.base.result(),
4049                                  self.index.result()),
4050                self.result() if self.type.is_pyobject else None,
4051                self.exception_value, self.in_nogil_context)
4052        else:
4053            error_check = '!%s' if error_value == 'NULL' else '%%s == %s' % error_value
4054            code.putln(
4055                "%s = %s(%s, %s%s); %s" % (
4056                    self.result(),
4057                    function,
4058                    self.base.py_result(),
4059                    index_code,
4060                    self.extra_index_params(code),
4061                    code.error_goto_if(error_check % self.result(), self.pos)))
4062        if self.type.is_pyobject:
4063            code.put_gotref(self.py_result())
4064
4065    def generate_setitem_code(self, value_code, code):
4066        if self.index.type.is_int:
4067            if self.base.type is bytearray_type:
4068                code.globalstate.use_utility_code(
4069                    UtilityCode.load_cached("SetItemIntByteArray", "StringTools.c"))
4070                function = "__Pyx_SetItemInt_ByteArray"
4071            else:
4072                code.globalstate.use_utility_code(
4073                    UtilityCode.load_cached("SetItemInt", "ObjectHandling.c"))
4074                function = "__Pyx_SetItemInt"
4075            index_code = self.index.result()
4076        else:
4077            index_code = self.index.py_result()
4078            if self.base.type is dict_type:
4079                function = "PyDict_SetItem"
4080            # It would seem that we could specialized lists/tuples, but that
4081            # shouldn't happen here.
4082            # Both PyList_SetItem() and PyTuple_SetItem() take a Py_ssize_t as
4083            # index instead of an object, and bad conversion here would give
4084            # the wrong exception. Also, tuples are supposed to be immutable,
4085            # and raise a TypeError when trying to set their entries
4086            # (PyTuple_SetItem() is for creating new tuples from scratch).
4087            else:
4088                function = "PyObject_SetItem"
4089        code.putln(code.error_goto_if_neg(
4090            "%s(%s, %s, %s%s)" % (
4091                function,
4092                self.base.py_result(),
4093                index_code,
4094                value_code,
4095                self.extra_index_params(code)),
4096            self.pos))
4097
4098    def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
4099        exception_check=None, exception_value=None):
4100        self.generate_subexpr_evaluation_code(code)
4101
4102        if self.type.is_pyobject:
4103            self.generate_setitem_code(rhs.py_result(), code)
4104        elif self.base.type is bytearray_type:
4105            value_code = self._check_byte_value(code, rhs)
4106            self.generate_setitem_code(value_code, code)
4107        elif self.base.type.is_cpp_class and self.exception_check and self.exception_check == '+':
4108            if overloaded_assignment and exception_check and \
4109                self.exception_value != exception_value:
4110                # Handle the case that both the index operator and the assignment
4111                # operator have a c++ exception handler and they are not the same.
4112                translate_double_cpp_exception(code, self.pos, self.type,
4113                    self.result(), rhs.result(), self.exception_value,
4114                    exception_value, self.in_nogil_context)
4115            else:
4116                # Handle the case that only the index operator has a
4117                # c++ exception handler, or that
4118                # both exception handlers are the same.
4119                translate_cpp_exception(code, self.pos,
4120                    "%s = %s;" % (self.result(), rhs.result()),
4121                    self.result() if self.type.is_pyobject else None,
4122                    self.exception_value, self.in_nogil_context)
4123        else:
4124            code.putln(
4125                "%s = %s;" % (self.result(), rhs.result()))
4126
4127        self.generate_subexpr_disposal_code(code)
4128        self.free_subexpr_temps(code)
4129        rhs.generate_disposal_code(code)
4130        rhs.free_temps(code)
4131
4132    def _check_byte_value(self, code, rhs):
4133        # TODO: should we do this generally on downcasts, or just here?
4134        assert rhs.type.is_int, repr(rhs.type)
4135        value_code = rhs.result()
4136        if rhs.has_constant_result():
4137            if 0 <= rhs.constant_result < 256:
4138                return value_code
4139            needs_cast = True  # make at least the C compiler happy
4140            warning(rhs.pos,
4141                    "value outside of range(0, 256)"
4142                    " when assigning to byte: %s" % rhs.constant_result,
4143                    level=1)
4144        else:
4145            needs_cast = rhs.type != PyrexTypes.c_uchar_type
4146
4147        if not self.nogil:
4148            conditions = []
4149            if rhs.is_literal or rhs.type.signed:
4150                conditions.append('%s < 0' % value_code)
4151            if (rhs.is_literal or not
4152                    (rhs.is_temp and rhs.type in (
4153                        PyrexTypes.c_uchar_type, PyrexTypes.c_char_type,
4154                        PyrexTypes.c_schar_type))):
4155                conditions.append('%s > 255' % value_code)
4156            if conditions:
4157                code.putln("if (unlikely(%s)) {" % ' || '.join(conditions))
4158                code.putln(
4159                    'PyErr_SetString(PyExc_ValueError,'
4160                    ' "byte must be in range(0, 256)"); %s' %
4161                    code.error_goto(self.pos))
4162                code.putln("}")
4163
4164        if needs_cast:
4165            value_code = '((unsigned char)%s)' % value_code
4166        return value_code
4167
4168    def generate_deletion_code(self, code, ignore_nonexisting=False):
4169        self.generate_subexpr_evaluation_code(code)
4170        #if self.type.is_pyobject:
4171        if self.index.type.is_int:
4172            function = "__Pyx_DelItemInt"
4173            index_code = self.index.result()
4174            code.globalstate.use_utility_code(
4175                UtilityCode.load_cached("DelItemInt", "ObjectHandling.c"))
4176        else:
4177            index_code = self.index.py_result()
4178            if self.base.type is dict_type:
4179                function = "PyDict_DelItem"
4180            else:
4181                function = "PyObject_DelItem"
4182        code.putln(code.error_goto_if_neg(
4183            "%s(%s, %s%s)" % (
4184                function,
4185                self.base.py_result(),
4186                index_code,
4187                self.extra_index_params(code)),
4188            self.pos))
4189        self.generate_subexpr_disposal_code(code)
4190        self.free_subexpr_temps(code)
4191
4192
4193class BufferIndexNode(_IndexingBaseNode):
4194    """
4195    Indexing of buffers and memoryviews. This node is created during type
4196    analysis from IndexNode and replaces it.
4197
4198    Attributes:
4199        base - base node being indexed
4200        indices - list of indexing expressions
4201    """
4202
4203    subexprs = ['base', 'indices']
4204
4205    is_buffer_access = True
4206
4207    # Whether we're assigning to a buffer (in that case it needs to be writable)
4208    writable_needed = False
4209
4210    # Any indexing temp variables that we need to clean up.
4211    index_temps = ()
4212
4213    def analyse_target_types(self, env):
4214        self.analyse_types(env, getting=False)
4215
4216    def analyse_types(self, env, getting=True):
4217        """
4218        Analyse types for buffer indexing only. Overridden by memoryview
4219        indexing and slicing subclasses
4220        """
4221        # self.indices are already analyzed
4222        if not self.base.is_name and not is_pythran_expr(self.base.type):
4223            error(self.pos, "Can only index buffer variables")
4224            self.type = error_type
4225            return self
4226
4227        if not getting:
4228            if not self.base.entry.type.writable:
4229                error(self.pos, "Writing to readonly buffer")
4230            else:
4231                self.writable_needed = True
4232                if self.base.type.is_buffer:
4233                    self.base.entry.buffer_aux.writable_needed = True
4234
4235        self.none_error_message = "'NoneType' object is not subscriptable"
4236        self.analyse_buffer_index(env, getting)
4237        self.wrap_in_nonecheck_node(env)
4238        return self
4239
4240    def analyse_buffer_index(self, env, getting):
4241        if is_pythran_expr(self.base.type):
4242            index_with_type_list = [(idx, idx.type) for idx in self.indices]
4243            self.type = PythranExpr(pythran_indexing_type(self.base.type, index_with_type_list))
4244        else:
4245            self.base = self.base.coerce_to_simple(env)
4246            self.type = self.base.type.dtype
4247        self.buffer_type = self.base.type
4248
4249        if getting and (self.type.is_pyobject or self.type.is_pythran_expr):
4250            self.is_temp = True
4251
4252    def analyse_assignment(self, rhs):
4253        """
4254        Called by IndexNode when this node is assigned to,
4255        with the rhs of the assignment
4256        """
4257
4258    def wrap_in_nonecheck_node(self, env):
4259        if not env.directives['nonecheck'] or not self.base.may_be_none():
4260            return
4261        self.base = self.base.as_none_safe_node(self.none_error_message)
4262
4263    def nogil_check(self, env):
4264        if self.is_buffer_access or self.is_memview_index:
4265            if self.type.is_pyobject:
4266                error(self.pos, "Cannot access buffer with object dtype without gil")
4267                self.type = error_type
4268
4269    def calculate_result_code(self):
4270        return "(*%s)" % self.buffer_ptr_code
4271
4272    def buffer_entry(self):
4273        base = self.base
4274        if self.base.is_nonecheck:
4275            base = base.arg
4276        return base.type.get_entry(base)
4277
4278    def get_index_in_temp(self, code, ivar):
4279        ret = code.funcstate.allocate_temp(
4280            PyrexTypes.widest_numeric_type(
4281                ivar.type,
4282                PyrexTypes.c_ssize_t_type if ivar.type.signed else PyrexTypes.c_size_t_type),
4283            manage_ref=False)
4284        code.putln("%s = %s;" % (ret, ivar.result()))
4285        return ret
4286
4287    def buffer_lookup_code(self, code):
4288        """
4289        ndarray[1, 2, 3] and memslice[1, 2, 3]
4290        """
4291        if self.in_nogil_context:
4292            if self.is_buffer_access or self.is_memview_index:
4293                if code.globalstate.directives['boundscheck']:
4294                    warning(self.pos, "Use boundscheck(False) for faster access", level=1)
4295
4296        # Assign indices to temps of at least (s)size_t to allow further index calculations.
4297        self.index_temps = index_temps = [self.get_index_in_temp(code,ivar) for ivar in self.indices]
4298
4299        # Generate buffer access code using these temps
4300        from . import Buffer
4301        buffer_entry = self.buffer_entry()
4302        if buffer_entry.type.is_buffer:
4303            negative_indices = buffer_entry.type.negative_indices
4304        else:
4305            negative_indices = Buffer.buffer_defaults['negative_indices']
4306
4307        return buffer_entry, Buffer.put_buffer_lookup_code(
4308            entry=buffer_entry,
4309            index_signeds=[ivar.type.signed for ivar in self.indices],
4310            index_cnames=index_temps,
4311            directives=code.globalstate.directives,
4312            pos=self.pos, code=code,
4313            negative_indices=negative_indices,
4314            in_nogil_context=self.in_nogil_context)
4315
4316    def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
4317        self.generate_subexpr_evaluation_code(code)
4318        self.generate_buffer_setitem_code(rhs, code)
4319        self.generate_subexpr_disposal_code(code)
4320        self.free_subexpr_temps(code)
4321        rhs.generate_disposal_code(code)
4322        rhs.free_temps(code)
4323
4324    def generate_buffer_setitem_code(self, rhs, code, op=""):
4325        base_type = self.base.type
4326        if is_pythran_expr(base_type) and is_pythran_supported_type(rhs.type):
4327            obj = code.funcstate.allocate_temp(PythranExpr(pythran_type(self.base.type)), manage_ref=False)
4328            # We have got to do this because we have to declare pythran objects
4329            # at the beginning of the functions.
4330            # Indeed, Cython uses "goto" statement for error management, and
4331            # RAII doesn't work with that kind of construction.
4332            # Moreover, the way Pythran expressions are made is that they don't
4333            # support move-assignation easily.
4334            # This, we explicitly destroy then in-place new objects in this
4335            # case.
4336            code.putln("__Pyx_call_destructor(%s);" % obj)
4337            code.putln("new (&%s) decltype(%s){%s};" % (obj, obj, self.base.pythran_result()))
4338            code.putln("%s%s %s= %s;" % (
4339                obj,
4340                pythran_indexing_code(self.indices),
4341                op,
4342                rhs.pythran_result()))
4343            code.funcstate.release_temp(obj)
4344            return
4345
4346        # Used from generate_assignment_code and InPlaceAssignmentNode
4347        buffer_entry, ptrexpr = self.buffer_lookup_code(code)
4348
4349        if self.buffer_type.dtype.is_pyobject:
4350            # Must manage refcounts. Decref what is already there
4351            # and incref what we put in.
4352            ptr = code.funcstate.allocate_temp(buffer_entry.buf_ptr_type,
4353                                               manage_ref=False)
4354            rhs_code = rhs.result()
4355            code.putln("%s = %s;" % (ptr, ptrexpr))
4356            code.put_gotref("*%s" % ptr)
4357            code.putln("__Pyx_INCREF(%s); __Pyx_DECREF(*%s);" % (
4358                rhs_code, ptr))
4359            code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
4360            code.put_giveref("*%s" % ptr)
4361            code.funcstate.release_temp(ptr)
4362        else:
4363            # Simple case
4364            code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
4365
4366    def generate_result_code(self, code):
4367        if is_pythran_expr(self.base.type):
4368            res = self.result()
4369            code.putln("__Pyx_call_destructor(%s);" % res)
4370            code.putln("new (&%s) decltype(%s){%s%s};" % (
4371                res,
4372                res,
4373                self.base.pythran_result(),
4374                pythran_indexing_code(self.indices)))
4375            return
4376        buffer_entry, self.buffer_ptr_code = self.buffer_lookup_code(code)
4377        if self.type.is_pyobject:
4378            # is_temp is True, so must pull out value and incref it.
4379            # NOTE: object temporary results for nodes are declared
4380            #       as PyObject *, so we need a cast
4381            code.putln("%s = (PyObject *) *%s;" % (self.result(), self.buffer_ptr_code))
4382            code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
4383
4384    def free_subexpr_temps(self, code):
4385        for temp in self.index_temps:
4386            code.funcstate.release_temp(temp)
4387        self.index_temps = ()
4388        super(BufferIndexNode, self).free_subexpr_temps(code)
4389
4390
4391class MemoryViewIndexNode(BufferIndexNode):
4392
4393    is_memview_index = True
4394    is_buffer_access = False
4395    warned_untyped_idx = False
4396
4397    def analyse_types(self, env, getting=True):
4398        # memoryviewslice indexing or slicing
4399        from . import MemoryView
4400
4401        self.is_pythran_mode = has_np_pythran(env)
4402        indices = self.indices
4403        have_slices, indices, newaxes = MemoryView.unellipsify(indices, self.base.type.ndim)
4404
4405        if not getting:
4406            self.writable_needed = True
4407            if self.base.is_name or self.base.is_attribute:
4408                self.base.entry.type.writable_needed = True
4409
4410        self.memslice_index = (not newaxes and len(indices) == self.base.type.ndim)
4411        axes = []
4412
4413        index_type = PyrexTypes.c_py_ssize_t_type
4414        new_indices = []
4415
4416        if len(indices) - len(newaxes) > self.base.type.ndim:
4417            self.type = error_type
4418            error(indices[self.base.type.ndim].pos,
4419                  "Too many indices specified for type %s" % self.base.type)
4420            return self
4421
4422        axis_idx = 0
4423        for i, index in enumerate(indices[:]):
4424            index = index.analyse_types(env)
4425            if index.is_none:
4426                self.is_memview_slice = True
4427                new_indices.append(index)
4428                axes.append(('direct', 'strided'))
4429                continue
4430
4431            access, packing = self.base.type.axes[axis_idx]
4432            axis_idx += 1
4433
4434            if index.is_slice:
4435                self.is_memview_slice = True
4436                if index.step.is_none:
4437                    axes.append((access, packing))
4438                else:
4439                    axes.append((access, 'strided'))
4440
4441                # Coerce start, stop and step to temps of the right type
4442                for attr in ('start', 'stop', 'step'):
4443                    value = getattr(index, attr)
4444                    if not value.is_none:
4445                        value = value.coerce_to(index_type, env)
4446                        #value = value.coerce_to_temp(env)
4447                        setattr(index, attr, value)
4448                        new_indices.append(value)
4449
4450            elif index.type.is_int or index.type.is_pyobject:
4451                if index.type.is_pyobject and not self.warned_untyped_idx:
4452                    warning(index.pos, "Index should be typed for more efficient access", level=2)
4453                    MemoryViewIndexNode.warned_untyped_idx = True
4454
4455                self.is_memview_index = True
4456                index = index.coerce_to(index_type, env)
4457                indices[i] = index
4458                new_indices.append(index)
4459
4460            else:
4461                self.type = error_type
4462                error(index.pos, "Invalid index for memoryview specified, type %s" % index.type)
4463                return self
4464
4465        ### FIXME: replace by MemoryViewSliceNode if is_memview_slice ?
4466        self.is_memview_index = self.is_memview_index and not self.is_memview_slice
4467        self.indices = new_indices
4468        # All indices with all start/stop/step for slices.
4469        # We need to keep this around.
4470        self.original_indices = indices
4471        self.nogil = env.nogil
4472
4473        self.analyse_operation(env, getting, axes)
4474        self.wrap_in_nonecheck_node(env)
4475        return self
4476
4477    def analyse_operation(self, env, getting, axes):
4478        self.none_error_message = "Cannot index None memoryview slice"
4479        self.analyse_buffer_index(env, getting)
4480
4481    def analyse_broadcast_operation(self, rhs):
4482        """
4483        Support broadcasting for slice assignment.
4484        E.g.
4485            m_2d[...] = m_1d  # or,
4486            m_1d[...] = m_2d  # if the leading dimension has extent 1
4487        """
4488        if self.type.is_memoryviewslice:
4489            lhs = self
4490            if lhs.is_memview_broadcast or rhs.is_memview_broadcast:
4491                lhs.is_memview_broadcast = True
4492                rhs.is_memview_broadcast = True
4493
4494    def analyse_as_memview_scalar_assignment(self, rhs):
4495        lhs = self.analyse_assignment(rhs)
4496        if lhs:
4497            rhs.is_memview_copy_assignment = lhs.is_memview_copy_assignment
4498            return lhs
4499        return self
4500
4501
4502class MemoryViewSliceNode(MemoryViewIndexNode):
4503
4504    is_memview_slice = True
4505
4506    # No-op slicing operation, this node will be replaced
4507    is_ellipsis_noop = False
4508    is_memview_scalar_assignment = False
4509    is_memview_index = False
4510    is_memview_broadcast = False
4511
4512    def analyse_ellipsis_noop(self, env, getting):
4513        """Slicing operations needing no evaluation, i.e. m[...] or m[:, :]"""
4514        ### FIXME: replace directly
4515        self.is_ellipsis_noop = all(
4516            index.is_slice and index.start.is_none and index.stop.is_none and index.step.is_none
4517            for index in self.indices)
4518
4519        if self.is_ellipsis_noop:
4520            self.type = self.base.type
4521
4522    def analyse_operation(self, env, getting, axes):
4523        from . import MemoryView
4524
4525        if not getting:
4526            self.is_memview_broadcast = True
4527            self.none_error_message = "Cannot assign to None memoryview slice"
4528        else:
4529            self.none_error_message = "Cannot slice None memoryview slice"
4530
4531        self.analyse_ellipsis_noop(env, getting)
4532        if self.is_ellipsis_noop:
4533            return
4534
4535        self.index = None
4536        self.is_temp = True
4537        self.use_managed_ref = True
4538
4539        if not MemoryView.validate_axes(self.pos, axes):
4540            self.type = error_type
4541            return
4542
4543        self.type = PyrexTypes.MemoryViewSliceType(self.base.type.dtype, axes)
4544
4545        if not (self.base.is_simple() or self.base.result_in_temp()):
4546            self.base = self.base.coerce_to_temp(env)
4547
4548    def analyse_assignment(self, rhs):
4549        if not rhs.type.is_memoryviewslice and (
4550                self.type.dtype.assignable_from(rhs.type) or
4551                rhs.type.is_pyobject):
4552            # scalar assignment
4553            return MemoryCopyScalar(self.pos, self)
4554        else:
4555            return MemoryCopySlice(self.pos, self)
4556
4557    def merged_indices(self, indices):
4558        """Return a new list of indices/slices with 'indices' merged into the current ones
4559        according to slicing rules.
4560        Is used to implement "view[i][j]" => "view[i, j]".
4561        Return None if the indices cannot (easily) be merged at compile time.
4562        """
4563        if not indices:
4564            return None
4565        # NOTE: Need to evaluate "self.original_indices" here as they might differ from "self.indices".
4566        new_indices = self.original_indices[:]
4567        indices = indices[:]
4568        for i, s in enumerate(self.original_indices):
4569            if s.is_slice:
4570                if s.start.is_none and s.stop.is_none and s.step.is_none:
4571                    # Full slice found, replace by index.
4572                    new_indices[i] = indices[0]
4573                    indices.pop(0)
4574                    if not indices:
4575                        return new_indices
4576                else:
4577                    # Found something non-trivial, e.g. a partial slice.
4578                    return None
4579            elif not s.type.is_int:
4580                # Not a slice, not an integer index => could be anything...
4581                return None
4582        if indices:
4583            if len(new_indices) + len(indices) > self.base.type.ndim:
4584                return None
4585            new_indices += indices
4586        return new_indices
4587
4588    def is_simple(self):
4589        if self.is_ellipsis_noop:
4590            # TODO: fix SimpleCallNode.is_simple()
4591            return self.base.is_simple() or self.base.result_in_temp()
4592
4593        return self.result_in_temp()
4594
4595    def calculate_result_code(self):
4596        """This is called in case this is a no-op slicing node"""
4597        return self.base.result()
4598
4599    def generate_result_code(self, code):
4600        if self.is_ellipsis_noop:
4601            return  ### FIXME: remove
4602        buffer_entry = self.buffer_entry()
4603        have_gil = not self.in_nogil_context
4604
4605        # TODO Mark: this is insane, do it better
4606        have_slices = False
4607        it = iter(self.indices)
4608        for index in self.original_indices:
4609            if index.is_slice:
4610                have_slices = True
4611                if not index.start.is_none:
4612                    index.start = next(it)
4613                if not index.stop.is_none:
4614                    index.stop = next(it)
4615                if not index.step.is_none:
4616                    index.step = next(it)
4617            else:
4618                next(it)
4619
4620        assert not list(it)
4621
4622        buffer_entry.generate_buffer_slice_code(
4623            code, self.original_indices, self.result(),
4624            have_gil=have_gil, have_slices=have_slices,
4625            directives=code.globalstate.directives)
4626
4627    def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
4628        if self.is_ellipsis_noop:
4629            self.generate_subexpr_evaluation_code(code)
4630        else:
4631            self.generate_evaluation_code(code)
4632
4633        if self.is_memview_scalar_assignment:
4634            self.generate_memoryviewslice_assign_scalar_code(rhs, code)
4635        else:
4636            self.generate_memoryviewslice_setslice_code(rhs, code)
4637
4638        if self.is_ellipsis_noop:
4639            self.generate_subexpr_disposal_code(code)
4640        else:
4641            self.generate_disposal_code(code)
4642
4643        rhs.generate_disposal_code(code)
4644        rhs.free_temps(code)
4645
4646
4647class MemoryCopyNode(ExprNode):
4648    """
4649    Wraps a memoryview slice for slice assignment.
4650
4651        dst: destination mememoryview slice
4652    """
4653
4654    subexprs = ['dst']
4655
4656    def __init__(self, pos, dst):
4657        super(MemoryCopyNode, self).__init__(pos)
4658        self.dst = dst
4659        self.type = dst.type
4660
4661    def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
4662        self.dst.generate_evaluation_code(code)
4663        self._generate_assignment_code(rhs, code)
4664        self.dst.generate_disposal_code(code)
4665        self.dst.free_temps(code)
4666        rhs.generate_disposal_code(code)
4667        rhs.free_temps(code)
4668
4669
4670class MemoryCopySlice(MemoryCopyNode):
4671    """
4672    Copy the contents of slice src to slice dst. Does not support indirect
4673    slices.
4674
4675        memslice1[...] = memslice2
4676        memslice1[:] = memslice2
4677    """
4678
4679    is_memview_copy_assignment = True
4680    copy_slice_cname = "__pyx_memoryview_copy_contents"
4681
4682    def _generate_assignment_code(self, src, code):
4683        dst = self.dst
4684
4685        src.type.assert_direct_dims(src.pos)
4686        dst.type.assert_direct_dims(dst.pos)
4687
4688        code.putln(code.error_goto_if_neg(
4689            "%s(%s, %s, %d, %d, %d)" % (self.copy_slice_cname,
4690                                        src.result(), dst.result(),
4691                                        src.type.ndim, dst.type.ndim,
4692                                        dst.type.dtype.is_pyobject),
4693            dst.pos))
4694
4695
4696class MemoryCopyScalar(MemoryCopyNode):
4697    """
4698    Assign a scalar to a slice. dst must be simple, scalar will be assigned
4699    to a correct type and not just something assignable.
4700
4701        memslice1[...] = 0.0
4702        memslice1[:] = 0.0
4703    """
4704
4705    def __init__(self, pos, dst):
4706        super(MemoryCopyScalar, self).__init__(pos, dst)
4707        self.type = dst.type.dtype
4708
4709    def _generate_assignment_code(self, scalar, code):
4710        from . import MemoryView
4711
4712        self.dst.type.assert_direct_dims(self.dst.pos)
4713
4714        dtype = self.dst.type.dtype
4715        type_decl = dtype.declaration_code("")
4716        slice_decl = self.dst.type.declaration_code("")
4717
4718        code.begin_block()
4719        code.putln("%s __pyx_temp_scalar = %s;" % (type_decl, scalar.result()))
4720        if self.dst.result_in_temp() or self.dst.is_simple():
4721            dst_temp = self.dst.result()
4722        else:
4723            code.putln("%s __pyx_temp_slice = %s;" % (slice_decl, self.dst.result()))
4724            dst_temp = "__pyx_temp_slice"
4725
4726        slice_iter_obj = MemoryView.slice_iter(self.dst.type, dst_temp,
4727                                               self.dst.type.ndim, code)
4728        p = slice_iter_obj.start_loops()
4729
4730        if dtype.is_pyobject:
4731            code.putln("Py_DECREF(*(PyObject **) %s);" % p)
4732
4733        code.putln("*((%s *) %s) = __pyx_temp_scalar;" % (type_decl, p))
4734
4735        if dtype.is_pyobject:
4736            code.putln("Py_INCREF(__pyx_temp_scalar);")
4737
4738        slice_iter_obj.end_loops()
4739        code.end_block()
4740
4741
4742class SliceIndexNode(ExprNode):
4743    #  2-element slice indexing
4744    #
4745    #  base      ExprNode
4746    #  start     ExprNode or None
4747    #  stop      ExprNode or None
4748    #  slice     ExprNode or None   constant slice object
4749
4750    subexprs = ['base', 'start', 'stop', 'slice']
4751
4752    slice = None
4753
4754    def infer_type(self, env):
4755        base_type = self.base.infer_type(env)
4756        if base_type.is_string or base_type.is_cpp_class:
4757            return bytes_type
4758        elif base_type.is_pyunicode_ptr:
4759            return unicode_type
4760        elif base_type in (bytes_type, bytearray_type, str_type, unicode_type,
4761                           basestring_type, list_type, tuple_type):
4762            return base_type
4763        elif base_type.is_ptr or base_type.is_array:
4764            return PyrexTypes.c_array_type(base_type.base_type, None)
4765        return py_object_type
4766
4767    def inferable_item_node(self, index=0):
4768        # slicing shouldn't change the result type of the base, but the index might
4769        if index is not not_a_constant and self.start:
4770            if self.start.has_constant_result():
4771                index += self.start.constant_result
4772            else:
4773                index = not_a_constant
4774        return self.base.inferable_item_node(index)
4775
4776    def may_be_none(self):
4777        base_type = self.base.type
4778        if base_type:
4779            if base_type.is_string:
4780                return False
4781            if base_type in (bytes_type, str_type, unicode_type,
4782                             basestring_type, list_type, tuple_type):
4783                return False
4784        return ExprNode.may_be_none(self)
4785
4786    def calculate_constant_result(self):
4787        if self.start is None:
4788            start = None
4789        else:
4790            start = self.start.constant_result
4791        if self.stop is None:
4792            stop = None
4793        else:
4794            stop = self.stop.constant_result
4795        self.constant_result = self.base.constant_result[start:stop]
4796
4797    def compile_time_value(self, denv):
4798        base = self.base.compile_time_value(denv)
4799        if self.start is None:
4800            start = 0
4801        else:
4802            start = self.start.compile_time_value(denv)
4803        if self.stop is None:
4804            stop = None
4805        else:
4806            stop = self.stop.compile_time_value(denv)
4807        try:
4808            return base[start:stop]
4809        except Exception as e:
4810            self.compile_time_value_error(e)
4811
4812    def analyse_target_declaration(self, env):
4813        pass
4814
4815    def analyse_target_types(self, env):
4816        node = self.analyse_types(env, getting=False)
4817        # when assigning, we must accept any Python type
4818        if node.type.is_pyobject:
4819            node.type = py_object_type
4820        return node
4821
4822    def analyse_types(self, env, getting=True):
4823        self.base = self.base.analyse_types(env)
4824
4825        if self.base.type.is_buffer or self.base.type.is_pythran_expr or self.base.type.is_memoryviewslice:
4826            none_node = NoneNode(self.pos)
4827            index = SliceNode(self.pos,
4828                              start=self.start or none_node,
4829                              stop=self.stop or none_node,
4830                              step=none_node)
4831            index_node = IndexNode(self.pos, index=index, base=self.base)
4832            return index_node.analyse_base_and_index_types(
4833                env, getting=getting, setting=not getting,
4834                analyse_base=False)
4835
4836        if self.start:
4837            self.start = self.start.analyse_types(env)
4838        if self.stop:
4839            self.stop = self.stop.analyse_types(env)
4840
4841        if not env.directives['wraparound']:
4842            check_negative_indices(self.start, self.stop)
4843
4844        base_type = self.base.type
4845        if base_type.is_array and not getting:
4846            # cannot assign directly to C array => try to assign by making a copy
4847            if not self.start and not self.stop:
4848                self.type = base_type
4849            else:
4850                self.type = PyrexTypes.CPtrType(base_type.base_type)
4851        elif base_type.is_string or base_type.is_cpp_string:
4852            self.type = default_str_type(env)
4853        elif base_type.is_pyunicode_ptr:
4854            self.type = unicode_type
4855        elif base_type.is_ptr:
4856            self.type = base_type
4857        elif base_type.is_array:
4858            # we need a ptr type here instead of an array type, as
4859            # array types can result in invalid type casts in the C
4860            # code
4861            self.type = PyrexTypes.CPtrType(base_type.base_type)
4862        else:
4863            self.base = self.base.coerce_to_pyobject(env)
4864            self.type = py_object_type
4865        if base_type.is_builtin_type:
4866            # slicing builtin types returns something of the same type
4867            self.type = base_type
4868            self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
4869
4870        if self.type is py_object_type:
4871            if (not self.start or self.start.is_literal) and \
4872                    (not self.stop or self.stop.is_literal):
4873                # cache the constant slice object, in case we need it
4874                none_node = NoneNode(self.pos)
4875                self.slice = SliceNode(
4876                    self.pos,
4877                    start=copy.deepcopy(self.start or none_node),
4878                    stop=copy.deepcopy(self.stop or none_node),
4879                    step=none_node
4880                ).analyse_types(env)
4881        else:
4882            c_int = PyrexTypes.c_py_ssize_t_type
4883
4884            def allow_none(node, default_value, env):
4885                # Coerce to Py_ssize_t, but allow None as meaning the default slice bound.
4886                from .UtilNodes import EvalWithTempExprNode, ResultRefNode
4887
4888                node_ref = ResultRefNode(node)
4889                new_expr = CondExprNode(
4890                    node.pos,
4891                    true_val=IntNode(
4892                        node.pos,
4893                        type=c_int,
4894                        value=default_value,
4895                        constant_result=int(default_value) if default_value.isdigit() else not_a_constant,
4896                    ),
4897                    false_val=node_ref.coerce_to(c_int, env),
4898                    test=PrimaryCmpNode(
4899                        node.pos,
4900                        operand1=node_ref,
4901                        operator='is',
4902                        operand2=NoneNode(node.pos),
4903                    ).analyse_types(env)
4904                ).analyse_result_type(env)
4905                return EvalWithTempExprNode(node_ref, new_expr)
4906
4907            if self.start:
4908                if self.start.type.is_pyobject:
4909                    self.start = allow_none(self.start, '0', env)
4910                self.start = self.start.coerce_to(c_int, env)
4911            if self.stop:
4912                if self.stop.type.is_pyobject:
4913                    self.stop = allow_none(self.stop, 'PY_SSIZE_T_MAX', env)
4914                self.stop = self.stop.coerce_to(c_int, env)
4915        self.is_temp = 1
4916        return self
4917
4918    def analyse_as_type(self, env):
4919        base_type = self.base.analyse_as_type(env)
4920        if base_type and not base_type.is_pyobject:
4921            if not self.start and not self.stop:
4922                # memory view
4923                from . import MemoryView
4924                env.use_utility_code(MemoryView.view_utility_code)
4925                none_node = NoneNode(self.pos)
4926                slice_node = SliceNode(
4927                    self.pos,
4928                    start=none_node,
4929                    stop=none_node,
4930                    step=none_node,
4931                )
4932                return PyrexTypes.MemoryViewSliceType(
4933                    base_type, MemoryView.get_axes_specs(env, [slice_node]))
4934        return None
4935
4936    nogil_check = Node.gil_error
4937    gil_message = "Slicing Python object"
4938
4939    get_slice_utility_code = TempitaUtilityCode.load(
4940        "SliceObject", "ObjectHandling.c", context={'access': 'Get'})
4941
4942    set_slice_utility_code = TempitaUtilityCode.load(
4943        "SliceObject", "ObjectHandling.c", context={'access': 'Set'})
4944
4945    def coerce_to(self, dst_type, env):
4946        if ((self.base.type.is_string or self.base.type.is_cpp_string)
4947                and dst_type in (bytes_type, bytearray_type, str_type, unicode_type)):
4948            if (dst_type not in (bytes_type, bytearray_type)
4949                    and not env.directives['c_string_encoding']):
4950                error(self.pos,
4951                    "default encoding required for conversion from '%s' to '%s'" %
4952                    (self.base.type, dst_type))
4953            self.type = dst_type
4954        if dst_type.is_array and self.base.type.is_array:
4955            if not self.start and not self.stop:
4956                # redundant slice building, copy C arrays directly
4957                return self.base.coerce_to(dst_type, env)
4958            # else: check array size if possible
4959        return super(SliceIndexNode, self).coerce_to(dst_type, env)
4960
4961    def generate_result_code(self, code):
4962        if not self.type.is_pyobject:
4963            error(self.pos,
4964                  "Slicing is not currently supported for '%s'." % self.type)
4965            return
4966
4967        base_result = self.base.result()
4968        result = self.result()
4969        start_code = self.start_code()
4970        stop_code = self.stop_code()
4971        if self.base.type.is_string:
4972            base_result = self.base.result()
4973            if self.base.type not in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_const_char_ptr_type):
4974                base_result = '((const char*)%s)' % base_result
4975            if self.type is bytearray_type:
4976                type_name = 'ByteArray'
4977            else:
4978                type_name = self.type.name.title()
4979            if self.stop is None:
4980                code.putln(
4981                    "%s = __Pyx_Py%s_FromString(%s + %s); %s" % (
4982                        result,
4983                        type_name,
4984                        base_result,
4985                        start_code,
4986                        code.error_goto_if_null(result, self.pos)))
4987            else:
4988                code.putln(
4989                    "%s = __Pyx_Py%s_FromStringAndSize(%s + %s, %s - %s); %s" % (
4990                        result,
4991                        type_name,
4992                        base_result,
4993                        start_code,
4994                        stop_code,
4995                        start_code,
4996                        code.error_goto_if_null(result, self.pos)))
4997        elif self.base.type.is_pyunicode_ptr:
4998            base_result = self.base.result()
4999            if self.base.type != PyrexTypes.c_py_unicode_ptr_type:
5000                base_result = '((const Py_UNICODE*)%s)' % base_result
5001            if self.stop is None:
5002                code.putln(
5003                    "%s = __Pyx_PyUnicode_FromUnicode(%s + %s); %s" % (
5004                        result,
5005                        base_result,
5006                        start_code,
5007                        code.error_goto_if_null(result, self.pos)))
5008            else:
5009                code.putln(
5010                    "%s = __Pyx_PyUnicode_FromUnicodeAndLength(%s + %s, %s - %s); %s" % (
5011                        result,
5012                        base_result,
5013                        start_code,
5014                        stop_code,
5015                        start_code,
5016                        code.error_goto_if_null(result, self.pos)))
5017
5018        elif self.base.type is unicode_type:
5019            code.globalstate.use_utility_code(
5020                          UtilityCode.load_cached("PyUnicode_Substring", "StringTools.c"))
5021            code.putln(
5022                "%s = __Pyx_PyUnicode_Substring(%s, %s, %s); %s" % (
5023                    result,
5024                    base_result,
5025                    start_code,
5026                    stop_code,
5027                    code.error_goto_if_null(result, self.pos)))
5028        elif self.type is py_object_type:
5029            code.globalstate.use_utility_code(self.get_slice_utility_code)
5030            (has_c_start, has_c_stop, c_start, c_stop,
5031             py_start, py_stop, py_slice) = self.get_slice_config()
5032            code.putln(
5033                "%s = __Pyx_PyObject_GetSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d); %s" % (
5034                    result,
5035                    self.base.py_result(),
5036                    c_start, c_stop,
5037                    py_start, py_stop, py_slice,
5038                    has_c_start, has_c_stop,
5039                    bool(code.globalstate.directives['wraparound']),
5040                    code.error_goto_if_null(result, self.pos)))
5041        else:
5042            if self.base.type is list_type:
5043                code.globalstate.use_utility_code(
5044                    TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
5045                cfunc = '__Pyx_PyList_GetSlice'
5046            elif self.base.type is tuple_type:
5047                code.globalstate.use_utility_code(
5048                    TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
5049                cfunc = '__Pyx_PyTuple_GetSlice'
5050            else:
5051                cfunc = 'PySequence_GetSlice'
5052            code.putln(
5053                "%s = %s(%s, %s, %s); %s" % (
5054                    result,
5055                    cfunc,
5056                    self.base.py_result(),
5057                    start_code,
5058                    stop_code,
5059                    code.error_goto_if_null(result, self.pos)))
5060        code.put_gotref(self.py_result())
5061
5062    def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
5063        exception_check=None, exception_value=None):
5064        self.generate_subexpr_evaluation_code(code)
5065        if self.type.is_pyobject:
5066            code.globalstate.use_utility_code(self.set_slice_utility_code)
5067            (has_c_start, has_c_stop, c_start, c_stop,
5068             py_start, py_stop, py_slice) = self.get_slice_config()
5069            code.put_error_if_neg(self.pos,
5070                "__Pyx_PyObject_SetSlice(%s, %s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
5071                    self.base.py_result(),
5072                    rhs.py_result(),
5073                    c_start, c_stop,
5074                    py_start, py_stop, py_slice,
5075                    has_c_start, has_c_stop,
5076                    bool(code.globalstate.directives['wraparound'])))
5077        else:
5078            start_offset = self.start_code() if self.start else '0'
5079            if rhs.type.is_array:
5080                array_length = rhs.type.size
5081                self.generate_slice_guard_code(code, array_length)
5082            else:
5083                array_length = '%s - %s' % (self.stop_code(), start_offset)
5084
5085            code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
5086            code.putln("memcpy(&(%s[%s]), %s, sizeof(%s[0]) * (%s));" % (
5087                self.base.result(), start_offset,
5088                rhs.result(),
5089                self.base.result(), array_length
5090            ))
5091
5092        self.generate_subexpr_disposal_code(code)
5093        self.free_subexpr_temps(code)
5094        rhs.generate_disposal_code(code)
5095        rhs.free_temps(code)
5096
5097    def generate_deletion_code(self, code, ignore_nonexisting=False):
5098        if not self.base.type.is_pyobject:
5099            error(self.pos,
5100                  "Deleting slices is only supported for Python types, not '%s'." % self.type)
5101            return
5102        self.generate_subexpr_evaluation_code(code)
5103        code.globalstate.use_utility_code(self.set_slice_utility_code)
5104        (has_c_start, has_c_stop, c_start, c_stop,
5105         py_start, py_stop, py_slice) = self.get_slice_config()
5106        code.put_error_if_neg(self.pos,
5107            "__Pyx_PyObject_DelSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
5108                self.base.py_result(),
5109                c_start, c_stop,
5110                py_start, py_stop, py_slice,
5111                has_c_start, has_c_stop,
5112                bool(code.globalstate.directives['wraparound'])))
5113        self.generate_subexpr_disposal_code(code)
5114        self.free_subexpr_temps(code)
5115
5116    def get_slice_config(self):
5117        has_c_start, c_start, py_start = False, '0', 'NULL'
5118        if self.start:
5119            has_c_start = not self.start.type.is_pyobject
5120            if has_c_start:
5121                c_start = self.start.result()
5122            else:
5123                py_start = '&%s' % self.start.py_result()
5124        has_c_stop, c_stop, py_stop = False, '0', 'NULL'
5125        if self.stop:
5126            has_c_stop = not self.stop.type.is_pyobject
5127            if has_c_stop:
5128                c_stop = self.stop.result()
5129            else:
5130                py_stop = '&%s' % self.stop.py_result()
5131        py_slice = self.slice and '&%s' % self.slice.py_result() or 'NULL'
5132        return (has_c_start, has_c_stop, c_start, c_stop,
5133                py_start, py_stop, py_slice)
5134
5135    def generate_slice_guard_code(self, code, target_size):
5136        if not self.base.type.is_array:
5137            return
5138        slice_size = self.base.type.size
5139        try:
5140            total_length = slice_size = int(slice_size)
5141        except ValueError:
5142            total_length = None
5143
5144        start = stop = None
5145        if self.stop:
5146            stop = self.stop.result()
5147            try:
5148                stop = int(stop)
5149                if stop < 0:
5150                    if total_length is None:
5151                        slice_size = '%s + %d' % (slice_size, stop)
5152                    else:
5153                        slice_size += stop
5154                else:
5155                    slice_size = stop
5156                stop = None
5157            except ValueError:
5158                pass
5159
5160        if self.start:
5161            start = self.start.result()
5162            try:
5163                start = int(start)
5164                if start < 0:
5165                    if total_length is None:
5166                        start = '%s + %d' % (self.base.type.size, start)
5167                    else:
5168                        start += total_length
5169                if isinstance(slice_size, _py_int_types):
5170                    slice_size -= start
5171                else:
5172                    slice_size = '%s - (%s)' % (slice_size, start)
5173                start = None
5174            except ValueError:
5175                pass
5176
5177        runtime_check = None
5178        compile_time_check = False
5179        try:
5180            int_target_size = int(target_size)
5181        except ValueError:
5182            int_target_size = None
5183        else:
5184            compile_time_check = isinstance(slice_size, _py_int_types)
5185
5186        if compile_time_check and slice_size < 0:
5187            if int_target_size > 0:
5188                error(self.pos, "Assignment to empty slice.")
5189        elif compile_time_check and start is None and stop is None:
5190            # we know the exact slice length
5191            if int_target_size != slice_size:
5192                error(self.pos, "Assignment to slice of wrong length, expected %s, got %s" % (
5193                      slice_size, target_size))
5194        elif start is not None:
5195            if stop is None:
5196                stop = slice_size
5197            runtime_check = "(%s)-(%s)" % (stop, start)
5198        elif stop is not None:
5199            runtime_check = stop
5200        else:
5201            runtime_check = slice_size
5202
5203        if runtime_check:
5204            code.putln("if (unlikely((%s) != (%s))) {" % (runtime_check, target_size))
5205            code.putln(
5206                'PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length,'
5207                ' expected %%" CYTHON_FORMAT_SSIZE_T "d, got %%" CYTHON_FORMAT_SSIZE_T "d",'
5208                ' (Py_ssize_t)(%s), (Py_ssize_t)(%s));' % (
5209                    target_size, runtime_check))
5210            code.putln(code.error_goto(self.pos))
5211            code.putln("}")
5212
5213    def start_code(self):
5214        if self.start:
5215            return self.start.result()
5216        else:
5217            return "0"
5218
5219    def stop_code(self):
5220        if self.stop:
5221            return self.stop.result()
5222        elif self.base.type.is_array:
5223            return self.base.type.size
5224        else:
5225            return "PY_SSIZE_T_MAX"
5226
5227    def calculate_result_code(self):
5228        # self.result() is not used, but this method must exist
5229        return "<unused>"
5230
5231
5232class SliceNode(ExprNode):
5233    #  start:stop:step in subscript list
5234    #
5235    #  start     ExprNode
5236    #  stop      ExprNode
5237    #  step      ExprNode
5238
5239    subexprs = ['start', 'stop', 'step']
5240    is_slice = True
5241    type = slice_type
5242    is_temp = 1
5243
5244    def calculate_constant_result(self):
5245        self.constant_result = slice(
5246            self.start.constant_result,
5247            self.stop.constant_result,
5248            self.step.constant_result)
5249
5250    def compile_time_value(self, denv):
5251        start = self.start.compile_time_value(denv)
5252        stop = self.stop.compile_time_value(denv)
5253        step = self.step.compile_time_value(denv)
5254        try:
5255            return slice(start, stop, step)
5256        except Exception as e:
5257            self.compile_time_value_error(e)
5258
5259    def may_be_none(self):
5260        return False
5261
5262    def analyse_types(self, env):
5263        start = self.start.analyse_types(env)
5264        stop = self.stop.analyse_types(env)
5265        step = self.step.analyse_types(env)
5266        self.start = start.coerce_to_pyobject(env)
5267        self.stop = stop.coerce_to_pyobject(env)
5268        self.step = step.coerce_to_pyobject(env)
5269        if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
5270            self.is_literal = True
5271            self.is_temp = False
5272        return self
5273
5274    gil_message = "Constructing Python slice object"
5275
5276    def calculate_result_code(self):
5277        return self.result_code
5278
5279    def generate_result_code(self, code):
5280        if self.is_literal:
5281            dedup_key = make_dedup_key(self.type, (self,))
5282            self.result_code = code.get_py_const(py_object_type, 'slice', cleanup_level=2, dedup_key=dedup_key)
5283            code = code.get_cached_constants_writer(self.result_code)
5284            if code is None:
5285                return  # already initialised
5286            code.mark_pos(self.pos)
5287
5288        code.putln(
5289            "%s = PySlice_New(%s, %s, %s); %s" % (
5290                self.result(),
5291                self.start.py_result(),
5292                self.stop.py_result(),
5293                self.step.py_result(),
5294                code.error_goto_if_null(self.result(), self.pos)))
5295        code.put_gotref(self.py_result())
5296        if self.is_literal:
5297            code.put_giveref(self.py_result())
5298
5299class SliceIntNode(SliceNode):
5300    #  start:stop:step in subscript list
5301    # This is just a node to hold start,stop and step nodes that can be
5302    # converted to integers. This does not generate a slice python object.
5303    #
5304    #  start     ExprNode
5305    #  stop      ExprNode
5306    #  step      ExprNode
5307
5308    is_temp = 0
5309
5310    def calculate_constant_result(self):
5311        self.constant_result = slice(
5312            self.start.constant_result,
5313            self.stop.constant_result,
5314            self.step.constant_result)
5315
5316    def compile_time_value(self, denv):
5317        start = self.start.compile_time_value(denv)
5318        stop = self.stop.compile_time_value(denv)
5319        step = self.step.compile_time_value(denv)
5320        try:
5321            return slice(start, stop, step)
5322        except Exception as e:
5323            self.compile_time_value_error(e)
5324
5325    def may_be_none(self):
5326        return False
5327
5328    def analyse_types(self, env):
5329        self.start = self.start.analyse_types(env)
5330        self.stop = self.stop.analyse_types(env)
5331        self.step = self.step.analyse_types(env)
5332
5333        if not self.start.is_none:
5334            self.start = self.start.coerce_to_integer(env)
5335        if not self.stop.is_none:
5336            self.stop = self.stop.coerce_to_integer(env)
5337        if not self.step.is_none:
5338            self.step = self.step.coerce_to_integer(env)
5339
5340        if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
5341            self.is_literal = True
5342            self.is_temp = False
5343        return self
5344
5345    def calculate_result_code(self):
5346        pass
5347
5348    def generate_result_code(self, code):
5349        for a in self.start,self.stop,self.step:
5350            if isinstance(a, CloneNode):
5351                a.arg.result()
5352
5353
5354class CallNode(ExprNode):
5355
5356    # allow overriding the default 'may_be_none' behaviour
5357    may_return_none = None
5358
5359    def infer_type(self, env):
5360        # TODO(robertwb): Reduce redundancy with analyse_types.
5361        function = self.function
5362        func_type = function.infer_type(env)
5363        if isinstance(function, NewExprNode):
5364            # note: needs call to infer_type() above
5365            return PyrexTypes.CPtrType(function.class_type)
5366        if func_type is py_object_type:
5367            # function might have lied for safety => try to find better type
5368            entry = getattr(function, 'entry', None)
5369            if entry is not None:
5370                func_type = entry.type or func_type
5371        if func_type.is_ptr:
5372            func_type = func_type.base_type
5373        if func_type.is_cfunction:
5374            if getattr(self.function, 'entry', None) and hasattr(self, 'args'):
5375                alternatives = self.function.entry.all_alternatives()
5376                arg_types = [arg.infer_type(env) for arg in self.args]
5377                func_entry = PyrexTypes.best_match(arg_types, alternatives)
5378                if func_entry:
5379                    func_type = func_entry.type
5380                    if func_type.is_ptr:
5381                        func_type = func_type.base_type
5382                    return func_type.return_type
5383            return func_type.return_type
5384        elif func_type is type_type:
5385            if function.is_name and function.entry and function.entry.type:
5386                result_type = function.entry.type
5387                if result_type.is_extension_type:
5388                    return result_type
5389                elif result_type.is_builtin_type:
5390                    if function.entry.name == 'float':
5391                        return PyrexTypes.c_double_type
5392                    elif function.entry.name in Builtin.types_that_construct_their_instance:
5393                        return result_type
5394        return py_object_type
5395
5396    def type_dependencies(self, env):
5397        # TODO: Update when Danilo's C++ code merged in to handle the
5398        # the case of function overloading.
5399        return self.function.type_dependencies(env)
5400
5401    def is_simple(self):
5402        # C function calls could be considered simple, but they may
5403        # have side-effects that may hit when multiple operations must
5404        # be effected in order, e.g. when constructing the argument
5405        # sequence for a function call or comparing values.
5406        return False
5407
5408    def may_be_none(self):
5409        if self.may_return_none is not None:
5410            return self.may_return_none
5411        func_type = self.function.type
5412        if func_type is type_type and self.function.is_name:
5413            entry = self.function.entry
5414            if entry.type.is_extension_type:
5415                return False
5416            if (entry.type.is_builtin_type and
5417                    entry.name in Builtin.types_that_construct_their_instance):
5418                return False
5419        return ExprNode.may_be_none(self)
5420
5421    def set_py_result_type(self, function, func_type=None):
5422        if func_type is None:
5423            func_type = function.type
5424        if func_type is Builtin.type_type and (
5425                function.is_name and
5426                function.entry and
5427                function.entry.is_builtin and
5428                function.entry.name in Builtin.types_that_construct_their_instance):
5429            # calling a builtin type that returns a specific object type
5430            if function.entry.name == 'float':
5431                # the following will come true later on in a transform
5432                self.type = PyrexTypes.c_double_type
5433                self.result_ctype = PyrexTypes.c_double_type
5434            else:
5435                self.type = Builtin.builtin_types[function.entry.name]
5436                self.result_ctype = py_object_type
5437            self.may_return_none = False
5438        elif function.is_name and function.type_entry:
5439            # We are calling an extension type constructor.  As long as we do not
5440            # support __new__(), the result type is clear
5441            self.type = function.type_entry.type
5442            self.result_ctype = py_object_type
5443            self.may_return_none = False
5444        else:
5445            self.type = py_object_type
5446
5447    def analyse_as_type_constructor(self, env):
5448        type = self.function.analyse_as_type(env)
5449        if type and type.is_struct_or_union:
5450            args, kwds = self.explicit_args_kwds()
5451            items = []
5452            for arg, member in zip(args, type.scope.var_entries):
5453                items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
5454            if kwds:
5455                items += kwds.key_value_pairs
5456            self.key_value_pairs = items
5457            self.__class__ = DictNode
5458            self.analyse_types(env)    # FIXME
5459            self.coerce_to(type, env)
5460            return True
5461        elif type and type.is_cpp_class:
5462            self.args = [ arg.analyse_types(env) for arg in self.args ]
5463            constructor = type.scope.lookup("<init>")
5464            if not constructor:
5465                error(self.function.pos, "no constructor found for C++  type '%s'" % self.function.name)
5466                self.type = error_type
5467                return self
5468            self.function = RawCNameExprNode(self.function.pos, constructor.type)
5469            self.function.entry = constructor
5470            self.function.set_cname(type.empty_declaration_code())
5471            self.analyse_c_function_call(env)
5472            self.type = type
5473            return True
5474
5475    def is_lvalue(self):
5476        return self.type.is_reference
5477
5478    def nogil_check(self, env):
5479        func_type = self.function_type()
5480        if func_type.is_pyobject:
5481            self.gil_error()
5482        elif not func_type.is_error and not getattr(func_type, 'nogil', False):
5483            self.gil_error()
5484
5485    gil_message = "Calling gil-requiring function"
5486
5487
5488class SimpleCallNode(CallNode):
5489    #  Function call without keyword, * or ** args.
5490    #
5491    #  function       ExprNode
5492    #  args           [ExprNode]
5493    #  arg_tuple      ExprNode or None     used internally
5494    #  self           ExprNode or None     used internally
5495    #  coerced_self   ExprNode or None     used internally
5496    #  wrapper_call   bool                 used internally
5497    #  has_optional_args   bool            used internally
5498    #  nogil          bool                 used internally
5499
5500    subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
5501
5502    self = None
5503    coerced_self = None
5504    arg_tuple = None
5505    wrapper_call = False
5506    has_optional_args = False
5507    nogil = False
5508    analysed = False
5509    overflowcheck = False
5510
5511    def compile_time_value(self, denv):
5512        function = self.function.compile_time_value(denv)
5513        args = [arg.compile_time_value(denv) for arg in self.args]
5514        try:
5515            return function(*args)
5516        except Exception as e:
5517            self.compile_time_value_error(e)
5518
5519    def analyse_as_type(self, env):
5520        attr = self.function.as_cython_attribute()
5521        if attr == 'pointer':
5522            if len(self.args) != 1:
5523                error(self.args.pos, "only one type allowed.")
5524            else:
5525                type = self.args[0].analyse_as_type(env)
5526                if not type:
5527                    error(self.args[0].pos, "Unknown type")
5528                else:
5529                    return PyrexTypes.CPtrType(type)
5530        elif attr == 'typeof':
5531            if len(self.args) != 1:
5532                error(self.args.pos, "only one type allowed.")
5533            operand = self.args[0].analyse_types(env)
5534            return operand.type
5535
5536    def explicit_args_kwds(self):
5537        return self.args, None
5538
5539    def analyse_types(self, env):
5540        if self.analyse_as_type_constructor(env):
5541            return self
5542        if self.analysed:
5543            return self
5544        self.analysed = True
5545        self.function.is_called = 1
5546        self.function = self.function.analyse_types(env)
5547        function = self.function
5548
5549        if function.is_attribute and function.entry and function.entry.is_cmethod:
5550            # Take ownership of the object from which the attribute
5551            # was obtained, because we need to pass it as 'self'.
5552            self.self = function.obj
5553            function.obj = CloneNode(self.self)
5554
5555        func_type = self.function_type()
5556        self.is_numpy_call_with_exprs = False
5557        if (has_np_pythran(env) and function.is_numpy_attribute and
5558                pythran_is_numpy_func_supported(function)):
5559            has_pythran_args = True
5560            self.arg_tuple = TupleNode(self.pos, args = self.args)
5561            self.arg_tuple = self.arg_tuple.analyse_types(env)
5562            for arg in self.arg_tuple.args:
5563                has_pythran_args &= is_pythran_supported_node_or_none(arg)
5564            self.is_numpy_call_with_exprs = bool(has_pythran_args)
5565        if self.is_numpy_call_with_exprs:
5566            env.add_include_file(pythran_get_func_include_file(function))
5567            return NumPyMethodCallNode.from_node(
5568                self,
5569                function_cname=pythran_functor(function),
5570                arg_tuple=self.arg_tuple,
5571                type=PythranExpr(pythran_func_type(function, self.arg_tuple.args)),
5572            )
5573        elif func_type.is_pyobject:
5574            self.arg_tuple = TupleNode(self.pos, args = self.args)
5575            self.arg_tuple = self.arg_tuple.analyse_types(env).coerce_to_pyobject(env)
5576            self.args = None
5577            self.set_py_result_type(function, func_type)
5578            self.is_temp = 1
5579        else:
5580            self.args = [ arg.analyse_types(env) for arg in self.args ]
5581            self.analyse_c_function_call(env)
5582            if func_type.exception_check == '+':
5583                self.is_temp = True
5584        return self
5585
5586    def function_type(self):
5587        # Return the type of the function being called, coercing a function
5588        # pointer to a function if necessary. If the function has fused
5589        # arguments, return the specific type.
5590        func_type = self.function.type
5591
5592        if func_type.is_ptr:
5593            func_type = func_type.base_type
5594
5595        return func_type
5596
5597    def analyse_c_function_call(self, env):
5598        func_type = self.function.type
5599        if func_type is error_type:
5600            self.type = error_type
5601            return
5602
5603        if func_type.is_cfunction and func_type.is_static_method:
5604            if self.self and self.self.type.is_extension_type:
5605                # To support this we'd need to pass self to determine whether
5606                # it was overloaded in Python space (possibly via a Cython
5607                # superclass turning a cdef method into a cpdef one).
5608                error(self.pos, "Cannot call a static method on an instance variable.")
5609            args = self.args
5610        elif self.self:
5611            args = [self.self] + self.args
5612        else:
5613            args = self.args
5614
5615        if func_type.is_cpp_class:
5616            overloaded_entry = self.function.type.scope.lookup("operator()")
5617            if overloaded_entry is None:
5618                self.type = PyrexTypes.error_type
5619                self.result_code = "<error>"
5620                return
5621        elif hasattr(self.function, 'entry'):
5622            overloaded_entry = self.function.entry
5623        elif self.function.is_subscript and self.function.is_fused_index:
5624            overloaded_entry = self.function.type.entry
5625        else:
5626            overloaded_entry = None
5627
5628        if overloaded_entry:
5629            if self.function.type.is_fused:
5630                functypes = self.function.type.get_all_specialized_function_types()
5631                alternatives = [f.entry for f in functypes]
5632            else:
5633                alternatives = overloaded_entry.all_alternatives()
5634
5635            entry = PyrexTypes.best_match(
5636                [arg.type for arg in args], alternatives, self.pos, env, args)
5637
5638            if not entry:
5639                self.type = PyrexTypes.error_type
5640                self.result_code = "<error>"
5641                return
5642
5643            entry.used = True
5644            if not func_type.is_cpp_class:
5645                self.function.entry = entry
5646            self.function.type = entry.type
5647            func_type = self.function_type()
5648        else:
5649            entry = None
5650            func_type = self.function_type()
5651            if not func_type.is_cfunction:
5652                error(self.pos, "Calling non-function type '%s'" % func_type)
5653                self.type = PyrexTypes.error_type
5654                self.result_code = "<error>"
5655                return
5656
5657        # Check no. of args
5658        max_nargs = len(func_type.args)
5659        expected_nargs = max_nargs - func_type.optional_arg_count
5660        actual_nargs = len(args)
5661        if func_type.optional_arg_count and expected_nargs != actual_nargs:
5662            self.has_optional_args = 1
5663            self.is_temp = 1
5664
5665        # check 'self' argument
5666        if entry and entry.is_cmethod and func_type.args and not func_type.is_static_method:
5667            formal_arg = func_type.args[0]
5668            arg = args[0]
5669            if formal_arg.not_none:
5670                if self.self:
5671                    self.self = self.self.as_none_safe_node(
5672                        "'NoneType' object has no attribute '%{0}s'".format('.30' if len(entry.name) <= 30 else ''),
5673                        error='PyExc_AttributeError',
5674                        format_args=[entry.name])
5675                else:
5676                    # unbound method
5677                    arg = arg.as_none_safe_node(
5678                        "descriptor '%s' requires a '%s' object but received a 'NoneType'",
5679                        format_args=[entry.name, formal_arg.type.name])
5680            if self.self:
5681                if formal_arg.accept_builtin_subtypes:
5682                    arg = CMethodSelfCloneNode(self.self)
5683                else:
5684                    arg = CloneNode(self.self)
5685                arg = self.coerced_self = arg.coerce_to(formal_arg.type, env)
5686            elif formal_arg.type.is_builtin_type:
5687                # special case: unbound methods of builtins accept subtypes
5688                arg = arg.coerce_to(formal_arg.type, env)
5689                if arg.type.is_builtin_type and isinstance(arg, PyTypeTestNode):
5690                    arg.exact_builtin_type = False
5691            args[0] = arg
5692
5693        # Coerce arguments
5694        some_args_in_temps = False
5695        for i in range(min(max_nargs, actual_nargs)):
5696            formal_arg = func_type.args[i]
5697            formal_type = formal_arg.type
5698            arg = args[i].coerce_to(formal_type, env)
5699            if formal_arg.not_none:
5700                # C methods must do the None checks at *call* time
5701                arg = arg.as_none_safe_node(
5702                    "cannot pass None into a C function argument that is declared 'not None'")
5703            if arg.is_temp:
5704                if i > 0:
5705                    # first argument in temp doesn't impact subsequent arguments
5706                    some_args_in_temps = True
5707            elif arg.type.is_pyobject and not env.nogil:
5708                if i == 0 and self.self is not None:
5709                    # a method's cloned "self" argument is ok
5710                    pass
5711                elif arg.nonlocally_immutable():
5712                    # plain local variables are ok
5713                    pass
5714                else:
5715                    # we do not safely own the argument's reference,
5716                    # but we must make sure it cannot be collected
5717                    # before we return from the function, so we create
5718                    # an owned temp reference to it
5719                    if i > 0: # first argument doesn't matter
5720                        some_args_in_temps = True
5721                    arg = arg.coerce_to_temp(env)
5722            args[i] = arg
5723
5724        # handle additional varargs parameters
5725        for i in range(max_nargs, actual_nargs):
5726            arg = args[i]
5727            if arg.type.is_pyobject:
5728                if arg.type is str_type:
5729                    arg_ctype = PyrexTypes.c_char_ptr_type
5730                else:
5731                    arg_ctype = arg.type.default_coerced_ctype()
5732                if arg_ctype is None:
5733                    error(self.args[i].pos,
5734                          "Python object cannot be passed as a varargs parameter")
5735                else:
5736                    args[i] = arg = arg.coerce_to(arg_ctype, env)
5737            if arg.is_temp and i > 0:
5738                some_args_in_temps = True
5739
5740        if some_args_in_temps:
5741            # if some args are temps and others are not, they may get
5742            # constructed in the wrong order (temps first) => make
5743            # sure they are either all temps or all not temps (except
5744            # for the last argument, which is evaluated last in any
5745            # case)
5746            for i in range(actual_nargs-1):
5747                if i == 0 and self.self is not None:
5748                    continue # self is ok
5749                arg = args[i]
5750                if arg.nonlocally_immutable():
5751                    # locals, C functions, unassignable types are safe.
5752                    pass
5753                elif arg.type.is_cpp_class:
5754                    # Assignment has side effects, avoid.
5755                    pass
5756                elif env.nogil and arg.type.is_pyobject:
5757                    # can't copy a Python reference into a temp in nogil
5758                    # env (this is safe: a construction would fail in
5759                    # nogil anyway)
5760                    pass
5761                else:
5762                    #self.args[i] = arg.coerce_to_temp(env)
5763                    # instead: issue a warning
5764                    if i > 0 or i == 1 and self.self is not None: # skip first arg
5765                        warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
5766                        break
5767
5768        self.args[:] = args
5769
5770        # Calc result type and code fragment
5771        if isinstance(self.function, NewExprNode):
5772            self.type = PyrexTypes.CPtrType(self.function.class_type)
5773        else:
5774            self.type = func_type.return_type
5775
5776        if self.function.is_name or self.function.is_attribute:
5777            func_entry = self.function.entry
5778            if func_entry and (func_entry.utility_code or func_entry.utility_code_definition):
5779                self.is_temp = 1  # currently doesn't work for self.calculate_result_code()
5780
5781        if self.type.is_pyobject:
5782            self.result_ctype = py_object_type
5783            self.is_temp = 1
5784        elif func_type.exception_value is not None or func_type.exception_check:
5785            self.is_temp = 1
5786        elif self.type.is_memoryviewslice:
5787            self.is_temp = 1
5788            # func_type.exception_check = True
5789
5790        if self.is_temp and self.type.is_reference:
5791            self.type = PyrexTypes.CFakeReferenceType(self.type.ref_base_type)
5792
5793        # Called in 'nogil' context?
5794        self.nogil = env.nogil
5795        if (self.nogil and
5796            func_type.exception_check and
5797            func_type.exception_check != '+'):
5798            env.use_utility_code(pyerr_occurred_withgil_utility_code)
5799        # C++ exception handler
5800        if func_type.exception_check == '+':
5801            if func_type.exception_value is None:
5802                env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
5803
5804        self.overflowcheck = env.directives['overflowcheck']
5805
5806    def calculate_result_code(self):
5807        return self.c_call_code()
5808
5809    def c_call_code(self):
5810        func_type = self.function_type()
5811        if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
5812            return "<error>"
5813        formal_args = func_type.args
5814        arg_list_code = []
5815        args = list(zip(formal_args, self.args))
5816        max_nargs = len(func_type.args)
5817        expected_nargs = max_nargs - func_type.optional_arg_count
5818        actual_nargs = len(self.args)
5819        for formal_arg, actual_arg in args[:expected_nargs]:
5820                arg_code = actual_arg.result_as(formal_arg.type)
5821                arg_list_code.append(arg_code)
5822
5823        if func_type.is_overridable:
5824            arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
5825
5826        if func_type.optional_arg_count:
5827            if expected_nargs == actual_nargs:
5828                optional_args = 'NULL'
5829            else:
5830                optional_args = "&%s" % self.opt_arg_struct
5831            arg_list_code.append(optional_args)
5832
5833        for actual_arg in self.args[len(formal_args):]:
5834            arg_list_code.append(actual_arg.result())
5835
5836        result = "%s(%s)" % (self.function.result(), ', '.join(arg_list_code))
5837        return result
5838
5839    def is_c_result_required(self):
5840        func_type = self.function_type()
5841        if not func_type.exception_value or func_type.exception_check == '+':
5842            return False  # skip allocation of unused result temp
5843        return True
5844
5845    def generate_evaluation_code(self, code):
5846        function = self.function
5847        if function.is_name or function.is_attribute:
5848            code.globalstate.use_entry_utility_code(function.entry)
5849
5850        abs_function_cnames = ('abs', 'labs', '__Pyx_abs_longlong')
5851        is_signed_int = self.type.is_int and self.type.signed
5852        if self.overflowcheck and is_signed_int and function.result() in abs_function_cnames:
5853            code.globalstate.use_utility_code(UtilityCode.load_cached("Common", "Overflow.c"))
5854            code.putln('if (unlikely(%s == __PYX_MIN(%s))) {\
5855                PyErr_SetString(PyExc_OverflowError,\
5856                                "Trying to take the absolute value of the most negative integer is not defined."); %s; }' % (
5857                            self.args[0].result(),
5858                            self.args[0].type.empty_declaration_code(),
5859                            code.error_goto(self.pos)))
5860
5861        if not function.type.is_pyobject or len(self.arg_tuple.args) > 1 or (
5862                self.arg_tuple.args and self.arg_tuple.is_literal):
5863            super(SimpleCallNode, self).generate_evaluation_code(code)
5864            return
5865
5866        # Special case 0-args and try to avoid explicit tuple creation for Python calls with 1 arg.
5867        arg = self.arg_tuple.args[0] if self.arg_tuple.args else None
5868        subexprs = (self.self, self.coerced_self, function, arg)
5869        for subexpr in subexprs:
5870            if subexpr is not None:
5871                subexpr.generate_evaluation_code(code)
5872
5873        code.mark_pos(self.pos)
5874        assert self.is_temp
5875        self.allocate_temp_result(code)
5876
5877        if arg is None:
5878            code.globalstate.use_utility_code(UtilityCode.load_cached(
5879                "PyObjectCallNoArg", "ObjectHandling.c"))
5880            code.putln(
5881                "%s = __Pyx_PyObject_CallNoArg(%s); %s" % (
5882                    self.result(),
5883                    function.py_result(),
5884                    code.error_goto_if_null(self.result(), self.pos)))
5885        else:
5886            code.globalstate.use_utility_code(UtilityCode.load_cached(
5887                "PyObjectCallOneArg", "ObjectHandling.c"))
5888            code.putln(
5889                "%s = __Pyx_PyObject_CallOneArg(%s, %s); %s" % (
5890                    self.result(),
5891                    function.py_result(),
5892                    arg.py_result(),
5893                    code.error_goto_if_null(self.result(), self.pos)))
5894
5895        code.put_gotref(self.py_result())
5896
5897        for subexpr in subexprs:
5898            if subexpr is not None:
5899                subexpr.generate_disposal_code(code)
5900                subexpr.free_temps(code)
5901
5902    def generate_result_code(self, code):
5903        func_type = self.function_type()
5904        if func_type.is_pyobject:
5905            arg_code = self.arg_tuple.py_result()
5906            code.globalstate.use_utility_code(UtilityCode.load_cached(
5907                "PyObjectCall", "ObjectHandling.c"))
5908            code.putln(
5909                "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
5910                    self.result(),
5911                    self.function.py_result(),
5912                    arg_code,
5913                    code.error_goto_if_null(self.result(), self.pos)))
5914            code.put_gotref(self.py_result())
5915        elif func_type.is_cfunction:
5916            if self.has_optional_args:
5917                actual_nargs = len(self.args)
5918                expected_nargs = len(func_type.args) - func_type.optional_arg_count
5919                self.opt_arg_struct = code.funcstate.allocate_temp(
5920                    func_type.op_arg_struct.base_type, manage_ref=True)
5921                code.putln("%s.%s = %s;" % (
5922                        self.opt_arg_struct,
5923                        Naming.pyrex_prefix + "n",
5924                        len(self.args) - expected_nargs))
5925                args = list(zip(func_type.args, self.args))
5926                for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
5927                    code.putln("%s.%s = %s;" % (
5928                            self.opt_arg_struct,
5929                            func_type.opt_arg_cname(formal_arg.name),
5930                            actual_arg.result_as(formal_arg.type)))
5931            exc_checks = []
5932            if self.type.is_pyobject and self.is_temp:
5933                exc_checks.append("!%s" % self.result())
5934            elif self.type.is_memoryviewslice:
5935                assert self.is_temp
5936                exc_checks.append(self.type.error_condition(self.result()))
5937            elif func_type.exception_check != '+':
5938                exc_val = func_type.exception_value
5939                exc_check = func_type.exception_check
5940                if exc_val is not None:
5941                    exc_checks.append("%s == %s" % (self.result(), func_type.return_type.cast_code(exc_val)))
5942                if exc_check:
5943                    if self.nogil:
5944                        exc_checks.append("__Pyx_ErrOccurredWithGIL()")
5945                    else:
5946                        exc_checks.append("PyErr_Occurred()")
5947            if self.is_temp or exc_checks:
5948                rhs = self.c_call_code()
5949                if self.result():
5950                    lhs = "%s = " % self.result()
5951                    if self.is_temp and self.type.is_pyobject:
5952                        #return_type = self.type # func_type.return_type
5953                        #print "SimpleCallNode.generate_result_code: casting", rhs, \
5954                        #    "from", return_type, "to pyobject" ###
5955                        rhs = typecast(py_object_type, self.type, rhs)
5956                else:
5957                    lhs = ""
5958                if func_type.exception_check == '+':
5959                    translate_cpp_exception(code, self.pos, '%s%s;' % (lhs, rhs),
5960                                            self.result() if self.type.is_pyobject else None,
5961                                            func_type.exception_value, self.nogil)
5962                else:
5963                    if exc_checks:
5964                        goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
5965                    else:
5966                        goto_error = ""
5967                    code.putln("%s%s; %s" % (lhs, rhs, goto_error))
5968                if self.type.is_pyobject and self.result():
5969                    code.put_gotref(self.py_result())
5970            if self.has_optional_args:
5971                code.funcstate.release_temp(self.opt_arg_struct)
5972
5973
5974class NumPyMethodCallNode(ExprNode):
5975    # Pythran call to a NumPy function or method.
5976    #
5977    # function_cname  string      the function/method to call
5978    # arg_tuple       TupleNode   the arguments as an args tuple
5979
5980    subexprs = ['arg_tuple']
5981    is_temp = True
5982    may_return_none = True
5983
5984    def generate_evaluation_code(self, code):
5985        code.mark_pos(self.pos)
5986        self.allocate_temp_result(code)
5987
5988        assert self.arg_tuple.mult_factor is None
5989        args = self.arg_tuple.args
5990        for arg in args:
5991            arg.generate_evaluation_code(code)
5992
5993        code.putln("// function evaluation code for numpy function")
5994        code.putln("__Pyx_call_destructor(%s);" % self.result())
5995        code.putln("new (&%s) decltype(%s){%s{}(%s)};" % (
5996            self.result(),
5997            self.result(),
5998            self.function_cname,
5999            ", ".join(a.pythran_result() for a in args)))
6000
6001
6002class PyMethodCallNode(SimpleCallNode):
6003    # Specialised call to a (potential) PyMethodObject with non-constant argument tuple.
6004    # Allows the self argument to be injected directly instead of repacking a tuple for it.
6005    #
6006    # function    ExprNode      the function/method object to call
6007    # arg_tuple   TupleNode     the arguments for the args tuple
6008
6009    subexprs = ['function', 'arg_tuple']
6010    is_temp = True
6011
6012    def generate_evaluation_code(self, code):
6013        code.mark_pos(self.pos)
6014        self.allocate_temp_result(code)
6015
6016        self.function.generate_evaluation_code(code)
6017        assert self.arg_tuple.mult_factor is None
6018        args = self.arg_tuple.args
6019        for arg in args:
6020            arg.generate_evaluation_code(code)
6021
6022        # make sure function is in temp so that we can replace the reference below if it's a method
6023        reuse_function_temp = self.function.is_temp
6024        if reuse_function_temp:
6025            function = self.function.result()
6026        else:
6027            function = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
6028            self.function.make_owned_reference(code)
6029            code.put("%s = %s; " % (function, self.function.py_result()))
6030            self.function.generate_disposal_code(code)
6031            self.function.free_temps(code)
6032
6033        self_arg = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
6034        code.putln("%s = NULL;" % self_arg)
6035        arg_offset_cname = None
6036        if len(args) > 1:
6037            arg_offset_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
6038            code.putln("%s = 0;" % arg_offset_cname)
6039
6040        def attribute_is_likely_method(attr):
6041            obj = attr.obj
6042            if obj.is_name and obj.entry.is_pyglobal:
6043                return False  # more likely to be a function
6044            return True
6045
6046        if self.function.is_attribute:
6047            likely_method = 'likely' if attribute_is_likely_method(self.function) else 'unlikely'
6048        elif self.function.is_name and self.function.cf_state:
6049            # not an attribute itself, but might have been assigned from one (e.g. bound method)
6050            for assignment in self.function.cf_state:
6051                value = assignment.rhs
6052                if value and value.is_attribute and value.obj.type and value.obj.type.is_pyobject:
6053                    if attribute_is_likely_method(value):
6054                        likely_method = 'likely'
6055                        break
6056            else:
6057                likely_method = 'unlikely'
6058        else:
6059            likely_method = 'unlikely'
6060
6061        code.putln("if (CYTHON_UNPACK_METHODS && %s(PyMethod_Check(%s))) {" % (likely_method, function))
6062        code.putln("%s = PyMethod_GET_SELF(%s);" % (self_arg, function))
6063        # the following is always true in Py3 (kept only for safety),
6064        # but is false for unbound methods in Py2
6065        code.putln("if (likely(%s)) {" % self_arg)
6066        code.putln("PyObject* function = PyMethod_GET_FUNCTION(%s);" % function)
6067        code.put_incref(self_arg, py_object_type)
6068        code.put_incref("function", py_object_type)
6069        # free method object as early to possible to enable reuse from CPython's freelist
6070        code.put_decref_set(function, "function")
6071        if len(args) > 1:
6072            code.putln("%s = 1;" % arg_offset_cname)
6073        code.putln("}")
6074        code.putln("}")
6075
6076        if not args:
6077            # fastest special case: try to avoid tuple creation
6078            code.globalstate.use_utility_code(
6079                UtilityCode.load_cached("PyObjectCallNoArg", "ObjectHandling.c"))
6080            code.globalstate.use_utility_code(
6081                UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
6082            code.putln(
6083                "%s = (%s) ? __Pyx_PyObject_CallOneArg(%s, %s) : __Pyx_PyObject_CallNoArg(%s);" % (
6084                    self.result(), self_arg,
6085                    function, self_arg,
6086                    function))
6087            code.put_xdecref_clear(self_arg, py_object_type)
6088            code.funcstate.release_temp(self_arg)
6089            code.putln(code.error_goto_if_null(self.result(), self.pos))
6090            code.put_gotref(self.py_result())
6091        elif len(args) == 1:
6092            # fastest special case: try to avoid tuple creation
6093            code.globalstate.use_utility_code(
6094                UtilityCode.load_cached("PyObjectCall2Args", "ObjectHandling.c"))
6095            code.globalstate.use_utility_code(
6096                UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
6097            arg = args[0]
6098            code.putln(
6099                "%s = (%s) ? __Pyx_PyObject_Call2Args(%s, %s, %s) : __Pyx_PyObject_CallOneArg(%s, %s);" % (
6100                    self.result(), self_arg,
6101                    function, self_arg, arg.py_result(),
6102                    function, arg.py_result()))
6103            code.put_xdecref_clear(self_arg, py_object_type)
6104            code.funcstate.release_temp(self_arg)
6105            arg.generate_disposal_code(code)
6106            arg.free_temps(code)
6107            code.putln(code.error_goto_if_null(self.result(), self.pos))
6108            code.put_gotref(self.py_result())
6109        else:
6110            code.globalstate.use_utility_code(
6111                UtilityCode.load_cached("PyFunctionFastCall", "ObjectHandling.c"))
6112            code.globalstate.use_utility_code(
6113                UtilityCode.load_cached("PyCFunctionFastCall", "ObjectHandling.c"))
6114            for test_func, call_prefix in [('PyFunction_Check', 'Py'), ('__Pyx_PyFastCFunction_Check', 'PyC')]:
6115                code.putln("#if CYTHON_FAST_%sCALL" % call_prefix.upper())
6116                code.putln("if (%s(%s)) {" % (test_func, function))
6117                code.putln("PyObject *%s[%d] = {%s, %s};" % (
6118                    Naming.quick_temp_cname,
6119                    len(args)+1,
6120                    self_arg,
6121                    ', '.join(arg.py_result() for arg in args)))
6122                code.putln("%s = __Pyx_%sFunction_FastCall(%s, %s+1-%s, %d+%s); %s" % (
6123                    self.result(),
6124                    call_prefix,
6125                    function,
6126                    Naming.quick_temp_cname,
6127                    arg_offset_cname,
6128                    len(args),
6129                    arg_offset_cname,
6130                    code.error_goto_if_null(self.result(), self.pos)))
6131                code.put_xdecref_clear(self_arg, py_object_type)
6132                code.put_gotref(self.py_result())
6133                for arg in args:
6134                    arg.generate_disposal_code(code)
6135                code.putln("} else")
6136                code.putln("#endif")
6137
6138            code.putln("{")
6139            args_tuple = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
6140            code.putln("%s = PyTuple_New(%d+%s); %s" % (
6141                args_tuple, len(args), arg_offset_cname,
6142                code.error_goto_if_null(args_tuple, self.pos)))
6143            code.put_gotref(args_tuple)
6144
6145            if len(args) > 1:
6146                code.putln("if (%s) {" % self_arg)
6147            code.putln("__Pyx_GIVEREF(%s); PyTuple_SET_ITEM(%s, 0, %s); %s = NULL;" % (
6148                self_arg, args_tuple, self_arg, self_arg))  # stealing owned ref in this case
6149            code.funcstate.release_temp(self_arg)
6150            if len(args) > 1:
6151                code.putln("}")
6152
6153            for i, arg in enumerate(args):
6154                arg.make_owned_reference(code)
6155                code.put_giveref(arg.py_result())
6156                code.putln("PyTuple_SET_ITEM(%s, %d+%s, %s);" % (
6157                    args_tuple, i, arg_offset_cname, arg.py_result()))
6158            if len(args) > 1:
6159                code.funcstate.release_temp(arg_offset_cname)
6160
6161            for arg in args:
6162                arg.generate_post_assignment_code(code)
6163                arg.free_temps(code)
6164
6165            code.globalstate.use_utility_code(
6166                UtilityCode.load_cached("PyObjectCall", "ObjectHandling.c"))
6167            code.putln(
6168                "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
6169                    self.result(),
6170                    function, args_tuple,
6171                    code.error_goto_if_null(self.result(), self.pos)))
6172            code.put_gotref(self.py_result())
6173
6174            code.put_decref_clear(args_tuple, py_object_type)
6175            code.funcstate.release_temp(args_tuple)
6176
6177            if len(args) == 1:
6178                code.putln("}")
6179            code.putln("}")  # !CYTHON_FAST_PYCALL
6180
6181        if reuse_function_temp:
6182            self.function.generate_disposal_code(code)
6183            self.function.free_temps(code)
6184        else:
6185            code.put_decref_clear(function, py_object_type)
6186            code.funcstate.release_temp(function)
6187
6188
6189class InlinedDefNodeCallNode(CallNode):
6190    #  Inline call to defnode
6191    #
6192    #  function       PyCFunctionNode
6193    #  function_name  NameNode
6194    #  args           [ExprNode]
6195
6196    subexprs = ['args', 'function_name']
6197    is_temp = 1
6198    type = py_object_type
6199    function = None
6200    function_name = None
6201
6202    def can_be_inlined(self):
6203        func_type= self.function.def_node
6204        if func_type.star_arg or func_type.starstar_arg:
6205            return False
6206        if len(func_type.args) != len(self.args):
6207            return False
6208        if func_type.num_kwonly_args:
6209            return False  # actually wrong number of arguments
6210        return True
6211
6212    def analyse_types(self, env):
6213        self.function_name = self.function_name.analyse_types(env)
6214
6215        self.args = [ arg.analyse_types(env) for arg in self.args ]
6216        func_type = self.function.def_node
6217        actual_nargs = len(self.args)
6218
6219        # Coerce arguments
6220        some_args_in_temps = False
6221        for i in range(actual_nargs):
6222            formal_type = func_type.args[i].type
6223            arg = self.args[i].coerce_to(formal_type, env)
6224            if arg.is_temp:
6225                if i > 0:
6226                    # first argument in temp doesn't impact subsequent arguments
6227                    some_args_in_temps = True
6228            elif arg.type.is_pyobject and not env.nogil:
6229                if arg.nonlocally_immutable():
6230                    # plain local variables are ok
6231                    pass
6232                else:
6233                    # we do not safely own the argument's reference,
6234                    # but we must make sure it cannot be collected
6235                    # before we return from the function, so we create
6236                    # an owned temp reference to it
6237                    if i > 0: # first argument doesn't matter
6238                        some_args_in_temps = True
6239                    arg = arg.coerce_to_temp(env)
6240            self.args[i] = arg
6241
6242        if some_args_in_temps:
6243            # if some args are temps and others are not, they may get
6244            # constructed in the wrong order (temps first) => make
6245            # sure they are either all temps or all not temps (except
6246            # for the last argument, which is evaluated last in any
6247            # case)
6248            for i in range(actual_nargs-1):
6249                arg = self.args[i]
6250                if arg.nonlocally_immutable():
6251                    # locals, C functions, unassignable types are safe.
6252                    pass
6253                elif arg.type.is_cpp_class:
6254                    # Assignment has side effects, avoid.
6255                    pass
6256                elif env.nogil and arg.type.is_pyobject:
6257                    # can't copy a Python reference into a temp in nogil
6258                    # env (this is safe: a construction would fail in
6259                    # nogil anyway)
6260                    pass
6261                else:
6262                    #self.args[i] = arg.coerce_to_temp(env)
6263                    # instead: issue a warning
6264                    if i > 0:
6265                        warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
6266                        break
6267        return self
6268
6269    def generate_result_code(self, code):
6270        arg_code = [self.function_name.py_result()]
6271        func_type = self.function.def_node
6272        for arg, proto_arg in zip(self.args, func_type.args):
6273            if arg.type.is_pyobject:
6274                arg_code.append(arg.result_as(proto_arg.type))
6275            else:
6276                arg_code.append(arg.result())
6277        arg_code = ', '.join(arg_code)
6278        code.putln(
6279            "%s = %s(%s); %s" % (
6280                self.result(),
6281                self.function.def_node.entry.pyfunc_cname,
6282                arg_code,
6283                code.error_goto_if_null(self.result(), self.pos)))
6284        code.put_gotref(self.py_result())
6285
6286
6287class PythonCapiFunctionNode(ExprNode):
6288    subexprs = []
6289
6290    def __init__(self, pos, py_name, cname, func_type, utility_code = None):
6291        ExprNode.__init__(self, pos, name=py_name, cname=cname,
6292                          type=func_type, utility_code=utility_code)
6293
6294    def analyse_types(self, env):
6295        return self
6296
6297    def generate_result_code(self, code):
6298        if self.utility_code:
6299            code.globalstate.use_utility_code(self.utility_code)
6300
6301    def calculate_result_code(self):
6302        return self.cname
6303
6304
6305class PythonCapiCallNode(SimpleCallNode):
6306    # Python C-API Function call (only created in transforms)
6307
6308    # By default, we assume that the call never returns None, as this
6309    # is true for most C-API functions in CPython.  If this does not
6310    # apply to a call, set the following to True (or None to inherit
6311    # the default behaviour).
6312    may_return_none = False
6313
6314    def __init__(self, pos, function_name, func_type,
6315                 utility_code = None, py_name=None, **kwargs):
6316        self.type = func_type.return_type
6317        self.result_ctype = self.type
6318        self.function = PythonCapiFunctionNode(
6319            pos, py_name, function_name, func_type,
6320            utility_code = utility_code)
6321        # call this last so that we can override the constructed
6322        # attributes above with explicit keyword arguments if required
6323        SimpleCallNode.__init__(self, pos, **kwargs)
6324
6325
6326class CachedBuiltinMethodCallNode(CallNode):
6327    # Python call to a method of a known Python builtin (only created in transforms)
6328
6329    subexprs = ['obj', 'args']
6330    is_temp = True
6331
6332    def __init__(self, call_node, obj, method_name, args):
6333        super(CachedBuiltinMethodCallNode, self).__init__(
6334            call_node.pos,
6335            obj=obj, method_name=method_name, args=args,
6336            may_return_none=call_node.may_return_none,
6337            type=call_node.type)
6338
6339    def may_be_none(self):
6340        if self.may_return_none is not None:
6341            return self.may_return_none
6342        return ExprNode.may_be_none(self)
6343
6344    def generate_result_code(self, code):
6345        type_cname = self.obj.type.cname
6346        obj_cname = self.obj.py_result()
6347        args = [arg.py_result() for arg in self.args]
6348        call_code = code.globalstate.cached_unbound_method_call_code(
6349            obj_cname, type_cname, self.method_name, args)
6350        code.putln("%s = %s; %s" % (
6351            self.result(), call_code,
6352            code.error_goto_if_null(self.result(), self.pos)
6353        ))
6354        code.put_gotref(self.result())
6355
6356
6357class GeneralCallNode(CallNode):
6358    #  General Python function call, including keyword,
6359    #  * and ** arguments.
6360    #
6361    #  function         ExprNode
6362    #  positional_args  ExprNode          Tuple of positional arguments
6363    #  keyword_args     ExprNode or None  Dict of keyword arguments
6364
6365    type = py_object_type
6366
6367    subexprs = ['function', 'positional_args', 'keyword_args']
6368
6369    nogil_check = Node.gil_error
6370
6371    def compile_time_value(self, denv):
6372        function = self.function.compile_time_value(denv)
6373        positional_args = self.positional_args.compile_time_value(denv)
6374        keyword_args = self.keyword_args.compile_time_value(denv)
6375        try:
6376            return function(*positional_args, **keyword_args)
6377        except Exception as e:
6378            self.compile_time_value_error(e)
6379
6380    def explicit_args_kwds(self):
6381        if (self.keyword_args and not self.keyword_args.is_dict_literal or
6382                not self.positional_args.is_sequence_constructor):
6383            raise CompileError(self.pos,
6384                'Compile-time keyword arguments must be explicit.')
6385        return self.positional_args.args, self.keyword_args
6386
6387    def analyse_types(self, env):
6388        if self.analyse_as_type_constructor(env):
6389            return self
6390        self.function = self.function.analyse_types(env)
6391        if not self.function.type.is_pyobject:
6392            if self.function.type.is_error:
6393                self.type = error_type
6394                return self
6395            if hasattr(self.function, 'entry'):
6396                node = self.map_to_simple_call_node()
6397                if node is not None and node is not self:
6398                    return node.analyse_types(env)
6399                elif self.function.entry.as_variable:
6400                    self.function = self.function.coerce_to_pyobject(env)
6401                elif node is self:
6402                    error(self.pos,
6403                          "Non-trivial keyword arguments and starred "
6404                          "arguments not allowed in cdef functions.")
6405                else:
6406                    # error was already reported
6407                    pass
6408            else:
6409                self.function = self.function.coerce_to_pyobject(env)
6410        if self.keyword_args:
6411            self.keyword_args = self.keyword_args.analyse_types(env)
6412        self.positional_args = self.positional_args.analyse_types(env)
6413        self.positional_args = \
6414            self.positional_args.coerce_to_pyobject(env)
6415        self.set_py_result_type(self.function)
6416        self.is_temp = 1
6417        return self
6418
6419    def map_to_simple_call_node(self):
6420        """
6421        Tries to map keyword arguments to declared positional arguments.
6422        Returns self to try a Python call, None to report an error
6423        or a SimpleCallNode if the mapping succeeds.
6424        """
6425        if not isinstance(self.positional_args, TupleNode):
6426            # has starred argument
6427            return self
6428        if not self.keyword_args.is_dict_literal:
6429            # keywords come from arbitrary expression => nothing to do here
6430            return self
6431        function = self.function
6432        entry = getattr(function, 'entry', None)
6433        if not entry:
6434            return self
6435        function_type = entry.type
6436        if function_type.is_ptr:
6437            function_type = function_type.base_type
6438        if not function_type.is_cfunction:
6439            return self
6440
6441        pos_args = self.positional_args.args
6442        kwargs = self.keyword_args
6443        declared_args = function_type.args
6444        if entry.is_cmethod:
6445            declared_args = declared_args[1:] # skip 'self'
6446
6447        if len(pos_args) > len(declared_args):
6448            error(self.pos, "function call got too many positional arguments, "
6449                            "expected %d, got %s" % (len(declared_args),
6450                                                     len(pos_args)))
6451            return None
6452
6453        matched_args = set([ arg.name for arg in declared_args[:len(pos_args)]
6454                             if arg.name ])
6455        unmatched_args = declared_args[len(pos_args):]
6456        matched_kwargs_count = 0
6457        args = list(pos_args)
6458
6459        # check for duplicate keywords
6460        seen = set(matched_args)
6461        has_errors = False
6462        for arg in kwargs.key_value_pairs:
6463            name = arg.key.value
6464            if name in seen:
6465                error(arg.pos, "argument '%s' passed twice" % name)
6466                has_errors = True
6467                # continue to report more errors if there are any
6468            seen.add(name)
6469
6470        # match keywords that are passed in order
6471        for decl_arg, arg in zip(unmatched_args, kwargs.key_value_pairs):
6472            name = arg.key.value
6473            if decl_arg.name == name:
6474                matched_args.add(name)
6475                matched_kwargs_count += 1
6476                args.append(arg.value)
6477            else:
6478                break
6479
6480        # match keyword arguments that are passed out-of-order, but keep
6481        # the evaluation of non-simple arguments in order by moving them
6482        # into temps
6483        from .UtilNodes import EvalWithTempExprNode, LetRefNode
6484        temps = []
6485        if len(kwargs.key_value_pairs) > matched_kwargs_count:
6486            unmatched_args = declared_args[len(args):]
6487            keywords = dict([ (arg.key.value, (i+len(pos_args), arg))
6488                              for i, arg in enumerate(kwargs.key_value_pairs) ])
6489            first_missing_keyword = None
6490            for decl_arg in unmatched_args:
6491                name = decl_arg.name
6492                if name not in keywords:
6493                    # missing keyword argument => either done or error
6494                    if not first_missing_keyword:
6495                        first_missing_keyword = name
6496                    continue
6497                elif first_missing_keyword:
6498                    if entry.as_variable:
6499                        # we might be able to convert the function to a Python
6500                        # object, which then allows full calling semantics
6501                        # with default values in gaps - currently, we only
6502                        # support optional arguments at the end
6503                        return self
6504                    # wasn't the last keyword => gaps are not supported
6505                    error(self.pos, "C function call is missing "
6506                                    "argument '%s'" % first_missing_keyword)
6507                    return None
6508                pos, arg = keywords[name]
6509                matched_args.add(name)
6510                matched_kwargs_count += 1
6511                if arg.value.is_simple():
6512                    args.append(arg.value)
6513                else:
6514                    temp = LetRefNode(arg.value)
6515                    assert temp.is_simple()
6516                    args.append(temp)
6517                    temps.append((pos, temp))
6518
6519            if temps:
6520                # may have to move preceding non-simple args into temps
6521                final_args = []
6522                new_temps = []
6523                first_temp_arg = temps[0][-1]
6524                for arg_value in args:
6525                    if arg_value is first_temp_arg:
6526                        break  # done
6527                    if arg_value.is_simple():
6528                        final_args.append(arg_value)
6529                    else:
6530                        temp = LetRefNode(arg_value)
6531                        new_temps.append(temp)
6532                        final_args.append(temp)
6533                if new_temps:
6534                    args = final_args
6535                temps = new_temps + [ arg for i,arg in sorted(temps) ]
6536
6537        # check for unexpected keywords
6538        for arg in kwargs.key_value_pairs:
6539            name = arg.key.value
6540            if name not in matched_args:
6541                has_errors = True
6542                error(arg.pos,
6543                      "C function got unexpected keyword argument '%s'" %
6544                      name)
6545
6546        if has_errors:
6547            # error was reported already
6548            return None
6549
6550        # all keywords mapped to positional arguments
6551        # if we are missing arguments, SimpleCallNode will figure it out
6552        node = SimpleCallNode(self.pos, function=function, args=args)
6553        for temp in temps[::-1]:
6554            node = EvalWithTempExprNode(temp, node)
6555        return node
6556
6557    def generate_result_code(self, code):
6558        if self.type.is_error: return
6559        if self.keyword_args:
6560            kwargs = self.keyword_args.py_result()
6561        else:
6562            kwargs = 'NULL'
6563        code.globalstate.use_utility_code(UtilityCode.load_cached(
6564            "PyObjectCall", "ObjectHandling.c"))
6565        code.putln(
6566            "%s = __Pyx_PyObject_Call(%s, %s, %s); %s" % (
6567                self.result(),
6568                self.function.py_result(),
6569                self.positional_args.py_result(),
6570                kwargs,
6571                code.error_goto_if_null(self.result(), self.pos)))
6572        code.put_gotref(self.py_result())
6573
6574
6575class AsTupleNode(ExprNode):
6576    #  Convert argument to tuple. Used for normalising
6577    #  the * argument of a function call.
6578    #
6579    #  arg    ExprNode
6580
6581    subexprs = ['arg']
6582    is_temp = 1
6583
6584    def calculate_constant_result(self):
6585        self.constant_result = tuple(self.arg.constant_result)
6586
6587    def compile_time_value(self, denv):
6588        arg = self.arg.compile_time_value(denv)
6589        try:
6590            return tuple(arg)
6591        except Exception as e:
6592            self.compile_time_value_error(e)
6593
6594    def analyse_types(self, env):
6595        self.arg = self.arg.analyse_types(env).coerce_to_pyobject(env)
6596        if self.arg.type is tuple_type:
6597            return self.arg.as_none_safe_node("'NoneType' object is not iterable")
6598        self.type = tuple_type
6599        return self
6600
6601    def may_be_none(self):
6602        return False
6603
6604    nogil_check = Node.gil_error
6605    gil_message = "Constructing Python tuple"
6606
6607    def generate_result_code(self, code):
6608        cfunc = "__Pyx_PySequence_Tuple" if self.arg.type in (py_object_type, tuple_type) else "PySequence_Tuple"
6609        code.putln(
6610            "%s = %s(%s); %s" % (
6611                self.result(),
6612                cfunc, self.arg.py_result(),
6613                code.error_goto_if_null(self.result(), self.pos)))
6614        code.put_gotref(self.py_result())
6615
6616
6617class MergedDictNode(ExprNode):
6618    #  Helper class for keyword arguments and other merged dicts.
6619    #
6620    #  keyword_args      [DictNode or other ExprNode]
6621
6622    subexprs = ['keyword_args']
6623    is_temp = 1
6624    type = dict_type
6625    reject_duplicates = True
6626
6627    def calculate_constant_result(self):
6628        result = {}
6629        reject_duplicates = self.reject_duplicates
6630        for item in self.keyword_args:
6631            if item.is_dict_literal:
6632                # process items in order
6633                items = ((key.constant_result, value.constant_result)
6634                         for key, value in item.key_value_pairs)
6635            else:
6636                items = item.constant_result.iteritems()
6637
6638            for key, value in items:
6639                if reject_duplicates and key in result:
6640                    raise ValueError("duplicate keyword argument found: %s" % key)
6641                result[key] = value
6642
6643        self.constant_result = result
6644
6645    def compile_time_value(self, denv):
6646        result = {}
6647        reject_duplicates = self.reject_duplicates
6648        for item in self.keyword_args:
6649            if item.is_dict_literal:
6650                # process items in order
6651                items = [(key.compile_time_value(denv), value.compile_time_value(denv))
6652                         for key, value in item.key_value_pairs]
6653            else:
6654                items = item.compile_time_value(denv).iteritems()
6655
6656            try:
6657                for key, value in items:
6658                    if reject_duplicates and key in result:
6659                        raise ValueError("duplicate keyword argument found: %s" % key)
6660                    result[key] = value
6661            except Exception as e:
6662                self.compile_time_value_error(e)
6663        return result
6664
6665    def type_dependencies(self, env):
6666        return ()
6667
6668    def infer_type(self, env):
6669        return dict_type
6670
6671    def analyse_types(self, env):
6672        self.keyword_args = [
6673            arg.analyse_types(env).coerce_to_pyobject(env).as_none_safe_node(
6674                # FIXME: CPython's error message starts with the runtime function name
6675                'argument after ** must be a mapping, not NoneType')
6676            for arg in self.keyword_args
6677        ]
6678
6679        return self
6680
6681    def may_be_none(self):
6682        return False
6683
6684    gil_message = "Constructing Python dict"
6685
6686    def generate_evaluation_code(self, code):
6687        code.mark_pos(self.pos)
6688        self.allocate_temp_result(code)
6689
6690        args = iter(self.keyword_args)
6691        item = next(args)
6692        item.generate_evaluation_code(code)
6693        if item.type is not dict_type:
6694            # CPython supports calling functions with non-dicts, so do we
6695            code.putln('if (likely(PyDict_CheckExact(%s))) {' %
6696                       item.py_result())
6697
6698        if item.is_dict_literal:
6699            item.make_owned_reference(code)
6700            code.putln("%s = %s;" % (self.result(), item.py_result()))
6701            item.generate_post_assignment_code(code)
6702        else:
6703            code.putln("%s = PyDict_Copy(%s); %s" % (
6704                self.result(),
6705                item.py_result(),
6706                code.error_goto_if_null(self.result(), item.pos)))
6707            code.put_gotref(self.result())
6708            item.generate_disposal_code(code)
6709
6710        if item.type is not dict_type:
6711            code.putln('} else {')
6712            code.putln("%s = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, %s, NULL); %s" % (
6713                self.result(),
6714                item.py_result(),
6715                code.error_goto_if_null(self.result(), self.pos)))
6716            code.put_gotref(self.py_result())
6717            item.generate_disposal_code(code)
6718            code.putln('}')
6719        item.free_temps(code)
6720
6721        helpers = set()
6722        for item in args:
6723            if item.is_dict_literal:
6724                # inline update instead of creating an intermediate dict
6725                for arg in item.key_value_pairs:
6726                    arg.generate_evaluation_code(code)
6727                    if self.reject_duplicates:
6728                        code.putln("if (unlikely(PyDict_Contains(%s, %s))) {" % (
6729                            self.result(),
6730                            arg.key.py_result()))
6731                        helpers.add("RaiseDoubleKeywords")
6732                        # FIXME: find out function name at runtime!
6733                        code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
6734                            arg.key.py_result(),
6735                            code.error_goto(self.pos)))
6736                        code.putln("}")
6737                    code.put_error_if_neg(arg.key.pos, "PyDict_SetItem(%s, %s, %s)" % (
6738                        self.result(),
6739                        arg.key.py_result(),
6740                        arg.value.py_result()))
6741                    arg.generate_disposal_code(code)
6742                    arg.free_temps(code)
6743            else:
6744                item.generate_evaluation_code(code)
6745                if self.reject_duplicates:
6746                    # merge mapping into kwdict one by one as we need to check for duplicates
6747                    helpers.add("MergeKeywords")
6748                    code.put_error_if_neg(item.pos, "__Pyx_MergeKeywords(%s, %s)" % (
6749                        self.result(), item.py_result()))
6750                else:
6751                    # simple case, just add all entries
6752                    helpers.add("RaiseMappingExpected")
6753                    code.putln("if (unlikely(PyDict_Update(%s, %s) < 0)) {" % (
6754                        self.result(), item.py_result()))
6755                    code.putln("if (PyErr_ExceptionMatches(PyExc_AttributeError)) "
6756                               "__Pyx_RaiseMappingExpectedError(%s);" % item.py_result())
6757                    code.putln(code.error_goto(item.pos))
6758                    code.putln("}")
6759                item.generate_disposal_code(code)
6760                item.free_temps(code)
6761
6762        for helper in sorted(helpers):
6763            code.globalstate.use_utility_code(UtilityCode.load_cached(helper, "FunctionArguments.c"))
6764
6765    def annotate(self, code):
6766        for item in self.keyword_args:
6767            item.annotate(code)
6768
6769
6770class AttributeNode(ExprNode):
6771    #  obj.attribute
6772    #
6773    #  obj          ExprNode
6774    #  attribute    string
6775    #  needs_none_check boolean        Used if obj is an extension type.
6776    #                                  If set to True, it is known that the type is not None.
6777    #
6778    #  Used internally:
6779    #
6780    #  is_py_attr           boolean   Is a Python getattr operation
6781    #  member               string    C name of struct member
6782    #  is_called            boolean   Function call is being done on result
6783    #  entry                Entry     Symbol table entry of attribute
6784
6785    is_attribute = 1
6786    subexprs = ['obj']
6787
6788    type = PyrexTypes.error_type
6789    entry = None
6790    is_called = 0
6791    needs_none_check = True
6792    is_memslice_transpose = False
6793    is_special_lookup = False
6794    is_py_attr = 0
6795
6796    def as_cython_attribute(self):
6797        if (isinstance(self.obj, NameNode) and
6798                self.obj.is_cython_module and not
6799                self.attribute == u"parallel"):
6800            return self.attribute
6801
6802        cy = self.obj.as_cython_attribute()
6803        if cy:
6804            return "%s.%s" % (cy, self.attribute)
6805        return None
6806
6807    def coerce_to(self, dst_type, env):
6808        #  If coercing to a generic pyobject and this is a cpdef function
6809        #  we can create the corresponding attribute
6810        if dst_type is py_object_type:
6811            entry = self.entry
6812            if entry and entry.is_cfunction and entry.as_variable:
6813                # must be a cpdef function
6814                self.is_temp = 1
6815                self.entry = entry.as_variable
6816                self.analyse_as_python_attribute(env)
6817                return self
6818        return ExprNode.coerce_to(self, dst_type, env)
6819
6820    def calculate_constant_result(self):
6821        attr = self.attribute
6822        if attr.startswith("__") and attr.endswith("__"):
6823            return
6824        self.constant_result = getattr(self.obj.constant_result, attr)
6825
6826    def compile_time_value(self, denv):
6827        attr = self.attribute
6828        if attr.startswith("__") and attr.endswith("__"):
6829            error(self.pos,
6830                  "Invalid attribute name '%s' in compile-time expression" % attr)
6831            return None
6832        obj = self.obj.compile_time_value(denv)
6833        try:
6834            return getattr(obj, attr)
6835        except Exception as e:
6836            self.compile_time_value_error(e)
6837
6838    def type_dependencies(self, env):
6839        return self.obj.type_dependencies(env)
6840
6841    def infer_type(self, env):
6842        # FIXME: this is way too redundant with analyse_types()
6843        node = self.analyse_as_cimported_attribute_node(env, target=False)
6844        if node is not None:
6845            if node.entry.type and node.entry.type.is_cfunction:
6846                # special-case - function converted to pointer
6847                return PyrexTypes.CPtrType(node.entry.type)
6848            else:
6849                return node.entry.type
6850        node = self.analyse_as_type_attribute(env)
6851        if node is not None:
6852            return node.entry.type
6853        obj_type = self.obj.infer_type(env)
6854        self.analyse_attribute(env, obj_type=obj_type)
6855        if obj_type.is_builtin_type and self.type.is_cfunction:
6856            # special case: C-API replacements for C methods of
6857            # builtin types cannot be inferred as C functions as
6858            # that would prevent their use as bound methods
6859            return py_object_type
6860        elif self.entry and self.entry.is_cmethod:
6861            # special case: bound methods should not be inferred
6862            # as their unbound method types
6863            return py_object_type
6864        return self.type
6865
6866    def analyse_target_declaration(self, env):
6867        pass
6868
6869    def analyse_target_types(self, env):
6870        node = self.analyse_types(env, target = 1)
6871        if node.type.is_const:
6872            error(self.pos, "Assignment to const attribute '%s'" % self.attribute)
6873        if not node.is_lvalue():
6874            error(self.pos, "Assignment to non-lvalue of type '%s'" % self.type)
6875        return node
6876
6877    def analyse_types(self, env, target = 0):
6878        self.initialized_check = env.directives['initializedcheck']
6879        node = self.analyse_as_cimported_attribute_node(env, target)
6880        if node is None and not target:
6881            node = self.analyse_as_type_attribute(env)
6882        if node is None:
6883            node = self.analyse_as_ordinary_attribute_node(env, target)
6884            assert node is not None
6885        if node.entry:
6886            node.entry.used = True
6887        if node.is_attribute:
6888            node.wrap_obj_in_nonecheck(env)
6889        return node
6890
6891    def analyse_as_cimported_attribute_node(self, env, target):
6892        # Try to interpret this as a reference to an imported
6893        # C const, type, var or function. If successful, mutates
6894        # this node into a NameNode and returns 1, otherwise
6895        # returns 0.
6896        module_scope = self.obj.analyse_as_module(env)
6897        if module_scope:
6898            entry = module_scope.lookup_here(self.attribute)
6899            if entry and (
6900                    entry.is_cglobal or entry.is_cfunction
6901                    or entry.is_type or entry.is_const):
6902                return self.as_name_node(env, entry, target)
6903            if self.is_cimported_module_without_shadow(env):
6904                error(self.pos, "cimported module has no attribute '%s'" % self.attribute)
6905                return self
6906        return None
6907
6908    def analyse_as_type_attribute(self, env):
6909        # Try to interpret this as a reference to an unbound
6910        # C method of an extension type or builtin type.  If successful,
6911        # creates a corresponding NameNode and returns it, otherwise
6912        # returns None.
6913        if self.obj.is_string_literal:
6914            return
6915        type = self.obj.analyse_as_type(env)
6916        if type:
6917            if type.is_extension_type or type.is_builtin_type or type.is_cpp_class:
6918                entry = type.scope.lookup_here(self.attribute)
6919                if entry and (entry.is_cmethod or type.is_cpp_class and entry.type.is_cfunction):
6920                    if type.is_builtin_type:
6921                        if not self.is_called:
6922                            # must handle this as Python object
6923                            return None
6924                        ubcm_entry = entry
6925                    else:
6926                        # Create a temporary entry describing the C method
6927                        # as an ordinary function.
6928                        if entry.func_cname and not hasattr(entry.type, 'op_arg_struct'):
6929                            cname = entry.func_cname
6930                            if entry.type.is_static_method or (
6931                                    env.parent_scope and env.parent_scope.is_cpp_class_scope):
6932                                ctype = entry.type
6933                            elif type.is_cpp_class:
6934                                error(self.pos, "%s not a static member of %s" % (entry.name, type))
6935                                ctype = PyrexTypes.error_type
6936                            else:
6937                                # Fix self type.
6938                                ctype = copy.copy(entry.type)
6939                                ctype.args = ctype.args[:]
6940                                ctype.args[0] = PyrexTypes.CFuncTypeArg('self', type, 'self', None)
6941                        else:
6942                            cname = "%s->%s" % (type.vtabptr_cname, entry.cname)
6943                            ctype = entry.type
6944                        ubcm_entry = Symtab.Entry(entry.name, cname, ctype)
6945                        ubcm_entry.is_cfunction = 1
6946                        ubcm_entry.func_cname = entry.func_cname
6947                        ubcm_entry.is_unbound_cmethod = 1
6948                        ubcm_entry.scope = entry.scope
6949                    return self.as_name_node(env, ubcm_entry, target=False)
6950            elif type.is_enum:
6951                if self.attribute in type.values:
6952                    for entry in type.entry.enum_values:
6953                        if entry.name == self.attribute:
6954                            return self.as_name_node(env, entry, target=False)
6955                    else:
6956                        error(self.pos, "%s not a known value of %s" % (self.attribute, type))
6957                else:
6958                    error(self.pos, "%s not a known value of %s" % (self.attribute, type))
6959        return None
6960
6961    def analyse_as_type(self, env):
6962        module_scope = self.obj.analyse_as_module(env)
6963        if module_scope:
6964            return module_scope.lookup_type(self.attribute)
6965        if not self.obj.is_string_literal:
6966            base_type = self.obj.analyse_as_type(env)
6967            if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
6968                return base_type.scope.lookup_type(self.attribute)
6969        return None
6970
6971    def analyse_as_extension_type(self, env):
6972        # Try to interpret this as a reference to an extension type
6973        # in a cimported module. Returns the extension type, or None.
6974        module_scope = self.obj.analyse_as_module(env)
6975        if module_scope:
6976            entry = module_scope.lookup_here(self.attribute)
6977            if entry and entry.is_type:
6978                if entry.type.is_extension_type or entry.type.is_builtin_type:
6979                    return entry.type
6980        return None
6981
6982    def analyse_as_module(self, env):
6983        # Try to interpret this as a reference to a cimported module
6984        # in another cimported module. Returns the module scope, or None.
6985        module_scope = self.obj.analyse_as_module(env)
6986        if module_scope:
6987            entry = module_scope.lookup_here(self.attribute)
6988            if entry and entry.as_module:
6989                return entry.as_module
6990        return None
6991
6992    def as_name_node(self, env, entry, target):
6993        # Create a corresponding NameNode from this node and complete the
6994        # analyse_types phase.
6995        node = NameNode.from_node(self, name=self.attribute, entry=entry)
6996        if target:
6997            node = node.analyse_target_types(env)
6998        else:
6999            node = node.analyse_rvalue_entry(env)
7000        node.entry.used = 1
7001        return node
7002
7003    def analyse_as_ordinary_attribute_node(self, env, target):
7004        self.obj = self.obj.analyse_types(env)
7005        self.analyse_attribute(env)
7006        if self.entry and self.entry.is_cmethod and not self.is_called:
7007#            error(self.pos, "C method can only be called")
7008            pass
7009        ## Reference to C array turns into pointer to first element.
7010        #while self.type.is_array:
7011        #    self.type = self.type.element_ptr_type()
7012        if self.is_py_attr:
7013            if not target:
7014                self.is_temp = 1
7015                self.result_ctype = py_object_type
7016        elif target and self.obj.type.is_builtin_type:
7017            error(self.pos, "Assignment to an immutable object field")
7018        #elif self.type.is_memoryviewslice and not target:
7019        #    self.is_temp = True
7020        return self
7021
7022    def analyse_attribute(self, env, obj_type = None):
7023        # Look up attribute and set self.type and self.member.
7024        immutable_obj = obj_type is not None # used during type inference
7025        self.is_py_attr = 0
7026        self.member = self.attribute
7027        if obj_type is None:
7028            if self.obj.type.is_string or self.obj.type.is_pyunicode_ptr:
7029                self.obj = self.obj.coerce_to_pyobject(env)
7030            obj_type = self.obj.type
7031        else:
7032            if obj_type.is_string or obj_type.is_pyunicode_ptr:
7033                obj_type = py_object_type
7034        if obj_type.is_ptr or obj_type.is_array:
7035            obj_type = obj_type.base_type
7036            self.op = "->"
7037        elif obj_type.is_extension_type or obj_type.is_builtin_type:
7038            self.op = "->"
7039        elif obj_type.is_reference and obj_type.is_fake_reference:
7040            self.op = "->"
7041        else:
7042            self.op = "."
7043        if obj_type.has_attributes:
7044            if obj_type.attributes_known():
7045                entry = obj_type.scope.lookup_here(self.attribute)
7046                if obj_type.is_memoryviewslice and not entry:
7047                    if self.attribute == 'T':
7048                        self.is_memslice_transpose = True
7049                        self.is_temp = True
7050                        self.use_managed_ref = True
7051                        self.type = self.obj.type.transpose(self.pos)
7052                        return
7053                    else:
7054                        obj_type.declare_attribute(self.attribute, env, self.pos)
7055                        entry = obj_type.scope.lookup_here(self.attribute)
7056                if entry and entry.is_member:
7057                    entry = None
7058            else:
7059                error(self.pos,
7060                    "Cannot select attribute of incomplete type '%s'"
7061                    % obj_type)
7062                self.type = PyrexTypes.error_type
7063                return
7064            self.entry = entry
7065            if entry:
7066                if obj_type.is_extension_type and entry.name == "__weakref__":
7067                    error(self.pos, "Illegal use of special attribute __weakref__")
7068
7069                # def methods need the normal attribute lookup
7070                # because they do not have struct entries
7071                # fused function go through assignment synthesis
7072                # (foo = pycfunction(foo_func_obj)) and need to go through
7073                # regular Python lookup as well
7074                if (entry.is_variable and not entry.fused_cfunction) or entry.is_cmethod:
7075                    self.type = entry.type
7076                    self.member = entry.cname
7077                    return
7078                else:
7079                    # If it's not a variable or C method, it must be a Python
7080                    # method of an extension type, so we treat it like a Python
7081                    # attribute.
7082                    pass
7083        # If we get here, the base object is not a struct/union/extension
7084        # type, or it is an extension type and the attribute is either not
7085        # declared or is declared as a Python method. Treat it as a Python
7086        # attribute reference.
7087        self.analyse_as_python_attribute(env, obj_type, immutable_obj)
7088
7089    def analyse_as_python_attribute(self, env, obj_type=None, immutable_obj=False):
7090        if obj_type is None:
7091            obj_type = self.obj.type
7092        # mangle private '__*' Python attributes used inside of a class
7093        self.attribute = env.mangle_class_private_name(self.attribute)
7094        self.member = self.attribute
7095        self.type = py_object_type
7096        self.is_py_attr = 1
7097
7098        if not obj_type.is_pyobject and not obj_type.is_error:
7099            # Expose python methods for immutable objects.
7100            if (obj_type.is_string or obj_type.is_cpp_string
7101                or obj_type.is_buffer or obj_type.is_memoryviewslice
7102                or obj_type.is_numeric
7103                or (obj_type.is_ctuple and obj_type.can_coerce_to_pyobject(env))
7104                or (obj_type.is_struct and obj_type.can_coerce_to_pyobject(env))):
7105                if not immutable_obj:
7106                    self.obj = self.obj.coerce_to_pyobject(env)
7107            elif (obj_type.is_cfunction and (self.obj.is_name or self.obj.is_attribute)
7108                  and self.obj.entry.as_variable
7109                  and self.obj.entry.as_variable.type.is_pyobject):
7110                # might be an optimised builtin function => unpack it
7111                if not immutable_obj:
7112                    self.obj = self.obj.coerce_to_pyobject(env)
7113            else:
7114                error(self.pos,
7115                      "Object of type '%s' has no attribute '%s'" %
7116                      (obj_type, self.attribute))
7117
7118    def wrap_obj_in_nonecheck(self, env):
7119        if not env.directives['nonecheck']:
7120            return
7121
7122        msg = None
7123        format_args = ()
7124        if (self.obj.type.is_extension_type and self.needs_none_check and not
7125                self.is_py_attr):
7126            msg = "'NoneType' object has no attribute '%{0}s'".format('.30' if len(self.attribute) <= 30 else '')
7127            format_args = (self.attribute,)
7128        elif self.obj.type.is_memoryviewslice:
7129            if self.is_memslice_transpose:
7130                msg = "Cannot transpose None memoryview slice"
7131            else:
7132                entry = self.obj.type.scope.lookup_here(self.attribute)
7133                if entry:
7134                    # copy/is_c_contig/shape/strides etc
7135                    msg = "Cannot access '%s' attribute of None memoryview slice"
7136                    format_args = (entry.name,)
7137
7138        if msg:
7139            self.obj = self.obj.as_none_safe_node(msg, 'PyExc_AttributeError',
7140                                                  format_args=format_args)
7141
7142    def nogil_check(self, env):
7143        if self.is_py_attr:
7144            self.gil_error()
7145
7146    gil_message = "Accessing Python attribute"
7147
7148    def is_cimported_module_without_shadow(self, env):
7149        return self.obj.is_cimported_module_without_shadow(env)
7150
7151    def is_simple(self):
7152        if self.obj:
7153            return self.result_in_temp() or self.obj.is_simple()
7154        else:
7155            return NameNode.is_simple(self)
7156
7157    def is_lvalue(self):
7158        if self.obj:
7159            return True
7160        else:
7161            return NameNode.is_lvalue(self)
7162
7163    def is_ephemeral(self):
7164        if self.obj:
7165            return self.obj.is_ephemeral()
7166        else:
7167            return NameNode.is_ephemeral(self)
7168
7169    def calculate_result_code(self):
7170        #print "AttributeNode.calculate_result_code:", self.member ###
7171        #print "...obj node =", self.obj, "code", self.obj.result() ###
7172        #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
7173        obj = self.obj
7174        obj_code = obj.result_as(obj.type)
7175        #print "...obj_code =", obj_code ###
7176        if self.entry and self.entry.is_cmethod:
7177            if obj.type.is_extension_type and not self.entry.is_builtin_cmethod:
7178                if self.entry.final_func_cname:
7179                    return self.entry.final_func_cname
7180
7181                if self.type.from_fused:
7182                    # If the attribute was specialized through indexing, make
7183                    # sure to get the right fused name, as our entry was
7184                    # replaced by our parent index node
7185                    # (AnalyseExpressionsTransform)
7186                    self.member = self.entry.cname
7187
7188                return "((struct %s *)%s%s%s)->%s" % (
7189                    obj.type.vtabstruct_cname, obj_code, self.op,
7190                    obj.type.vtabslot_cname, self.member)
7191            elif self.result_is_used:
7192                return self.member
7193            # Generating no code at all for unused access to optimised builtin
7194            # methods fixes the problem that some optimisations only exist as
7195            # macros, i.e. there is no function pointer to them, so we would
7196            # generate invalid C code here.
7197            return
7198        elif obj.type.is_complex:
7199            return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
7200        else:
7201            if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
7202                # accessing a field of a builtin type, need to cast better than result_as() does
7203                obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
7204            return "%s%s%s" % (obj_code, self.op, self.member)
7205
7206    def generate_result_code(self, code):
7207        if self.is_py_attr:
7208            if self.is_special_lookup:
7209                code.globalstate.use_utility_code(
7210                    UtilityCode.load_cached("PyObjectLookupSpecial", "ObjectHandling.c"))
7211                lookup_func_name = '__Pyx_PyObject_LookupSpecial'
7212            else:
7213                code.globalstate.use_utility_code(
7214                    UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c"))
7215                lookup_func_name = '__Pyx_PyObject_GetAttrStr'
7216            code.putln(
7217                '%s = %s(%s, %s); %s' % (
7218                    self.result(),
7219                    lookup_func_name,
7220                    self.obj.py_result(),
7221                    code.intern_identifier(self.attribute),
7222                    code.error_goto_if_null(self.result(), self.pos)))
7223            code.put_gotref(self.py_result())
7224        elif self.type.is_memoryviewslice:
7225            if self.is_memslice_transpose:
7226                # transpose the slice
7227                for access, packing in self.type.axes:
7228                    if access == 'ptr':
7229                        error(self.pos, "Transposing not supported for slices "
7230                                        "with indirect dimensions")
7231                        return
7232
7233                code.putln("%s = %s;" % (self.result(), self.obj.result()))
7234                code.put_incref_memoryviewslice(self.result(), have_gil=True)
7235
7236                T = "__pyx_memslice_transpose(&%s) == 0"
7237                code.putln(code.error_goto_if(T % self.result(), self.pos))
7238            elif self.initialized_check:
7239                code.putln(
7240                    'if (unlikely(!%s.memview)) {'
7241                        'PyErr_SetString(PyExc_AttributeError,'
7242                                        '"Memoryview is not initialized");'
7243                        '%s'
7244                    '}' % (self.result(), code.error_goto(self.pos)))
7245        else:
7246            # result_code contains what is needed, but we may need to insert
7247            # a check and raise an exception
7248            if self.obj.type and self.obj.type.is_extension_type:
7249                pass
7250            elif self.entry and self.entry.is_cmethod:
7251                # C method implemented as function call with utility code
7252                code.globalstate.use_entry_utility_code(self.entry)
7253
7254    def generate_disposal_code(self, code):
7255        if self.is_temp and self.type.is_memoryviewslice and self.is_memslice_transpose:
7256            # mirror condition for putting the memview incref here:
7257            code.put_xdecref_memoryviewslice(
7258                    self.result(), have_gil=True)
7259            code.putln("%s.memview = NULL;" % self.result())
7260            code.putln("%s.data = NULL;" % self.result())
7261        else:
7262            ExprNode.generate_disposal_code(self, code)
7263
7264    def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
7265        exception_check=None, exception_value=None):
7266        self.obj.generate_evaluation_code(code)
7267        if self.is_py_attr:
7268            code.globalstate.use_utility_code(
7269                UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
7270            code.put_error_if_neg(self.pos,
7271                '__Pyx_PyObject_SetAttrStr(%s, %s, %s)' % (
7272                    self.obj.py_result(),
7273                    code.intern_identifier(self.attribute),
7274                    rhs.py_result()))
7275            rhs.generate_disposal_code(code)
7276            rhs.free_temps(code)
7277        elif self.obj.type.is_complex:
7278            code.putln("__Pyx_SET_C%s(%s, %s);" % (
7279                self.member.upper(),
7280                self.obj.result_as(self.obj.type),
7281                rhs.result_as(self.ctype())))
7282            rhs.generate_disposal_code(code)
7283            rhs.free_temps(code)
7284        else:
7285            select_code = self.result()
7286            if self.type.is_pyobject and self.use_managed_ref:
7287                rhs.make_owned_reference(code)
7288                code.put_giveref(rhs.py_result())
7289                code.put_gotref(select_code)
7290                code.put_decref(select_code, self.ctype())
7291            elif self.type.is_memoryviewslice:
7292                from . import MemoryView
7293                MemoryView.put_assign_to_memviewslice(
7294                        select_code, rhs, rhs.result(), self.type, code)
7295
7296            if not self.type.is_memoryviewslice:
7297                code.putln(
7298                    "%s = %s;" % (
7299                        select_code,
7300                        rhs.result_as(self.ctype())))
7301                        #rhs.result()))
7302            rhs.generate_post_assignment_code(code)
7303            rhs.free_temps(code)
7304        self.obj.generate_disposal_code(code)
7305        self.obj.free_temps(code)
7306
7307    def generate_deletion_code(self, code, ignore_nonexisting=False):
7308        self.obj.generate_evaluation_code(code)
7309        if self.is_py_attr or (self.entry.scope.is_property_scope
7310                               and u'__del__' in self.entry.scope.entries):
7311            code.globalstate.use_utility_code(
7312                UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
7313            code.put_error_if_neg(self.pos,
7314                '__Pyx_PyObject_DelAttrStr(%s, %s)' % (
7315                    self.obj.py_result(),
7316                    code.intern_identifier(self.attribute)))
7317        else:
7318            error(self.pos, "Cannot delete C attribute of extension type")
7319        self.obj.generate_disposal_code(code)
7320        self.obj.free_temps(code)
7321
7322    def annotate(self, code):
7323        if self.is_py_attr:
7324            style, text = 'py_attr', 'python attribute (%s)'
7325        else:
7326            style, text = 'c_attr', 'c attribute (%s)'
7327        code.annotate(self.pos, AnnotationItem(style, text % self.type, size=len(self.attribute)))
7328
7329
7330#-------------------------------------------------------------------
7331#
7332#  Constructor nodes
7333#
7334#-------------------------------------------------------------------
7335
7336class StarredUnpackingNode(ExprNode):
7337    #  A starred expression like "*a"
7338    #
7339    #  This is only allowed in sequence assignment or construction such as
7340    #
7341    #      a, *b = (1,2,3,4)    =>     a = 1 ; b = [2,3,4]
7342    #
7343    #  and will be special cased during type analysis (or generate an error
7344    #  if it's found at unexpected places).
7345    #
7346    #  target          ExprNode
7347
7348    subexprs = ['target']
7349    is_starred = 1
7350    type = py_object_type
7351    is_temp = 1
7352    starred_expr_allowed_here = False
7353
7354    def __init__(self, pos, target):
7355        ExprNode.__init__(self, pos, target=target)
7356
7357    def analyse_declarations(self, env):
7358        if not self.starred_expr_allowed_here:
7359            error(self.pos, "starred expression is not allowed here")
7360        self.target.analyse_declarations(env)
7361
7362    def infer_type(self, env):
7363        return self.target.infer_type(env)
7364
7365    def analyse_types(self, env):
7366        if not self.starred_expr_allowed_here:
7367            error(self.pos, "starred expression is not allowed here")
7368        self.target = self.target.analyse_types(env)
7369        self.type = self.target.type
7370        return self
7371
7372    def analyse_target_declaration(self, env):
7373        self.target.analyse_target_declaration(env)
7374
7375    def analyse_target_types(self, env):
7376        self.target = self.target.analyse_target_types(env)
7377        self.type = self.target.type
7378        return self
7379
7380    def calculate_result_code(self):
7381        return ""
7382
7383    def generate_result_code(self, code):
7384        pass
7385
7386
7387class SequenceNode(ExprNode):
7388    #  Base class for list and tuple constructor nodes.
7389    #  Contains common code for performing sequence unpacking.
7390    #
7391    #  args                    [ExprNode]
7392    #  unpacked_items          [ExprNode] or None
7393    #  coerced_unpacked_items  [ExprNode] or None
7394    # mult_factor              ExprNode     the integer number of content repetitions ([1,2]*3)
7395
7396    subexprs = ['args', 'mult_factor']
7397
7398    is_sequence_constructor = 1
7399    unpacked_items = None
7400    mult_factor = None
7401    slow = False  # trade speed for code size (e.g. use PyTuple_Pack())
7402
7403    def compile_time_value_list(self, denv):
7404        return [arg.compile_time_value(denv) for arg in self.args]
7405
7406    def replace_starred_target_node(self):
7407        # replace a starred node in the targets by the contained expression
7408        self.starred_assignment = False
7409        args = []
7410        for arg in self.args:
7411            if arg.is_starred:
7412                if self.starred_assignment:
7413                    error(arg.pos, "more than 1 starred expression in assignment")
7414                self.starred_assignment = True
7415                arg = arg.target
7416                arg.is_starred = True
7417            args.append(arg)
7418        self.args = args
7419
7420    def analyse_target_declaration(self, env):
7421        self.replace_starred_target_node()
7422        for arg in self.args:
7423            arg.analyse_target_declaration(env)
7424
7425    def analyse_types(self, env, skip_children=False):
7426        for i, arg in enumerate(self.args):
7427            if not skip_children:
7428                arg = arg.analyse_types(env)
7429            self.args[i] = arg.coerce_to_pyobject(env)
7430        if self.mult_factor:
7431            self.mult_factor = self.mult_factor.analyse_types(env)
7432            if not self.mult_factor.type.is_int:
7433                self.mult_factor = self.mult_factor.coerce_to_pyobject(env)
7434        self.is_temp = 1
7435        # not setting self.type here, subtypes do this
7436        return self
7437
7438    def coerce_to_ctuple(self, dst_type, env):
7439        if self.type == dst_type:
7440            return self
7441        assert not self.mult_factor
7442        if len(self.args) != dst_type.size:
7443            error(self.pos, "trying to coerce sequence to ctuple of wrong length, expected %d, got %d" % (
7444                dst_type.size, len(self.args)))
7445        coerced_args = [arg.coerce_to(type, env) for arg, type in zip(self.args, dst_type.components)]
7446        return TupleNode(self.pos, args=coerced_args, type=dst_type, is_temp=True)
7447
7448    def _create_merge_node_if_necessary(self, env):
7449        self._flatten_starred_args()
7450        if not any(arg.is_starred for arg in self.args):
7451            return self
7452        # convert into MergedSequenceNode by building partial sequences
7453        args = []
7454        values = []
7455        for arg in self.args:
7456            if arg.is_starred:
7457                if values:
7458                    args.append(TupleNode(values[0].pos, args=values).analyse_types(env, skip_children=True))
7459                    values = []
7460                args.append(arg.target)
7461            else:
7462                values.append(arg)
7463        if values:
7464            args.append(TupleNode(values[0].pos, args=values).analyse_types(env, skip_children=True))
7465        node = MergedSequenceNode(self.pos, args, self.type)
7466        if self.mult_factor:
7467            node = binop_node(
7468                self.pos, '*', node, self.mult_factor.coerce_to_pyobject(env),
7469                inplace=True, type=self.type, is_temp=True)
7470        return node
7471
7472    def _flatten_starred_args(self):
7473        args = []
7474        for arg in self.args:
7475            if arg.is_starred and arg.target.is_sequence_constructor and not arg.target.mult_factor:
7476                args.extend(arg.target.args)
7477            else:
7478                args.append(arg)
7479        self.args[:] = args
7480
7481    def may_be_none(self):
7482        return False
7483
7484    def analyse_target_types(self, env):
7485        if self.mult_factor:
7486            error(self.pos, "can't assign to multiplied sequence")
7487        self.unpacked_items = []
7488        self.coerced_unpacked_items = []
7489        self.any_coerced_items = False
7490        for i, arg in enumerate(self.args):
7491            arg = self.args[i] = arg.analyse_target_types(env)
7492            if arg.is_starred:
7493                if not arg.type.assignable_from(list_type):
7494                    error(arg.pos,
7495                          "starred target must have Python object (list) type")
7496                if arg.type is py_object_type:
7497                    arg.type = list_type
7498            unpacked_item = PyTempNode(self.pos, env)
7499            coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
7500            if unpacked_item is not coerced_unpacked_item:
7501                self.any_coerced_items = True
7502            self.unpacked_items.append(unpacked_item)
7503            self.coerced_unpacked_items.append(coerced_unpacked_item)
7504        self.type = py_object_type
7505        return self
7506
7507    def generate_result_code(self, code):
7508        self.generate_operation_code(code)
7509
7510    def generate_sequence_packing_code(self, code, target=None, plain=False):
7511        if target is None:
7512            target = self.result()
7513        size_factor = c_mult = ''
7514        mult_factor = None
7515
7516        if self.mult_factor and not plain:
7517            mult_factor = self.mult_factor
7518            if mult_factor.type.is_int:
7519                c_mult = mult_factor.result()
7520                if (isinstance(mult_factor.constant_result, _py_int_types) and
7521                        mult_factor.constant_result > 0):
7522                    size_factor = ' * %s' % mult_factor.constant_result
7523                elif mult_factor.type.signed:
7524                    size_factor = ' * ((%s<0) ? 0:%s)' % (c_mult, c_mult)
7525                else:
7526                    size_factor = ' * (%s)' % (c_mult,)
7527
7528        if self.type is tuple_type and (self.is_literal or self.slow) and not c_mult:
7529            # use PyTuple_Pack() to avoid generating huge amounts of one-time code
7530            code.putln('%s = PyTuple_Pack(%d, %s); %s' % (
7531                target,
7532                len(self.args),
7533                ', '.join(arg.py_result() for arg in self.args),
7534                code.error_goto_if_null(target, self.pos)))
7535            code.put_gotref(target)
7536        elif self.type.is_ctuple:
7537            for i, arg in enumerate(self.args):
7538                code.putln("%s.f%s = %s;" % (
7539                    target, i, arg.result()))
7540        else:
7541            # build the tuple/list step by step, potentially multiplying it as we go
7542            if self.type is list_type:
7543                create_func, set_item_func = 'PyList_New', 'PyList_SET_ITEM'
7544            elif self.type is tuple_type:
7545                create_func, set_item_func = 'PyTuple_New', 'PyTuple_SET_ITEM'
7546            else:
7547                raise InternalError("sequence packing for unexpected type %s" % self.type)
7548            arg_count = len(self.args)
7549            code.putln("%s = %s(%s%s); %s" % (
7550                target, create_func, arg_count, size_factor,
7551                code.error_goto_if_null(target, self.pos)))
7552            code.put_gotref(target)
7553
7554            if c_mult:
7555                # FIXME: can't use a temp variable here as the code may
7556                # end up in the constant building function.  Temps
7557                # currently don't work there.
7558
7559                #counter = code.funcstate.allocate_temp(mult_factor.type, manage_ref=False)
7560                counter = Naming.quick_temp_cname
7561                code.putln('{ Py_ssize_t %s;' % counter)
7562                if arg_count == 1:
7563                    offset = counter
7564                else:
7565                    offset = '%s * %s' % (counter, arg_count)
7566                code.putln('for (%s=0; %s < %s; %s++) {' % (
7567                    counter, counter, c_mult, counter
7568                    ))
7569            else:
7570                offset = ''
7571
7572            for i in range(arg_count):
7573                arg = self.args[i]
7574                if c_mult or not arg.result_in_temp():
7575                    code.put_incref(arg.result(), arg.ctype())
7576                code.put_giveref(arg.py_result())
7577                code.putln("%s(%s, %s, %s);" % (
7578                    set_item_func,
7579                    target,
7580                    (offset and i) and ('%s + %s' % (offset, i)) or (offset or i),
7581                    arg.py_result()))
7582
7583            if c_mult:
7584                code.putln('}')
7585                #code.funcstate.release_temp(counter)
7586                code.putln('}')
7587
7588        if mult_factor is not None and mult_factor.type.is_pyobject:
7589            code.putln('{ PyObject* %s = PyNumber_InPlaceMultiply(%s, %s); %s' % (
7590                Naming.quick_temp_cname, target, mult_factor.py_result(),
7591                code.error_goto_if_null(Naming.quick_temp_cname, self.pos)
7592                ))
7593            code.put_gotref(Naming.quick_temp_cname)
7594            code.put_decref(target, py_object_type)
7595            code.putln('%s = %s;' % (target, Naming.quick_temp_cname))
7596            code.putln('}')
7597
7598    def generate_subexpr_disposal_code(self, code):
7599        if self.mult_factor and self.mult_factor.type.is_int:
7600            super(SequenceNode, self).generate_subexpr_disposal_code(code)
7601        elif self.type is tuple_type and (self.is_literal or self.slow):
7602            super(SequenceNode, self).generate_subexpr_disposal_code(code)
7603        else:
7604            # We call generate_post_assignment_code here instead
7605            # of generate_disposal_code, because values were stored
7606            # in the tuple using a reference-stealing operation.
7607            for arg in self.args:
7608                arg.generate_post_assignment_code(code)
7609                # Should NOT call free_temps -- this is invoked by the default
7610                # generate_evaluation_code which will do that.
7611            if self.mult_factor:
7612                self.mult_factor.generate_disposal_code(code)
7613
7614    def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
7615        exception_check=None, exception_value=None):
7616        if self.starred_assignment:
7617            self.generate_starred_assignment_code(rhs, code)
7618        else:
7619            self.generate_parallel_assignment_code(rhs, code)
7620
7621        for item in self.unpacked_items:
7622            item.release(code)
7623        rhs.free_temps(code)
7624
7625    _func_iternext_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
7626        PyrexTypes.py_object_type, [
7627            PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None),
7628            ]))
7629
7630    def generate_parallel_assignment_code(self, rhs, code):
7631        # Need to work around the fact that generate_evaluation_code
7632        # allocates the temps in a rather hacky way -- the assignment
7633        # is evaluated twice, within each if-block.
7634        for item in self.unpacked_items:
7635            item.allocate(code)
7636        special_unpack = (rhs.type is py_object_type
7637                          or rhs.type in (tuple_type, list_type)
7638                          or not rhs.type.is_builtin_type)
7639        long_enough_for_a_loop = len(self.unpacked_items) > 3
7640
7641        if special_unpack:
7642            self.generate_special_parallel_unpacking_code(
7643                code, rhs, use_loop=long_enough_for_a_loop)
7644        else:
7645            code.putln("{")
7646            self.generate_generic_parallel_unpacking_code(
7647                code, rhs, self.unpacked_items, use_loop=long_enough_for_a_loop)
7648            code.putln("}")
7649
7650        for value_node in self.coerced_unpacked_items:
7651            value_node.generate_evaluation_code(code)
7652        for i in range(len(self.args)):
7653            self.args[i].generate_assignment_code(
7654                self.coerced_unpacked_items[i], code)
7655
7656    def generate_special_parallel_unpacking_code(self, code, rhs, use_loop):
7657        sequence_type_test = '1'
7658        none_check = "likely(%s != Py_None)" % rhs.py_result()
7659        if rhs.type is list_type:
7660            sequence_types = ['List']
7661            if rhs.may_be_none():
7662                sequence_type_test = none_check
7663        elif rhs.type is tuple_type:
7664            sequence_types = ['Tuple']
7665            if rhs.may_be_none():
7666                sequence_type_test = none_check
7667        else:
7668            sequence_types = ['Tuple', 'List']
7669            tuple_check = 'likely(PyTuple_CheckExact(%s))' % rhs.py_result()
7670            list_check  = 'PyList_CheckExact(%s)' % rhs.py_result()
7671            sequence_type_test = "(%s) || (%s)" % (tuple_check, list_check)
7672
7673        code.putln("if (%s) {" % sequence_type_test)
7674        code.putln("PyObject* sequence = %s;" % rhs.py_result())
7675
7676        # list/tuple => check size
7677        code.putln("Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);")
7678        code.putln("if (unlikely(size != %d)) {" % len(self.args))
7679        code.globalstate.use_utility_code(raise_too_many_values_to_unpack)
7680        code.putln("if (size > %d) __Pyx_RaiseTooManyValuesError(%d);" % (
7681            len(self.args), len(self.args)))
7682        code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
7683        code.putln("else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);")
7684        # < 0 => exception
7685        code.putln(code.error_goto(self.pos))
7686        code.putln("}")
7687
7688        code.putln("#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS")
7689        # unpack items from list/tuple in unrolled loop (can't fail)
7690        if len(sequence_types) == 2:
7691            code.putln("if (likely(Py%s_CheckExact(sequence))) {" % sequence_types[0])
7692        for i, item in enumerate(self.unpacked_items):
7693            code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
7694                item.result(), sequence_types[0], i))
7695        if len(sequence_types) == 2:
7696            code.putln("} else {")
7697            for i, item in enumerate(self.unpacked_items):
7698                code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
7699                    item.result(), sequence_types[1], i))
7700            code.putln("}")
7701        for item in self.unpacked_items:
7702            code.put_incref(item.result(), item.ctype())
7703
7704        code.putln("#else")
7705        # in non-CPython, use the PySequence protocol (which can fail)
7706        if not use_loop:
7707            for i, item in enumerate(self.unpacked_items):
7708                code.putln("%s = PySequence_ITEM(sequence, %d); %s" % (
7709                    item.result(), i,
7710                    code.error_goto_if_null(item.result(), self.pos)))
7711                code.put_gotref(item.result())
7712        else:
7713            code.putln("{")
7714            code.putln("Py_ssize_t i;")
7715            code.putln("PyObject** temps[%s] = {%s};" % (
7716                len(self.unpacked_items),
7717                ','.join(['&%s' % item.result() for item in self.unpacked_items])))
7718            code.putln("for (i=0; i < %s; i++) {" % len(self.unpacked_items))
7719            code.putln("PyObject* item = PySequence_ITEM(sequence, i); %s" % (
7720                code.error_goto_if_null('item', self.pos)))
7721            code.put_gotref('item')
7722            code.putln("*(temps[i]) = item;")
7723            code.putln("}")
7724            code.putln("}")
7725
7726        code.putln("#endif")
7727        rhs.generate_disposal_code(code)
7728
7729        if sequence_type_test == '1':
7730            code.putln("}")  # all done
7731        elif sequence_type_test == none_check:
7732            # either tuple/list or None => save some code by generating the error directly
7733            code.putln("} else {")
7734            code.globalstate.use_utility_code(
7735                UtilityCode.load_cached("RaiseNoneIterError", "ObjectHandling.c"))
7736            code.putln("__Pyx_RaiseNoneNotIterableError(); %s" % code.error_goto(self.pos))
7737            code.putln("}")  # all done
7738        else:
7739            code.putln("} else {")  # needs iteration fallback code
7740            self.generate_generic_parallel_unpacking_code(
7741                code, rhs, self.unpacked_items, use_loop=use_loop)
7742            code.putln("}")
7743
7744    def generate_generic_parallel_unpacking_code(self, code, rhs, unpacked_items, use_loop, terminate=True):
7745        code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
7746        code.globalstate.use_utility_code(UtilityCode.load_cached("IterFinish", "ObjectHandling.c"))
7747        code.putln("Py_ssize_t index = -1;") # must be at the start of a C block!
7748
7749        if use_loop:
7750            code.putln("PyObject** temps[%s] = {%s};" % (
7751                len(self.unpacked_items),
7752                ','.join(['&%s' % item.result() for item in unpacked_items])))
7753
7754        iterator_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
7755        code.putln(
7756            "%s = PyObject_GetIter(%s); %s" % (
7757                iterator_temp,
7758                rhs.py_result(),
7759                code.error_goto_if_null(iterator_temp, self.pos)))
7760        code.put_gotref(iterator_temp)
7761        rhs.generate_disposal_code(code)
7762
7763        iternext_func = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
7764        code.putln("%s = Py_TYPE(%s)->tp_iternext;" % (
7765            iternext_func, iterator_temp))
7766
7767        unpacking_error_label = code.new_label('unpacking_failed')
7768        unpack_code = "%s(%s)" % (iternext_func, iterator_temp)
7769        if use_loop:
7770            code.putln("for (index=0; index < %s; index++) {" % len(unpacked_items))
7771            code.put("PyObject* item = %s; if (unlikely(!item)) " % unpack_code)
7772            code.put_goto(unpacking_error_label)
7773            code.put_gotref("item")
7774            code.putln("*(temps[index]) = item;")
7775            code.putln("}")
7776        else:
7777            for i, item in enumerate(unpacked_items):
7778                code.put(
7779                    "index = %d; %s = %s; if (unlikely(!%s)) " % (
7780                        i,
7781                        item.result(),
7782                        unpack_code,
7783                        item.result()))
7784                code.put_goto(unpacking_error_label)
7785                code.put_gotref(item.py_result())
7786
7787        if terminate:
7788            code.globalstate.use_utility_code(
7789                UtilityCode.load_cached("UnpackItemEndCheck", "ObjectHandling.c"))
7790            code.put_error_if_neg(self.pos, "__Pyx_IternextUnpackEndCheck(%s, %d)" % (
7791                unpack_code,
7792                len(unpacked_items)))
7793            code.putln("%s = NULL;" % iternext_func)
7794            code.put_decref_clear(iterator_temp, py_object_type)
7795
7796        unpacking_done_label = code.new_label('unpacking_done')
7797        code.put_goto(unpacking_done_label)
7798
7799        code.put_label(unpacking_error_label)
7800        code.put_decref_clear(iterator_temp, py_object_type)
7801        code.putln("%s = NULL;" % iternext_func)
7802        code.putln("if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);")
7803        code.putln(code.error_goto(self.pos))
7804        code.put_label(unpacking_done_label)
7805
7806        code.funcstate.release_temp(iternext_func)
7807        if terminate:
7808            code.funcstate.release_temp(iterator_temp)
7809            iterator_temp = None
7810
7811        return iterator_temp
7812
7813    def generate_starred_assignment_code(self, rhs, code):
7814        for i, arg in enumerate(self.args):
7815            if arg.is_starred:
7816                starred_target = self.unpacked_items[i]
7817                unpacked_fixed_items_left  = self.unpacked_items[:i]
7818                unpacked_fixed_items_right = self.unpacked_items[i+1:]
7819                break
7820        else:
7821            assert False
7822
7823        iterator_temp = None
7824        if unpacked_fixed_items_left:
7825            for item in unpacked_fixed_items_left:
7826                item.allocate(code)
7827            code.putln('{')
7828            iterator_temp = self.generate_generic_parallel_unpacking_code(
7829                code, rhs, unpacked_fixed_items_left,
7830                use_loop=True, terminate=False)
7831            for i, item in enumerate(unpacked_fixed_items_left):
7832                value_node = self.coerced_unpacked_items[i]
7833                value_node.generate_evaluation_code(code)
7834            code.putln('}')
7835
7836        starred_target.allocate(code)
7837        target_list = starred_target.result()
7838        code.putln("%s = PySequence_List(%s); %s" % (
7839            target_list,
7840            iterator_temp or rhs.py_result(),
7841            code.error_goto_if_null(target_list, self.pos)))
7842        code.put_gotref(target_list)
7843
7844        if iterator_temp:
7845            code.put_decref_clear(iterator_temp, py_object_type)
7846            code.funcstate.release_temp(iterator_temp)
7847        else:
7848            rhs.generate_disposal_code(code)
7849
7850        if unpacked_fixed_items_right:
7851            code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
7852            length_temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
7853            code.putln('%s = PyList_GET_SIZE(%s);' % (length_temp, target_list))
7854            code.putln("if (unlikely(%s < %d)) {" % (length_temp, len(unpacked_fixed_items_right)))
7855            code.putln("__Pyx_RaiseNeedMoreValuesError(%d+%s); %s" % (
7856                 len(unpacked_fixed_items_left), length_temp,
7857                 code.error_goto(self.pos)))
7858            code.putln('}')
7859
7860            for item in unpacked_fixed_items_right[::-1]:
7861                item.allocate(code)
7862            for i, (item, coerced_arg) in enumerate(zip(unpacked_fixed_items_right[::-1],
7863                                                        self.coerced_unpacked_items[::-1])):
7864                code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
7865                code.putln("%s = PyList_GET_ITEM(%s, %s-%d); " % (
7866                    item.py_result(), target_list, length_temp, i+1))
7867                # resize the list the hard way
7868                code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
7869                code.putln('#else')
7870                code.putln("%s = PySequence_ITEM(%s, %s-%d); " % (
7871                    item.py_result(), target_list, length_temp, i+1))
7872                code.putln('#endif')
7873                code.put_gotref(item.py_result())
7874                coerced_arg.generate_evaluation_code(code)
7875
7876            code.putln('#if !CYTHON_COMPILING_IN_CPYTHON')
7877            sublist_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
7878            code.putln('%s = PySequence_GetSlice(%s, 0, %s-%d); %s' % (
7879                sublist_temp, target_list, length_temp, len(unpacked_fixed_items_right),
7880                code.error_goto_if_null(sublist_temp, self.pos)))
7881            code.put_gotref(sublist_temp)
7882            code.funcstate.release_temp(length_temp)
7883            code.put_decref(target_list, py_object_type)
7884            code.putln('%s = %s; %s = NULL;' % (target_list, sublist_temp, sublist_temp))
7885            code.putln('#else')
7886            code.putln('(void)%s;' % sublist_temp)  # avoid warning about unused variable
7887            code.funcstate.release_temp(sublist_temp)
7888            code.putln('#endif')
7889
7890        for i, arg in enumerate(self.args):
7891            arg.generate_assignment_code(self.coerced_unpacked_items[i], code)
7892
7893    def annotate(self, code):
7894        for arg in self.args:
7895            arg.annotate(code)
7896        if self.unpacked_items:
7897            for arg in self.unpacked_items:
7898                arg.annotate(code)
7899            for arg in self.coerced_unpacked_items:
7900                arg.annotate(code)
7901
7902
7903class TupleNode(SequenceNode):
7904    #  Tuple constructor.
7905
7906    type = tuple_type
7907    is_partly_literal = False
7908
7909    gil_message = "Constructing Python tuple"
7910
7911    def infer_type(self, env):
7912        if self.mult_factor or not self.args:
7913            return tuple_type
7914        arg_types = [arg.infer_type(env) for arg in self.args]
7915        if any(type.is_pyobject or type.is_memoryviewslice or type.is_unspecified or type.is_fused
7916               for type in arg_types):
7917            return tuple_type
7918        return env.declare_tuple_type(self.pos, arg_types).type
7919
7920    def analyse_types(self, env, skip_children=False):
7921        if len(self.args) == 0:
7922            self.is_temp = False
7923            self.is_literal = True
7924            return self
7925
7926        if not skip_children:
7927            for i, arg in enumerate(self.args):
7928                if arg.is_starred:
7929                    arg.starred_expr_allowed_here = True
7930                self.args[i] = arg.analyse_types(env)
7931        if (not self.mult_factor and
7932                not any((arg.is_starred or arg.type.is_pyobject or arg.type.is_memoryviewslice or arg.type.is_fused)
7933                        for arg in self.args)):
7934            self.type = env.declare_tuple_type(self.pos, (arg.type for arg in self.args)).type
7935            self.is_temp = 1
7936            return self
7937
7938        node = SequenceNode.analyse_types(self, env, skip_children=True)
7939        node = node._create_merge_node_if_necessary(env)
7940        if not node.is_sequence_constructor:
7941            return node
7942
7943        if not all(child.is_literal for child in node.args):
7944            return node
7945        if not node.mult_factor or (
7946                node.mult_factor.is_literal and
7947                isinstance(node.mult_factor.constant_result, _py_int_types)):
7948            node.is_temp = False
7949            node.is_literal = True
7950        else:
7951            if not node.mult_factor.type.is_pyobject:
7952                node.mult_factor = node.mult_factor.coerce_to_pyobject(env)
7953            node.is_temp = True
7954            node.is_partly_literal = True
7955        return node
7956
7957    def analyse_as_type(self, env):
7958        # ctuple type
7959        if not self.args:
7960            return None
7961        item_types = [arg.analyse_as_type(env) for arg in self.args]
7962        if any(t is None for t in item_types):
7963            return None
7964        entry = env.declare_tuple_type(self.pos, item_types)
7965        return entry.type
7966
7967    def coerce_to(self, dst_type, env):
7968        if self.type.is_ctuple:
7969            if dst_type.is_ctuple and self.type.size == dst_type.size:
7970                return self.coerce_to_ctuple(dst_type, env)
7971            elif dst_type is tuple_type or dst_type is py_object_type:
7972                coerced_args = [arg.coerce_to_pyobject(env) for arg in self.args]
7973                return TupleNode(self.pos, args=coerced_args, type=tuple_type, is_temp=1).analyse_types(env, skip_children=True)
7974            else:
7975                return self.coerce_to_pyobject(env).coerce_to(dst_type, env)
7976        elif dst_type.is_ctuple and not self.mult_factor:
7977            return self.coerce_to_ctuple(dst_type, env)
7978        else:
7979            return SequenceNode.coerce_to(self, dst_type, env)
7980
7981    def as_list(self):
7982        t = ListNode(self.pos, args=self.args, mult_factor=self.mult_factor)
7983        if isinstance(self.constant_result, tuple):
7984            t.constant_result = list(self.constant_result)
7985        return t
7986
7987    def is_simple(self):
7988        # either temp or constant => always simple
7989        return True
7990
7991    def nonlocally_immutable(self):
7992        # either temp or constant => always safe
7993        return True
7994
7995    def calculate_result_code(self):
7996        if len(self.args) > 0:
7997            return self.result_code
7998        else:
7999            return Naming.empty_tuple
8000
8001    def calculate_constant_result(self):
8002        self.constant_result = tuple([
8003                arg.constant_result for arg in self.args])
8004
8005    def compile_time_value(self, denv):
8006        values = self.compile_time_value_list(denv)
8007        try:
8008            return tuple(values)
8009        except Exception as e:
8010            self.compile_time_value_error(e)
8011
8012    def generate_operation_code(self, code):
8013        if len(self.args) == 0:
8014            # result_code is Naming.empty_tuple
8015            return
8016
8017        if self.is_literal or self.is_partly_literal:
8018            # The "mult_factor" is part of the deduplication if it is also constant, i.e. when
8019            # we deduplicate the multiplied result.  Otherwise, only deduplicate the constant part.
8020            dedup_key = make_dedup_key(self.type, [self.mult_factor if self.is_literal else None] + self.args)
8021            tuple_target = code.get_py_const(py_object_type, 'tuple', cleanup_level=2, dedup_key=dedup_key)
8022            const_code = code.get_cached_constants_writer(tuple_target)
8023            if const_code is not None:
8024                # constant is not yet initialised
8025                const_code.mark_pos(self.pos)
8026                self.generate_sequence_packing_code(const_code, tuple_target, plain=not self.is_literal)
8027                const_code.put_giveref(tuple_target)
8028            if self.is_literal:
8029                self.result_code = tuple_target
8030            else:
8031                code.putln('%s = PyNumber_Multiply(%s, %s); %s' % (
8032                    self.result(), tuple_target, self.mult_factor.py_result(),
8033                    code.error_goto_if_null(self.result(), self.pos)
8034                ))
8035                code.put_gotref(self.py_result())
8036        else:
8037            self.type.entry.used = True
8038            self.generate_sequence_packing_code(code)
8039
8040
8041class ListNode(SequenceNode):
8042    #  List constructor.
8043
8044    # obj_conversion_errors    [PyrexError]   used internally
8045    # orignial_args            [ExprNode]     used internally
8046
8047    obj_conversion_errors = []
8048    type = list_type
8049    in_module_scope = False
8050
8051    gil_message = "Constructing Python list"
8052
8053    def type_dependencies(self, env):
8054        return ()
8055
8056    def infer_type(self, env):
8057        # TODO: Infer non-object list arrays.
8058        return list_type
8059
8060    def analyse_expressions(self, env):
8061        for arg in self.args:
8062            if arg.is_starred:
8063                arg.starred_expr_allowed_here = True
8064        node = SequenceNode.analyse_expressions(self, env)
8065        return node.coerce_to_pyobject(env)
8066
8067    def analyse_types(self, env):
8068        with local_errors(ignore=True) as errors:
8069            self.original_args = list(self.args)
8070            node = SequenceNode.analyse_types(self, env)
8071        node.obj_conversion_errors = errors
8072        if env.is_module_scope:
8073            self.in_module_scope = True
8074        node = node._create_merge_node_if_necessary(env)
8075        return node
8076
8077    def coerce_to(self, dst_type, env):
8078        if dst_type.is_pyobject:
8079            for err in self.obj_conversion_errors:
8080                report_error(err)
8081            self.obj_conversion_errors = []
8082            if not self.type.subtype_of(dst_type):
8083                error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
8084        elif (dst_type.is_array or dst_type.is_ptr) and dst_type.base_type is not PyrexTypes.c_void_type:
8085            array_length = len(self.args)
8086            if self.mult_factor:
8087                if isinstance(self.mult_factor.constant_result, _py_int_types):
8088                    if self.mult_factor.constant_result <= 0:
8089                        error(self.pos, "Cannot coerce non-positively multiplied list to '%s'" % dst_type)
8090                    else:
8091                        array_length *= self.mult_factor.constant_result
8092                else:
8093                    error(self.pos, "Cannot coerce dynamically multiplied list to '%s'" % dst_type)
8094            base_type = dst_type.base_type
8095            self.type = PyrexTypes.CArrayType(base_type, array_length)
8096            for i in range(len(self.original_args)):
8097                arg = self.args[i]
8098                if isinstance(arg, CoerceToPyTypeNode):
8099                    arg = arg.arg
8100                self.args[i] = arg.coerce_to(base_type, env)
8101        elif dst_type.is_cpp_class:
8102            # TODO(robertwb): Avoid object conversion for vector/list/set.
8103            return TypecastNode(self.pos, operand=self, type=PyrexTypes.py_object_type).coerce_to(dst_type, env)
8104        elif self.mult_factor:
8105            error(self.pos, "Cannot coerce multiplied list to '%s'" % dst_type)
8106        elif dst_type.is_struct:
8107            if len(self.args) > len(dst_type.scope.var_entries):
8108                error(self.pos, "Too many members for '%s'" % dst_type)
8109            else:
8110                if len(self.args) < len(dst_type.scope.var_entries):
8111                    warning(self.pos, "Too few members for '%s'" % dst_type, 1)
8112                for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
8113                    if isinstance(arg, CoerceToPyTypeNode):
8114                        arg = arg.arg
8115                    self.args[i] = arg.coerce_to(member.type, env)
8116            self.type = dst_type
8117        elif dst_type.is_ctuple:
8118            return self.coerce_to_ctuple(dst_type, env)
8119        else:
8120            self.type = error_type
8121            error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
8122        return self
8123
8124    def as_list(self):  # dummy for compatibility with TupleNode
8125        return self
8126
8127    def as_tuple(self):
8128        t = TupleNode(self.pos, args=self.args, mult_factor=self.mult_factor)
8129        if isinstance(self.constant_result, list):
8130            t.constant_result = tuple(self.constant_result)
8131        return t
8132
8133    def allocate_temp_result(self, code):
8134        if self.type.is_array:
8135            if self.in_module_scope:
8136                self.temp_code = code.funcstate.allocate_temp(
8137                    self.type, manage_ref=False, static=True, reusable=False)
8138            else:
8139                # To be valid C++, we must allocate the memory on the stack
8140                # manually and be sure not to reuse it for something else.
8141                # Yes, this means that we leak a temp array variable.
8142                self.temp_code = code.funcstate.allocate_temp(
8143                    self.type, manage_ref=False, reusable=False)
8144        else:
8145            SequenceNode.allocate_temp_result(self, code)
8146
8147    def calculate_constant_result(self):
8148        if self.mult_factor:
8149            raise ValueError()  # may exceed the compile time memory
8150        self.constant_result = [
8151            arg.constant_result for arg in self.args]
8152
8153    def compile_time_value(self, denv):
8154        l = self.compile_time_value_list(denv)
8155        if self.mult_factor:
8156            l *= self.mult_factor.compile_time_value(denv)
8157        return l
8158
8159    def generate_operation_code(self, code):
8160        if self.type.is_pyobject:
8161            for err in self.obj_conversion_errors:
8162                report_error(err)
8163            self.generate_sequence_packing_code(code)
8164        elif self.type.is_array:
8165            if self.mult_factor:
8166                code.putln("{")
8167                code.putln("Py_ssize_t %s;" % Naming.quick_temp_cname)
8168                code.putln("for ({i} = 0; {i} < {count}; {i}++) {{".format(
8169                    i=Naming.quick_temp_cname, count=self.mult_factor.result()))
8170                offset = '+ (%d * %s)' % (len(self.args), Naming.quick_temp_cname)
8171            else:
8172                offset = ''
8173            for i, arg in enumerate(self.args):
8174                if arg.type.is_array:
8175                    code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
8176                    code.putln("memcpy(&(%s[%s%s]), %s, sizeof(%s[0]));" % (
8177                        self.result(), i, offset,
8178                        arg.result(), self.result()
8179                    ))
8180                else:
8181                    code.putln("%s[%s%s] = %s;" % (
8182                        self.result(),
8183                        i,
8184                        offset,
8185                        arg.result()))
8186            if self.mult_factor:
8187                code.putln("}")
8188                code.putln("}")
8189        elif self.type.is_struct:
8190            for arg, member in zip(self.args, self.type.scope.var_entries):
8191                code.putln("%s.%s = %s;" % (
8192                    self.result(),
8193                    member.cname,
8194                    arg.result()))
8195        else:
8196            raise InternalError("List type never specified")
8197
8198
8199class ScopedExprNode(ExprNode):
8200    # Abstract base class for ExprNodes that have their own local
8201    # scope, such as generator expressions.
8202    #
8203    # expr_scope    Scope  the inner scope of the expression
8204
8205    subexprs = []
8206    expr_scope = None
8207
8208    # does this node really have a local scope, e.g. does it leak loop
8209    # variables or not?  non-leaking Py3 behaviour is default, except
8210    # for list comprehensions where the behaviour differs in Py2 and
8211    # Py3 (set in Parsing.py based on parser context)
8212    has_local_scope = True
8213
8214    def init_scope(self, outer_scope, expr_scope=None):
8215        if expr_scope is not None:
8216            self.expr_scope = expr_scope
8217        elif self.has_local_scope:
8218            self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
8219        else:
8220            self.expr_scope = None
8221
8222    def analyse_declarations(self, env):
8223        self.init_scope(env)
8224
8225    def analyse_scoped_declarations(self, env):
8226        # this is called with the expr_scope as env
8227        pass
8228
8229    def analyse_types(self, env):
8230        # no recursion here, the children will be analysed separately below
8231        return self
8232
8233    def analyse_scoped_expressions(self, env):
8234        # this is called with the expr_scope as env
8235        return self
8236
8237    def generate_evaluation_code(self, code):
8238        # set up local variables and free their references on exit
8239        generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
8240        if not self.has_local_scope or not self.expr_scope.var_entries:
8241            # no local variables => delegate, done
8242            generate_inner_evaluation_code(code)
8243            return
8244
8245        code.putln('{ /* enter inner scope */')
8246        py_entries = []
8247        for _, entry in sorted(item for item in self.expr_scope.entries.items() if item[0]):
8248            if not entry.in_closure:
8249                if entry.type.is_pyobject and entry.used:
8250                    py_entries.append(entry)
8251        if not py_entries:
8252            # no local Python references => no cleanup required
8253            generate_inner_evaluation_code(code)
8254            code.putln('} /* exit inner scope */')
8255            return
8256
8257        # must free all local Python references at each exit point
8258        old_loop_labels = code.new_loop_labels()
8259        old_error_label = code.new_error_label()
8260
8261        generate_inner_evaluation_code(code)
8262
8263        # normal (non-error) exit
8264        self._generate_vars_cleanup(code, py_entries)
8265
8266        # error/loop body exit points
8267        exit_scope = code.new_label('exit_scope')
8268        code.put_goto(exit_scope)
8269        for label, old_label in ([(code.error_label, old_error_label)] +
8270                                 list(zip(code.get_loop_labels(), old_loop_labels))):
8271            if code.label_used(label):
8272                code.put_label(label)
8273                self._generate_vars_cleanup(code, py_entries)
8274                code.put_goto(old_label)
8275        code.put_label(exit_scope)
8276        code.putln('} /* exit inner scope */')
8277
8278        code.set_loop_labels(old_loop_labels)
8279        code.error_label = old_error_label
8280
8281    def _generate_vars_cleanup(self, code, py_entries):
8282        for entry in py_entries:
8283            if entry.is_cglobal:
8284                code.put_var_gotref(entry)
8285                code.put_decref_set(entry.cname, "Py_None")
8286            else:
8287                code.put_var_xdecref_clear(entry)
8288
8289
8290class ComprehensionNode(ScopedExprNode):
8291    # A list/set/dict comprehension
8292
8293    child_attrs = ["loop"]
8294
8295    is_temp = True
8296    constant_result = not_a_constant
8297
8298    def infer_type(self, env):
8299        return self.type
8300
8301    def analyse_declarations(self, env):
8302        self.append.target = self # this is used in the PyList_Append of the inner loop
8303        self.init_scope(env)
8304
8305    def analyse_scoped_declarations(self, env):
8306        self.loop.analyse_declarations(env)
8307
8308    def analyse_types(self, env):
8309        if not self.has_local_scope:
8310            self.loop = self.loop.analyse_expressions(env)
8311        return self
8312
8313    def analyse_scoped_expressions(self, env):
8314        if self.has_local_scope:
8315            self.loop = self.loop.analyse_expressions(env)
8316        return self
8317
8318    def may_be_none(self):
8319        return False
8320
8321    def generate_result_code(self, code):
8322        self.generate_operation_code(code)
8323
8324    def generate_operation_code(self, code):
8325        if self.type is Builtin.list_type:
8326            create_code = 'PyList_New(0)'
8327        elif self.type is Builtin.set_type:
8328            create_code = 'PySet_New(NULL)'
8329        elif self.type is Builtin.dict_type:
8330            create_code = 'PyDict_New()'
8331        else:
8332            raise InternalError("illegal type for comprehension: %s" % self.type)
8333        code.putln('%s = %s; %s' % (
8334            self.result(), create_code,
8335            code.error_goto_if_null(self.result(), self.pos)))
8336
8337        code.put_gotref(self.result())
8338        self.loop.generate_execution_code(code)
8339
8340    def annotate(self, code):
8341        self.loop.annotate(code)
8342
8343
8344class ComprehensionAppendNode(Node):
8345    # Need to be careful to avoid infinite recursion:
8346    # target must not be in child_attrs/subexprs
8347
8348    child_attrs = ['expr']
8349    target = None
8350
8351    type = PyrexTypes.c_int_type
8352
8353    def analyse_expressions(self, env):
8354        self.expr = self.expr.analyse_expressions(env)
8355        if not self.expr.type.is_pyobject:
8356            self.expr = self.expr.coerce_to_pyobject(env)
8357        return self
8358
8359    def generate_execution_code(self, code):
8360        if self.target.type is list_type:
8361            code.globalstate.use_utility_code(
8362                UtilityCode.load_cached("ListCompAppend", "Optimize.c"))
8363            function = "__Pyx_ListComp_Append"
8364        elif self.target.type is set_type:
8365            function = "PySet_Add"
8366        else:
8367            raise InternalError(
8368                "Invalid type for comprehension node: %s" % self.target.type)
8369
8370        self.expr.generate_evaluation_code(code)
8371        code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
8372            function,
8373            self.target.result(),
8374            self.expr.result()
8375            ), self.pos))
8376        self.expr.generate_disposal_code(code)
8377        self.expr.free_temps(code)
8378
8379    def generate_function_definitions(self, env, code):
8380        self.expr.generate_function_definitions(env, code)
8381
8382    def annotate(self, code):
8383        self.expr.annotate(code)
8384
8385class DictComprehensionAppendNode(ComprehensionAppendNode):
8386    child_attrs = ['key_expr', 'value_expr']
8387
8388    def analyse_expressions(self, env):
8389        self.key_expr = self.key_expr.analyse_expressions(env)
8390        if not self.key_expr.type.is_pyobject:
8391            self.key_expr = self.key_expr.coerce_to_pyobject(env)
8392        self.value_expr = self.value_expr.analyse_expressions(env)
8393        if not self.value_expr.type.is_pyobject:
8394            self.value_expr = self.value_expr.coerce_to_pyobject(env)
8395        return self
8396
8397    def generate_execution_code(self, code):
8398        self.key_expr.generate_evaluation_code(code)
8399        self.value_expr.generate_evaluation_code(code)
8400        code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
8401            self.target.result(),
8402            self.key_expr.result(),
8403            self.value_expr.result()
8404            ), self.pos))
8405        self.key_expr.generate_disposal_code(code)
8406        self.key_expr.free_temps(code)
8407        self.value_expr.generate_disposal_code(code)
8408        self.value_expr.free_temps(code)
8409
8410    def generate_function_definitions(self, env, code):
8411        self.key_expr.generate_function_definitions(env, code)
8412        self.value_expr.generate_function_definitions(env, code)
8413
8414    def annotate(self, code):
8415        self.key_expr.annotate(code)
8416        self.value_expr.annotate(code)
8417
8418
8419class InlinedGeneratorExpressionNode(ExprNode):
8420    # An inlined generator expression for which the result is calculated
8421    # inside of the loop and returned as a single, first and only Generator
8422    # return value.
8423    # This will only be created by transforms when replacing safe builtin
8424    # calls on generator expressions.
8425    #
8426    # gen            GeneratorExpressionNode      the generator, not containing any YieldExprNodes
8427    # orig_func      String                       the name of the builtin function this node replaces
8428    # target         ExprNode or None             a 'target' for a ComprehensionAppend node
8429
8430    subexprs = ["gen"]
8431    orig_func = None
8432    target = None
8433    is_temp = True
8434    type = py_object_type
8435
8436    def __init__(self, pos, gen, comprehension_type=None, **kwargs):
8437        gbody = gen.def_node.gbody
8438        gbody.is_inlined = True
8439        if comprehension_type is not None:
8440            assert comprehension_type in (list_type, set_type, dict_type), comprehension_type
8441            gbody.inlined_comprehension_type = comprehension_type
8442            kwargs.update(
8443                target=RawCNameExprNode(pos, comprehension_type, Naming.retval_cname),
8444                type=comprehension_type,
8445            )
8446        super(InlinedGeneratorExpressionNode, self).__init__(pos, gen=gen, **kwargs)
8447
8448    def may_be_none(self):
8449        return self.orig_func not in ('any', 'all', 'sorted')
8450
8451    def infer_type(self, env):
8452        return self.type
8453
8454    def analyse_types(self, env):
8455        self.gen = self.gen.analyse_expressions(env)
8456        return self
8457
8458    def generate_result_code(self, code):
8459        code.putln("%s = __Pyx_Generator_Next(%s); %s" % (
8460            self.result(), self.gen.result(),
8461            code.error_goto_if_null(self.result(), self.pos)))
8462        code.put_gotref(self.result())
8463
8464
8465class MergedSequenceNode(ExprNode):
8466    """
8467    Merge a sequence of iterables into a set/list/tuple.
8468
8469    The target collection is determined by self.type, which must be set externally.
8470
8471    args    [ExprNode]
8472    """
8473    subexprs = ['args']
8474    is_temp = True
8475    gil_message = "Constructing Python collection"
8476
8477    def __init__(self, pos, args, type):
8478        if type in (list_type, tuple_type) and args and args[0].is_sequence_constructor:
8479            # construct a list directly from the first argument that we can then extend
8480            if args[0].type is not list_type:
8481                args[0] = ListNode(args[0].pos, args=args[0].args, is_temp=True)
8482        ExprNode.__init__(self, pos, args=args, type=type)
8483
8484    def calculate_constant_result(self):
8485        result = []
8486        for item in self.args:
8487            if item.is_sequence_constructor and item.mult_factor:
8488                if item.mult_factor.constant_result <= 0:
8489                    continue
8490                # otherwise, adding each item once should be enough
8491            if item.is_set_literal or item.is_sequence_constructor:
8492                # process items in order
8493                items = (arg.constant_result for arg in item.args)
8494            else:
8495                items = item.constant_result
8496            result.extend(items)
8497        if self.type is set_type:
8498            result = set(result)
8499        elif self.type is tuple_type:
8500            result = tuple(result)
8501        else:
8502            assert self.type is list_type
8503        self.constant_result = result
8504
8505    def compile_time_value(self, denv):
8506        result = []
8507        for item in self.args:
8508            if item.is_sequence_constructor and item.mult_factor:
8509                if item.mult_factor.compile_time_value(denv) <= 0:
8510                    continue
8511            if item.is_set_literal or item.is_sequence_constructor:
8512                # process items in order
8513                items = (arg.compile_time_value(denv) for arg in item.args)
8514            else:
8515                items = item.compile_time_value(denv)
8516            result.extend(items)
8517        if self.type is set_type:
8518            try:
8519                result = set(result)
8520            except Exception as e:
8521                self.compile_time_value_error(e)
8522        elif self.type is tuple_type:
8523            result = tuple(result)
8524        else:
8525            assert self.type is list_type
8526        return result
8527
8528    def type_dependencies(self, env):
8529        return ()
8530
8531    def infer_type(self, env):
8532        return self.type
8533
8534    def analyse_types(self, env):
8535        args = [
8536            arg.analyse_types(env).coerce_to_pyobject(env).as_none_safe_node(
8537                # FIXME: CPython's error message starts with the runtime function name
8538                'argument after * must be an iterable, not NoneType')
8539            for arg in self.args
8540        ]
8541
8542        if len(args) == 1 and args[0].type is self.type:
8543            # strip this intermediate node and use the bare collection
8544            return args[0]
8545
8546        assert self.type in (set_type, list_type, tuple_type)
8547
8548        self.args = args
8549        return self
8550
8551    def may_be_none(self):
8552        return False
8553
8554    def generate_evaluation_code(self, code):
8555        code.mark_pos(self.pos)
8556        self.allocate_temp_result(code)
8557
8558        is_set = self.type is set_type
8559
8560        args = iter(self.args)
8561        item = next(args)
8562        item.generate_evaluation_code(code)
8563        if (is_set and item.is_set_literal or
8564                not is_set and item.is_sequence_constructor and item.type is list_type):
8565            code.putln("%s = %s;" % (self.result(), item.py_result()))
8566            item.generate_post_assignment_code(code)
8567        else:
8568            code.putln("%s = %s(%s); %s" % (
8569                self.result(),
8570                'PySet_New' if is_set else 'PySequence_List',
8571                item.py_result(),
8572                code.error_goto_if_null(self.result(), self.pos)))
8573            code.put_gotref(self.py_result())
8574            item.generate_disposal_code(code)
8575        item.free_temps(code)
8576
8577        helpers = set()
8578        if is_set:
8579            add_func = "PySet_Add"
8580            extend_func = "__Pyx_PySet_Update"
8581        else:
8582            add_func = "__Pyx_ListComp_Append"
8583            extend_func = "__Pyx_PyList_Extend"
8584
8585        for item in args:
8586            if (is_set and (item.is_set_literal or item.is_sequence_constructor) or
8587                    (item.is_sequence_constructor and not item.mult_factor)):
8588                if not is_set and item.args:
8589                    helpers.add(("ListCompAppend", "Optimize.c"))
8590                for arg in item.args:
8591                    arg.generate_evaluation_code(code)
8592                    code.put_error_if_neg(arg.pos, "%s(%s, %s)" % (
8593                        add_func,
8594                        self.result(),
8595                        arg.py_result()))
8596                    arg.generate_disposal_code(code)
8597                    arg.free_temps(code)
8598                continue
8599
8600            if is_set:
8601                helpers.add(("PySet_Update", "Builtins.c"))
8602            else:
8603                helpers.add(("ListExtend", "Optimize.c"))
8604
8605            item.generate_evaluation_code(code)
8606            code.put_error_if_neg(item.pos, "%s(%s, %s)" % (
8607                extend_func,
8608                self.result(),
8609                item.py_result()))
8610            item.generate_disposal_code(code)
8611            item.free_temps(code)
8612
8613        if self.type is tuple_type:
8614            code.putln("{")
8615            code.putln("PyObject *%s = PyList_AsTuple(%s);" % (
8616                Naming.quick_temp_cname,
8617                self.result()))
8618            code.put_decref(self.result(), py_object_type)
8619            code.putln("%s = %s; %s" % (
8620                self.result(),
8621                Naming.quick_temp_cname,
8622                code.error_goto_if_null(self.result(), self.pos)))
8623            code.put_gotref(self.result())
8624            code.putln("}")
8625
8626        for helper in sorted(helpers):
8627            code.globalstate.use_utility_code(UtilityCode.load_cached(*helper))
8628
8629    def annotate(self, code):
8630        for item in self.args:
8631            item.annotate(code)
8632
8633
8634class SetNode(ExprNode):
8635    """
8636    Set constructor.
8637    """
8638    subexprs = ['args']
8639    type = set_type
8640    is_set_literal = True
8641    gil_message = "Constructing Python set"
8642
8643    def analyse_types(self, env):
8644        for i in range(len(self.args)):
8645            arg = self.args[i]
8646            arg = arg.analyse_types(env)
8647            self.args[i] = arg.coerce_to_pyobject(env)
8648        self.type = set_type
8649        self.is_temp = 1
8650        return self
8651
8652    def may_be_none(self):
8653        return False
8654
8655    def calculate_constant_result(self):
8656        self.constant_result = set([arg.constant_result for arg in self.args])
8657
8658    def compile_time_value(self, denv):
8659        values = [arg.compile_time_value(denv) for arg in self.args]
8660        try:
8661            return set(values)
8662        except Exception as e:
8663            self.compile_time_value_error(e)
8664
8665    def generate_evaluation_code(self, code):
8666        for arg in self.args:
8667            arg.generate_evaluation_code(code)
8668        self.allocate_temp_result(code)
8669        code.putln(
8670            "%s = PySet_New(0); %s" % (
8671                self.result(),
8672                code.error_goto_if_null(self.result(), self.pos)))
8673        code.put_gotref(self.py_result())
8674        for arg in self.args:
8675            code.put_error_if_neg(
8676                self.pos,
8677                "PySet_Add(%s, %s)" % (self.result(), arg.py_result()))
8678            arg.generate_disposal_code(code)
8679            arg.free_temps(code)
8680
8681
8682class DictNode(ExprNode):
8683    #  Dictionary constructor.
8684    #
8685    #  key_value_pairs     [DictItemNode]
8686    #  exclude_null_values [boolean]          Do not add NULL values to dict
8687    #
8688    # obj_conversion_errors    [PyrexError]   used internally
8689
8690    subexprs = ['key_value_pairs']
8691    is_temp = 1
8692    exclude_null_values = False
8693    type = dict_type
8694    is_dict_literal = True
8695    reject_duplicates = False
8696
8697    obj_conversion_errors = []
8698
8699    @classmethod
8700    def from_pairs(cls, pos, pairs):
8701        return cls(pos, key_value_pairs=[
8702                DictItemNode(pos, key=k, value=v) for k, v in pairs])
8703
8704    def calculate_constant_result(self):
8705        self.constant_result = dict([
8706                item.constant_result for item in self.key_value_pairs])
8707
8708    def compile_time_value(self, denv):
8709        pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
8710            for item in self.key_value_pairs]
8711        try:
8712            return dict(pairs)
8713        except Exception as e:
8714            self.compile_time_value_error(e)
8715
8716    def type_dependencies(self, env):
8717        return ()
8718
8719    def infer_type(self, env):
8720        # TODO: Infer struct constructors.
8721        return dict_type
8722
8723    def analyse_types(self, env):
8724        with local_errors(ignore=True) as errors:
8725            self.key_value_pairs = [
8726                item.analyse_types(env)
8727                for item in self.key_value_pairs
8728            ]
8729        self.obj_conversion_errors = errors
8730        return self
8731
8732    def may_be_none(self):
8733        return False
8734
8735    def coerce_to(self, dst_type, env):
8736        if dst_type.is_pyobject:
8737            self.release_errors()
8738            if self.type.is_struct_or_union:
8739                if not dict_type.subtype_of(dst_type):
8740                    error(self.pos, "Cannot interpret struct as non-dict type '%s'" % dst_type)
8741                return DictNode(self.pos, key_value_pairs=[
8742                    DictItemNode(item.pos, key=item.key.coerce_to_pyobject(env),
8743                                 value=item.value.coerce_to_pyobject(env))
8744                    for item in self.key_value_pairs])
8745            if not self.type.subtype_of(dst_type):
8746                error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
8747        elif dst_type.is_struct_or_union:
8748            self.type = dst_type
8749            if not dst_type.is_struct and len(self.key_value_pairs) != 1:
8750                error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
8751            elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
8752                warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
8753            for item in self.key_value_pairs:
8754                if isinstance(item.key, CoerceToPyTypeNode):
8755                    item.key = item.key.arg
8756                if not item.key.is_string_literal:
8757                    error(item.key.pos, "Invalid struct field identifier")
8758                    item.key = StringNode(item.key.pos, value="<error>")
8759                else:
8760                    key = str(item.key.value) # converts string literals to unicode in Py3
8761                    member = dst_type.scope.lookup_here(key)
8762                    if not member:
8763                        error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
8764                    else:
8765                        value = item.value
8766                        if isinstance(value, CoerceToPyTypeNode):
8767                            value = value.arg
8768                        item.value = value.coerce_to(member.type, env)
8769        else:
8770            self.type = error_type
8771            error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
8772        return self
8773
8774    def release_errors(self):
8775        for err in self.obj_conversion_errors:
8776            report_error(err)
8777        self.obj_conversion_errors = []
8778
8779    gil_message = "Constructing Python dict"
8780
8781    def generate_evaluation_code(self, code):
8782        #  Custom method used here because key-value
8783        #  pairs are evaluated and used one at a time.
8784        code.mark_pos(self.pos)
8785        self.allocate_temp_result(code)
8786
8787        is_dict = self.type.is_pyobject
8788        if is_dict:
8789            self.release_errors()
8790            code.putln(
8791                "%s = __Pyx_PyDict_NewPresized(%d); %s" % (
8792                    self.result(),
8793                    len(self.key_value_pairs),
8794                    code.error_goto_if_null(self.result(), self.pos)))
8795            code.put_gotref(self.py_result())
8796
8797        keys_seen = set()
8798        key_type = None
8799        needs_error_helper = False
8800
8801        for item in self.key_value_pairs:
8802            item.generate_evaluation_code(code)
8803            if is_dict:
8804                if self.exclude_null_values:
8805                    code.putln('if (%s) {' % item.value.py_result())
8806                key = item.key
8807                if self.reject_duplicates:
8808                    if keys_seen is not None:
8809                        # avoid runtime 'in' checks for literals that we can do at compile time
8810                        if not key.is_string_literal:
8811                            keys_seen = None
8812                        elif key.value in keys_seen:
8813                            # FIXME: this could be a compile time error, at least in Cython code
8814                            keys_seen = None
8815                        elif key_type is not type(key.value):
8816                            if key_type is None:
8817                                key_type = type(key.value)
8818                                keys_seen.add(key.value)
8819                            else:
8820                                # different types => may not be able to compare at compile time
8821                                keys_seen = None
8822                        else:
8823                            keys_seen.add(key.value)
8824
8825                    if keys_seen is None:
8826                        code.putln('if (unlikely(PyDict_Contains(%s, %s))) {' % (
8827                            self.result(), key.py_result()))
8828                        # currently only used in function calls
8829                        needs_error_helper = True
8830                        code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
8831                            key.py_result(),
8832                            code.error_goto(item.pos)))
8833                        code.putln("} else {")
8834
8835                code.put_error_if_neg(self.pos, "PyDict_SetItem(%s, %s, %s)" % (
8836                    self.result(),
8837                    item.key.py_result(),
8838                    item.value.py_result()))
8839                if self.reject_duplicates and keys_seen is None:
8840                    code.putln('}')
8841                if self.exclude_null_values:
8842                    code.putln('}')
8843            else:
8844                code.putln("%s.%s = %s;" % (
8845                        self.result(),
8846                        item.key.value,
8847                        item.value.result()))
8848            item.generate_disposal_code(code)
8849            item.free_temps(code)
8850
8851        if needs_error_helper:
8852            code.globalstate.use_utility_code(
8853                UtilityCode.load_cached("RaiseDoubleKeywords", "FunctionArguments.c"))
8854
8855    def annotate(self, code):
8856        for item in self.key_value_pairs:
8857            item.annotate(code)
8858
8859
8860class DictItemNode(ExprNode):
8861    # Represents a single item in a DictNode
8862    #
8863    # key          ExprNode
8864    # value        ExprNode
8865    subexprs = ['key', 'value']
8866
8867    nogil_check = None # Parent DictNode takes care of it
8868
8869    def calculate_constant_result(self):
8870        self.constant_result = (
8871            self.key.constant_result, self.value.constant_result)
8872
8873    def analyse_types(self, env):
8874        self.key = self.key.analyse_types(env)
8875        self.value = self.value.analyse_types(env)
8876        self.key = self.key.coerce_to_pyobject(env)
8877        self.value = self.value.coerce_to_pyobject(env)
8878        return self
8879
8880    def generate_evaluation_code(self, code):
8881        self.key.generate_evaluation_code(code)
8882        self.value.generate_evaluation_code(code)
8883
8884    def generate_disposal_code(self, code):
8885        self.key.generate_disposal_code(code)
8886        self.value.generate_disposal_code(code)
8887
8888    def free_temps(self, code):
8889        self.key.free_temps(code)
8890        self.value.free_temps(code)
8891
8892    def __iter__(self):
8893        return iter([self.key, self.value])
8894
8895
8896class SortedDictKeysNode(ExprNode):
8897    # build sorted list of dict keys, e.g. for dir()
8898    subexprs = ['arg']
8899
8900    is_temp = True
8901
8902    def __init__(self, arg):
8903        ExprNode.__init__(self, arg.pos, arg=arg)
8904        self.type = Builtin.list_type
8905
8906    def analyse_types(self, env):
8907        arg = self.arg.analyse_types(env)
8908        if arg.type is Builtin.dict_type:
8909            arg = arg.as_none_safe_node(
8910                "'NoneType' object is not iterable")
8911        self.arg = arg
8912        return self
8913
8914    def may_be_none(self):
8915        return False
8916
8917    def generate_result_code(self, code):
8918        dict_result = self.arg.py_result()
8919        if self.arg.type is Builtin.dict_type:
8920            code.putln('%s = PyDict_Keys(%s); %s' % (
8921                self.result(), dict_result,
8922                code.error_goto_if_null(self.result(), self.pos)))
8923            code.put_gotref(self.py_result())
8924        else:
8925            # originally used PyMapping_Keys() here, but that may return a tuple
8926            code.globalstate.use_utility_code(UtilityCode.load_cached(
8927                'PyObjectCallMethod0', 'ObjectHandling.c'))
8928            keys_cname = code.intern_identifier(StringEncoding.EncodedString("keys"))
8929            code.putln('%s = __Pyx_PyObject_CallMethod0(%s, %s); %s' % (
8930                self.result(), dict_result, keys_cname,
8931                code.error_goto_if_null(self.result(), self.pos)))
8932            code.put_gotref(self.py_result())
8933            code.putln("if (unlikely(!PyList_Check(%s))) {" % self.result())
8934            code.put_decref_set(self.result(), "PySequence_List(%s)" % self.result())
8935            code.putln(code.error_goto_if_null(self.result(), self.pos))
8936            code.put_gotref(self.py_result())
8937            code.putln("}")
8938        code.put_error_if_neg(
8939            self.pos, 'PyList_Sort(%s)' % self.py_result())
8940
8941
8942class ModuleNameMixin(object):
8943    def get_py_mod_name(self, code):
8944        return code.get_py_string_const(
8945            self.module_name, identifier=True)
8946
8947    def get_py_qualified_name(self, code):
8948        return code.get_py_string_const(
8949            self.qualname, identifier=True)
8950
8951
8952class ClassNode(ExprNode, ModuleNameMixin):
8953    #  Helper class used in the implementation of Python
8954    #  class definitions. Constructs a class object given
8955    #  a name, tuple of bases and class dictionary.
8956    #
8957    #  name         EncodedString      Name of the class
8958    #  class_def_node  PyClassDefNode  PyClassDefNode defining this class
8959    #  doc          ExprNode or None   Doc string
8960    #  module_name  EncodedString      Name of defining module
8961
8962    subexprs = ['doc']
8963    type = py_object_type
8964    is_temp = True
8965
8966    def infer_type(self, env):
8967        # TODO: could return 'type' in some cases
8968        return py_object_type
8969
8970    def analyse_types(self, env):
8971        if self.doc:
8972            self.doc = self.doc.analyse_types(env)
8973            self.doc = self.doc.coerce_to_pyobject(env)
8974        env.use_utility_code(UtilityCode.load_cached("CreateClass", "ObjectHandling.c"))
8975        return self
8976
8977    def may_be_none(self):
8978        return True
8979
8980    gil_message = "Constructing Python class"
8981
8982    def generate_result_code(self, code):
8983        class_def_node = self.class_def_node
8984        cname = code.intern_identifier(self.name)
8985
8986        if self.doc:
8987            code.put_error_if_neg(self.pos,
8988                'PyDict_SetItem(%s, %s, %s)' % (
8989                    class_def_node.dict.py_result(),
8990                    code.intern_identifier(
8991                        StringEncoding.EncodedString("__doc__")),
8992                    self.doc.py_result()))
8993        py_mod_name = self.get_py_mod_name(code)
8994        qualname = self.get_py_qualified_name(code)
8995        code.putln(
8996            '%s = __Pyx_CreateClass(%s, %s, %s, %s, %s); %s' % (
8997                self.result(),
8998                class_def_node.bases.py_result(),
8999                class_def_node.dict.py_result(),
9000                cname,
9001                qualname,
9002                py_mod_name,
9003                code.error_goto_if_null(self.result(), self.pos)))
9004        code.put_gotref(self.py_result())
9005
9006
9007class Py3ClassNode(ExprNode):
9008    #  Helper class used in the implementation of Python3+
9009    #  class definitions. Constructs a class object given
9010    #  a name, tuple of bases and class dictionary.
9011    #
9012    #  name         EncodedString      Name of the class
9013    #  module_name  EncodedString      Name of defining module
9014    #  class_def_node  PyClassDefNode  PyClassDefNode defining this class
9015    #  calculate_metaclass  bool       should call CalculateMetaclass()
9016    #  allow_py2_metaclass  bool       should look for Py2 metaclass
9017
9018    subexprs = []
9019    type = py_object_type
9020    is_temp = True
9021
9022    def infer_type(self, env):
9023        # TODO: could return 'type' in some cases
9024        return py_object_type
9025
9026    def analyse_types(self, env):
9027        return self
9028
9029    def may_be_none(self):
9030        return True
9031
9032    gil_message = "Constructing Python class"
9033
9034    def generate_result_code(self, code):
9035        code.globalstate.use_utility_code(UtilityCode.load_cached("Py3ClassCreate", "ObjectHandling.c"))
9036        cname = code.intern_identifier(self.name)
9037        class_def_node = self.class_def_node
9038        mkw = class_def_node.mkw.py_result() if class_def_node.mkw else 'NULL'
9039        if class_def_node.metaclass:
9040            metaclass = class_def_node.metaclass.py_result()
9041        else:
9042            metaclass = "((PyObject*)&__Pyx_DefaultClassType)"
9043        code.putln(
9044            '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s, %d, %d); %s' % (
9045                self.result(),
9046                metaclass,
9047                cname,
9048                class_def_node.bases.py_result(),
9049                class_def_node.dict.py_result(),
9050                mkw,
9051                self.calculate_metaclass,
9052                self.allow_py2_metaclass,
9053                code.error_goto_if_null(self.result(), self.pos)))
9054        code.put_gotref(self.py_result())
9055
9056
9057class PyClassMetaclassNode(ExprNode):
9058    # Helper class holds Python3 metaclass object
9059    #
9060    #  class_def_node  PyClassDefNode  PyClassDefNode defining this class
9061
9062    subexprs = []
9063
9064    def analyse_types(self, env):
9065        self.type = py_object_type
9066        self.is_temp = True
9067        return self
9068
9069    def may_be_none(self):
9070        return True
9071
9072    def generate_result_code(self, code):
9073        bases = self.class_def_node.bases
9074        mkw = self.class_def_node.mkw
9075        if mkw:
9076            code.globalstate.use_utility_code(
9077                UtilityCode.load_cached("Py3MetaclassGet", "ObjectHandling.c"))
9078            call = "__Pyx_Py3MetaclassGet(%s, %s)" % (
9079                bases.result(),
9080                mkw.result())
9081        else:
9082            code.globalstate.use_utility_code(
9083                UtilityCode.load_cached("CalculateMetaclass", "ObjectHandling.c"))
9084            call = "__Pyx_CalculateMetaclass(NULL, %s)" % (
9085                bases.result())
9086        code.putln(
9087            "%s = %s; %s" % (
9088                self.result(), call,
9089                code.error_goto_if_null(self.result(), self.pos)))
9090        code.put_gotref(self.py_result())
9091
9092
9093class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
9094    # Helper class holds Python3 namespace object
9095    #
9096    # All this are not owned by this node
9097    #  class_def_node  PyClassDefNode  PyClassDefNode defining this class
9098    #  doc          ExprNode or None   Doc string (owned)
9099
9100    subexprs = ['doc']
9101
9102    def analyse_types(self, env):
9103        if self.doc:
9104            self.doc = self.doc.analyse_types(env).coerce_to_pyobject(env)
9105        self.type = py_object_type
9106        self.is_temp = 1
9107        return self
9108
9109    def may_be_none(self):
9110        return True
9111
9112    def generate_result_code(self, code):
9113        cname = code.intern_identifier(self.name)
9114        py_mod_name = self.get_py_mod_name(code)
9115        qualname = self.get_py_qualified_name(code)
9116        class_def_node = self.class_def_node
9117        null = "(PyObject *) NULL"
9118        doc_code = self.doc.result() if self.doc else null
9119        mkw = class_def_node.mkw.py_result() if class_def_node.mkw else null
9120        metaclass = class_def_node.metaclass.py_result() if class_def_node.metaclass else null
9121        code.putln(
9122            "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s, %s); %s" % (
9123                self.result(),
9124                metaclass,
9125                class_def_node.bases.result(),
9126                cname,
9127                qualname,
9128                mkw,
9129                py_mod_name,
9130                doc_code,
9131                code.error_goto_if_null(self.result(), self.pos)))
9132        code.put_gotref(self.py_result())
9133
9134
9135class ClassCellInjectorNode(ExprNode):
9136    # Initialize CyFunction.func_classobj
9137    is_temp = True
9138    type = py_object_type
9139    subexprs = []
9140    is_active = False
9141
9142    def analyse_expressions(self, env):
9143        return self
9144
9145    def generate_result_code(self, code):
9146        assert self.is_active
9147        code.putln(
9148            '%s = PyList_New(0); %s' % (
9149                self.result(),
9150                code.error_goto_if_null(self.result(), self.pos)))
9151        code.put_gotref(self.result())
9152
9153    def generate_injection_code(self, code, classobj_cname):
9154        assert self.is_active
9155        code.globalstate.use_utility_code(
9156            UtilityCode.load_cached("CyFunctionClassCell", "CythonFunction.c"))
9157        code.put_error_if_neg(self.pos, '__Pyx_CyFunction_InitClassCell(%s, %s)' % (
9158            self.result(), classobj_cname))
9159
9160
9161class ClassCellNode(ExprNode):
9162    # Class Cell for noargs super()
9163    subexprs = []
9164    is_temp = True
9165    is_generator = False
9166    type = py_object_type
9167
9168    def analyse_types(self, env):
9169        return self
9170
9171    def generate_result_code(self, code):
9172        if not self.is_generator:
9173            code.putln('%s = __Pyx_CyFunction_GetClassObj(%s);' % (
9174                self.result(),
9175                Naming.self_cname))
9176        else:
9177            code.putln('%s =  %s->classobj;' % (
9178                self.result(), Naming.generator_cname))
9179        code.putln(
9180            'if (!%s) { PyErr_SetString(PyExc_SystemError, '
9181            '"super(): empty __class__ cell"); %s }' % (
9182                self.result(),
9183                code.error_goto(self.pos)))
9184        code.put_incref(self.result(), py_object_type)
9185
9186
9187class PyCFunctionNode(ExprNode, ModuleNameMixin):
9188    #  Helper class used in the implementation of Python
9189    #  functions.  Constructs a PyCFunction object
9190    #  from a PyMethodDef struct.
9191    #
9192    #  pymethdef_cname   string             PyMethodDef structure
9193    #  self_object       ExprNode or None
9194    #  binding           bool
9195    #  def_node          DefNode            the Python function node
9196    #  module_name       EncodedString      Name of defining module
9197    #  code_object       CodeObjectNode     the PyCodeObject creator node
9198
9199    subexprs = ['code_object', 'defaults_tuple', 'defaults_kwdict',
9200                'annotations_dict']
9201
9202    self_object = None
9203    code_object = None
9204    binding = False
9205    def_node = None
9206    defaults = None
9207    defaults_struct = None
9208    defaults_pyobjects = 0
9209    defaults_tuple = None
9210    defaults_kwdict = None
9211    annotations_dict = None
9212
9213    type = py_object_type
9214    is_temp = 1
9215
9216    specialized_cpdefs = None
9217    is_specialization = False
9218
9219    @classmethod
9220    def from_defnode(cls, node, binding):
9221        return cls(node.pos,
9222                   def_node=node,
9223                   pymethdef_cname=node.entry.pymethdef_cname,
9224                   binding=binding or node.specialized_cpdefs,
9225                   specialized_cpdefs=node.specialized_cpdefs,
9226                   code_object=CodeObjectNode(node))
9227
9228    def analyse_types(self, env):
9229        if self.binding:
9230            self.analyse_default_args(env)
9231        return self
9232
9233    def analyse_default_args(self, env):
9234        """
9235        Handle non-literal function's default arguments.
9236        """
9237        nonliteral_objects = []
9238        nonliteral_other = []
9239        default_args = []
9240        default_kwargs = []
9241        annotations = []
9242
9243        # For global cpdef functions and def/cpdef methods in cdef classes, we must use global constants
9244        # for default arguments to avoid the dependency on the CyFunction object as 'self' argument
9245        # in the underlying C function.  Basically, cpdef functions/methods are static C functions,
9246        # so their optional arguments must be static, too.
9247        # TODO: change CyFunction implementation to pass both function object and owning object for method calls
9248        must_use_constants = env.is_c_class_scope or (self.def_node.is_wrapper and env.is_module_scope)
9249
9250        for arg in self.def_node.args:
9251            if arg.default and not must_use_constants:
9252                if not arg.default.is_literal:
9253                    arg.is_dynamic = True
9254                    if arg.type.is_pyobject:
9255                        nonliteral_objects.append(arg)
9256                    else:
9257                        nonliteral_other.append(arg)
9258                else:
9259                    arg.default = DefaultLiteralArgNode(arg.pos, arg.default)
9260                if arg.kw_only:
9261                    default_kwargs.append(arg)
9262                else:
9263                    default_args.append(arg)
9264            if arg.annotation:
9265                arg.annotation = self.analyse_annotation(env, arg.annotation)
9266                annotations.append((arg.pos, arg.name, arg.annotation))
9267
9268        for arg in (self.def_node.star_arg, self.def_node.starstar_arg):
9269            if arg and arg.annotation:
9270                arg.annotation = self.analyse_annotation(env, arg.annotation)
9271                annotations.append((arg.pos, arg.name, arg.annotation))
9272
9273        annotation = self.def_node.return_type_annotation
9274        if annotation:
9275            annotation = self.analyse_annotation(env, annotation)
9276            self.def_node.return_type_annotation = annotation
9277            annotations.append((annotation.pos, StringEncoding.EncodedString("return"), annotation))
9278
9279        if nonliteral_objects or nonliteral_other:
9280            module_scope = env.global_scope()
9281            cname = module_scope.next_id(Naming.defaults_struct_prefix)
9282            scope = Symtab.StructOrUnionScope(cname)
9283            self.defaults = []
9284            for arg in nonliteral_objects:
9285                entry = scope.declare_var(arg.name, arg.type, None,
9286                                          Naming.arg_prefix + arg.name,
9287                                          allow_pyobject=True)
9288                self.defaults.append((arg, entry))
9289            for arg in nonliteral_other:
9290                entry = scope.declare_var(arg.name, arg.type, None,
9291                                          Naming.arg_prefix + arg.name,
9292                                          allow_pyobject=False, allow_memoryview=True)
9293                self.defaults.append((arg, entry))
9294            entry = module_scope.declare_struct_or_union(
9295                None, 'struct', scope, 1, None, cname=cname)
9296            self.defaults_struct = scope
9297            self.defaults_pyobjects = len(nonliteral_objects)
9298            for arg, entry in self.defaults:
9299                arg.default_value = '%s->%s' % (
9300                    Naming.dynamic_args_cname, entry.cname)
9301            self.def_node.defaults_struct = self.defaults_struct.name
9302
9303        if default_args or default_kwargs:
9304            if self.defaults_struct is None:
9305                if default_args:
9306                    defaults_tuple = TupleNode(self.pos, args=[
9307                        arg.default for arg in default_args])
9308                    self.defaults_tuple = defaults_tuple.analyse_types(env).coerce_to_pyobject(env)
9309                if default_kwargs:
9310                    defaults_kwdict = DictNode(self.pos, key_value_pairs=[
9311                        DictItemNode(
9312                            arg.pos,
9313                            key=IdentifierStringNode(arg.pos, value=arg.name),
9314                            value=arg.default)
9315                        for arg in default_kwargs])
9316                    self.defaults_kwdict = defaults_kwdict.analyse_types(env)
9317            else:
9318                if default_args:
9319                    defaults_tuple = DefaultsTupleNode(
9320                        self.pos, default_args, self.defaults_struct)
9321                else:
9322                    defaults_tuple = NoneNode(self.pos)
9323                if default_kwargs:
9324                    defaults_kwdict = DefaultsKwDictNode(
9325                        self.pos, default_kwargs, self.defaults_struct)
9326                else:
9327                    defaults_kwdict = NoneNode(self.pos)
9328
9329                defaults_getter = Nodes.DefNode(
9330                    self.pos, args=[], star_arg=None, starstar_arg=None,
9331                    body=Nodes.ReturnStatNode(
9332                        self.pos, return_type=py_object_type,
9333                        value=TupleNode(
9334                            self.pos, args=[defaults_tuple, defaults_kwdict])),
9335                    decorators=None,
9336                    name=StringEncoding.EncodedString("__defaults__"))
9337                # defaults getter must never live in class scopes, it's always a module function
9338                module_scope = env.global_scope()
9339                defaults_getter.analyse_declarations(module_scope)
9340                defaults_getter = defaults_getter.analyse_expressions(module_scope)
9341                defaults_getter.body = defaults_getter.body.analyse_expressions(
9342                    defaults_getter.local_scope)
9343                defaults_getter.py_wrapper_required = False
9344                defaults_getter.pymethdef_required = False
9345                self.def_node.defaults_getter = defaults_getter
9346        if annotations:
9347            annotations_dict = DictNode(self.pos, key_value_pairs=[
9348                DictItemNode(
9349                    pos, key=IdentifierStringNode(pos, value=name),
9350                    value=value)
9351                for pos, name, value in annotations])
9352            self.annotations_dict = annotations_dict.analyse_types(env)
9353
9354    def analyse_annotation(self, env, annotation):
9355        if annotation is None:
9356            return None
9357        atype = annotation.analyse_as_type(env)
9358        if atype is not None:
9359            # Keep parsed types as strings as they might not be Python representable.
9360            annotation = UnicodeNode(
9361                annotation.pos,
9362                value=StringEncoding.EncodedString(atype.declaration_code('', for_display=True)))
9363        annotation = annotation.analyse_types(env)
9364        if not annotation.type.is_pyobject:
9365            annotation = annotation.coerce_to_pyobject(env)
9366        return annotation
9367
9368    def may_be_none(self):
9369        return False
9370
9371    gil_message = "Constructing Python function"
9372
9373    def self_result_code(self):
9374        if self.self_object is None:
9375            self_result = "NULL"
9376        else:
9377            self_result = self.self_object.py_result()
9378        return self_result
9379
9380    def generate_result_code(self, code):
9381        if self.binding:
9382            self.generate_cyfunction_code(code)
9383        else:
9384            self.generate_pycfunction_code(code)
9385
9386    def generate_pycfunction_code(self, code):
9387        py_mod_name = self.get_py_mod_name(code)
9388        code.putln(
9389            '%s = PyCFunction_NewEx(&%s, %s, %s); %s' % (
9390                self.result(),
9391                self.pymethdef_cname,
9392                self.self_result_code(),
9393                py_mod_name,
9394                code.error_goto_if_null(self.result(), self.pos)))
9395
9396        code.put_gotref(self.py_result())
9397
9398    def generate_cyfunction_code(self, code):
9399        if self.specialized_cpdefs:
9400            def_node = self.specialized_cpdefs[0]
9401        else:
9402            def_node = self.def_node
9403
9404        if self.specialized_cpdefs or self.is_specialization:
9405            code.globalstate.use_utility_code(
9406                UtilityCode.load_cached("FusedFunction", "CythonFunction.c"))
9407            constructor = "__pyx_FusedFunction_New"
9408        else:
9409            code.globalstate.use_utility_code(
9410                UtilityCode.load_cached("CythonFunction", "CythonFunction.c"))
9411            constructor = "__Pyx_CyFunction_New"
9412
9413        if self.code_object:
9414            code_object_result = self.code_object.py_result()
9415        else:
9416            code_object_result = 'NULL'
9417
9418        flags = []
9419        if def_node.is_staticmethod:
9420            flags.append('__Pyx_CYFUNCTION_STATICMETHOD')
9421        elif def_node.is_classmethod:
9422            flags.append('__Pyx_CYFUNCTION_CLASSMETHOD')
9423
9424        if def_node.local_scope.parent_scope.is_c_class_scope and not def_node.entry.is_anonymous:
9425            flags.append('__Pyx_CYFUNCTION_CCLASS')
9426
9427        if flags:
9428            flags = ' | '.join(flags)
9429        else:
9430            flags = '0'
9431
9432        code.putln(
9433            '%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s' % (
9434                self.result(),
9435                constructor,
9436                self.pymethdef_cname,
9437                flags,
9438                self.get_py_qualified_name(code),
9439                self.self_result_code(),
9440                self.get_py_mod_name(code),
9441                Naming.moddict_cname,
9442                code_object_result,
9443                code.error_goto_if_null(self.result(), self.pos)))
9444
9445        code.put_gotref(self.py_result())
9446
9447        if def_node.requires_classobj:
9448            assert code.pyclass_stack, "pyclass_stack is empty"
9449            class_node = code.pyclass_stack[-1]
9450            code.put_incref(self.py_result(), py_object_type)
9451            code.putln(
9452                'PyList_Append(%s, %s);' % (
9453                    class_node.class_cell.result(),
9454                    self.result()))
9455            code.put_giveref(self.py_result())
9456
9457        if self.defaults:
9458            code.putln(
9459                'if (!__Pyx_CyFunction_InitDefaults(%s, sizeof(%s), %d)) %s' % (
9460                    self.result(), self.defaults_struct.name,
9461                    self.defaults_pyobjects, code.error_goto(self.pos)))
9462            defaults = '__Pyx_CyFunction_Defaults(%s, %s)' % (
9463                self.defaults_struct.name, self.result())
9464            for arg, entry in self.defaults:
9465                arg.generate_assignment_code(code, target='%s->%s' % (
9466                    defaults, entry.cname))
9467
9468        if self.defaults_tuple:
9469            code.putln('__Pyx_CyFunction_SetDefaultsTuple(%s, %s);' % (
9470                self.result(), self.defaults_tuple.py_result()))
9471        if self.defaults_kwdict:
9472            code.putln('__Pyx_CyFunction_SetDefaultsKwDict(%s, %s);' % (
9473                self.result(), self.defaults_kwdict.py_result()))
9474        if def_node.defaults_getter and not self.specialized_cpdefs:
9475            # Fused functions do not support dynamic defaults, only their specialisations can have them for now.
9476            code.putln('__Pyx_CyFunction_SetDefaultsGetter(%s, %s);' % (
9477                self.result(), def_node.defaults_getter.entry.pyfunc_cname))
9478        if self.annotations_dict:
9479            code.putln('__Pyx_CyFunction_SetAnnotationsDict(%s, %s);' % (
9480                self.result(), self.annotations_dict.py_result()))
9481
9482
9483class InnerFunctionNode(PyCFunctionNode):
9484    # Special PyCFunctionNode that depends on a closure class
9485    #
9486
9487    binding = True
9488    needs_self_code = True
9489
9490    def self_result_code(self):
9491        if self.needs_self_code:
9492            return "((PyObject*)%s)" % Naming.cur_scope_cname
9493        return "NULL"
9494
9495
9496class CodeObjectNode(ExprNode):
9497    # Create a PyCodeObject for a CyFunction instance.
9498    #
9499    # def_node   DefNode    the Python function node
9500    # varnames   TupleNode  a tuple with all local variable names
9501
9502    subexprs = ['varnames']
9503    is_temp = False
9504    result_code = None
9505
9506    def __init__(self, def_node):
9507        ExprNode.__init__(self, def_node.pos, def_node=def_node)
9508        args = list(def_node.args)
9509        # if we have args/kwargs, then the first two in var_entries are those
9510        local_vars = [arg for arg in def_node.local_scope.var_entries if arg.name]
9511        self.varnames = TupleNode(
9512            def_node.pos,
9513            args=[IdentifierStringNode(arg.pos, value=arg.name)
9514                  for arg in args + local_vars],
9515            is_temp=0,
9516            is_literal=1)
9517
9518    def may_be_none(self):
9519        return False
9520
9521    def calculate_result_code(self, code=None):
9522        if self.result_code is None:
9523            self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
9524        return self.result_code
9525
9526    def generate_result_code(self, code):
9527        if self.result_code is None:
9528            self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
9529
9530        code = code.get_cached_constants_writer(self.result_code)
9531        if code is None:
9532            return  # already initialised
9533        code.mark_pos(self.pos)
9534        func = self.def_node
9535        func_name = code.get_py_string_const(
9536            func.name, identifier=True, is_str=False, unicode_value=func.name)
9537        # FIXME: better way to get the module file path at module init time? Encoding to use?
9538        file_path = StringEncoding.bytes_literal(func.pos[0].get_filenametable_entry().encode('utf8'), 'utf8')
9539        file_path_const = code.get_py_string_const(file_path, identifier=False, is_str=True)
9540
9541        # This combination makes CPython create a new dict for "frame.f_locals" (see GH #1836).
9542        flags = ['CO_OPTIMIZED', 'CO_NEWLOCALS']
9543
9544        if self.def_node.star_arg:
9545            flags.append('CO_VARARGS')
9546        if self.def_node.starstar_arg:
9547            flags.append('CO_VARKEYWORDS')
9548
9549        code.putln("%s = (PyObject*)__Pyx_PyCode_New(%d, %d, %d, 0, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s); %s" % (
9550            self.result_code,
9551            len(func.args) - func.num_kwonly_args,  # argcount
9552            func.num_kwonly_args,      # kwonlyargcount (Py3 only)
9553            len(self.varnames.args),   # nlocals
9554            '|'.join(flags) or '0',    # flags
9555            Naming.empty_bytes,        # code
9556            Naming.empty_tuple,        # consts
9557            Naming.empty_tuple,        # names (FIXME)
9558            self.varnames.result(),    # varnames
9559            Naming.empty_tuple,        # freevars (FIXME)
9560            Naming.empty_tuple,        # cellvars (FIXME)
9561            file_path_const,           # filename
9562            func_name,                 # name
9563            self.pos[1],               # firstlineno
9564            Naming.empty_bytes,        # lnotab
9565            code.error_goto_if_null(self.result_code, self.pos),
9566            ))
9567
9568
9569class DefaultLiteralArgNode(ExprNode):
9570    # CyFunction's literal argument default value
9571    #
9572    # Evaluate literal only once.
9573
9574    subexprs = []
9575    is_literal = True
9576    is_temp = False
9577
9578    def __init__(self, pos, arg):
9579        super(DefaultLiteralArgNode, self).__init__(pos)
9580        self.arg = arg
9581        self.type = self.arg.type
9582        self.evaluated = False
9583
9584    def analyse_types(self, env):
9585        return self
9586
9587    def generate_result_code(self, code):
9588        pass
9589
9590    def generate_evaluation_code(self, code):
9591        if not self.evaluated:
9592            self.arg.generate_evaluation_code(code)
9593            self.evaluated = True
9594
9595    def result(self):
9596        return self.type.cast_code(self.arg.result())
9597
9598
9599class DefaultNonLiteralArgNode(ExprNode):
9600    # CyFunction's non-literal argument default value
9601
9602    subexprs = []
9603
9604    def __init__(self, pos, arg, defaults_struct):
9605        super(DefaultNonLiteralArgNode, self).__init__(pos)
9606        self.arg = arg
9607        self.defaults_struct = defaults_struct
9608
9609    def analyse_types(self, env):
9610        self.type = self.arg.type
9611        self.is_temp = False
9612        return self
9613
9614    def generate_result_code(self, code):
9615        pass
9616
9617    def result(self):
9618        return '__Pyx_CyFunction_Defaults(%s, %s)->%s' % (
9619            self.defaults_struct.name, Naming.self_cname,
9620            self.defaults_struct.lookup(self.arg.name).cname)
9621
9622
9623class DefaultsTupleNode(TupleNode):
9624    # CyFunction's __defaults__ tuple
9625
9626    def __init__(self, pos, defaults, defaults_struct):
9627        args = []
9628        for arg in defaults:
9629            if not arg.default.is_literal:
9630                arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
9631            else:
9632                arg = arg.default
9633            args.append(arg)
9634        super(DefaultsTupleNode, self).__init__(pos, args=args)
9635
9636    def analyse_types(self, env, skip_children=False):
9637        return super(DefaultsTupleNode, self).analyse_types(env, skip_children).coerce_to_pyobject(env)
9638
9639
9640class DefaultsKwDictNode(DictNode):
9641    # CyFunction's __kwdefaults__ dict
9642
9643    def __init__(self, pos, defaults, defaults_struct):
9644        items = []
9645        for arg in defaults:
9646            name = IdentifierStringNode(arg.pos, value=arg.name)
9647            if not arg.default.is_literal:
9648                arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
9649            else:
9650                arg = arg.default
9651            items.append(DictItemNode(arg.pos, key=name, value=arg))
9652        super(DefaultsKwDictNode, self).__init__(pos, key_value_pairs=items)
9653
9654
9655class LambdaNode(InnerFunctionNode):
9656    # Lambda expression node (only used as a function reference)
9657    #
9658    # args          [CArgDeclNode]         formal arguments
9659    # star_arg      PyArgDeclNode or None  * argument
9660    # starstar_arg  PyArgDeclNode or None  ** argument
9661    # lambda_name   string                 a module-globally unique lambda name
9662    # result_expr   ExprNode
9663    # def_node      DefNode                the underlying function 'def' node
9664
9665    child_attrs = ['def_node']
9666
9667    name = StringEncoding.EncodedString('<lambda>')
9668
9669    def analyse_declarations(self, env):
9670        self.lambda_name = self.def_node.lambda_name = env.next_id('lambda')
9671        self.def_node.no_assignment_synthesis = True
9672        self.def_node.pymethdef_required = True
9673        self.def_node.analyse_declarations(env)
9674        self.def_node.is_cyfunction = True
9675        self.pymethdef_cname = self.def_node.entry.pymethdef_cname
9676        env.add_lambda_def(self.def_node)
9677
9678    def analyse_types(self, env):
9679        self.def_node = self.def_node.analyse_expressions(env)
9680        return super(LambdaNode, self).analyse_types(env)
9681
9682    def generate_result_code(self, code):
9683        self.def_node.generate_execution_code(code)
9684        super(LambdaNode, self).generate_result_code(code)
9685
9686
9687class GeneratorExpressionNode(LambdaNode):
9688    # A generator expression, e.g.  (i for i in range(10))
9689    #
9690    # Result is a generator.
9691    #
9692    # loop      ForStatNode   the for-loop, containing a YieldExprNode
9693    # def_node  DefNode       the underlying generator 'def' node
9694
9695    name = StringEncoding.EncodedString('genexpr')
9696    binding = False
9697
9698    def analyse_declarations(self, env):
9699        self.genexpr_name = env.next_id('genexpr')
9700        super(GeneratorExpressionNode, self).analyse_declarations(env)
9701        # No pymethdef required
9702        self.def_node.pymethdef_required = False
9703        self.def_node.py_wrapper_required = False
9704        self.def_node.is_cyfunction = False
9705        # Force genexpr signature
9706        self.def_node.entry.signature = TypeSlots.pyfunction_noargs
9707
9708    def generate_result_code(self, code):
9709        code.putln(
9710            '%s = %s(%s); %s' % (
9711                self.result(),
9712                self.def_node.entry.pyfunc_cname,
9713                self.self_result_code(),
9714                code.error_goto_if_null(self.result(), self.pos)))
9715        code.put_gotref(self.py_result())
9716
9717
9718class YieldExprNode(ExprNode):
9719    # Yield expression node
9720    #
9721    # arg         ExprNode   the value to return from the generator
9722    # label_num   integer    yield label number
9723    # is_yield_from  boolean is a YieldFromExprNode to delegate to another generator
9724
9725    subexprs = ['arg']
9726    type = py_object_type
9727    label_num = 0
9728    is_yield_from = False
9729    is_await = False
9730    in_async_gen = False
9731    expr_keyword = 'yield'
9732
9733    def analyse_types(self, env):
9734        if not self.label_num or (self.is_yield_from and self.in_async_gen):
9735            error(self.pos, "'%s' not supported here" % self.expr_keyword)
9736        self.is_temp = 1
9737        if self.arg is not None:
9738            self.arg = self.arg.analyse_types(env)
9739            if not self.arg.type.is_pyobject:
9740                self.coerce_yield_argument(env)
9741        return self
9742
9743    def coerce_yield_argument(self, env):
9744        self.arg = self.arg.coerce_to_pyobject(env)
9745
9746    def generate_evaluation_code(self, code):
9747        if self.arg:
9748            self.arg.generate_evaluation_code(code)
9749            self.arg.make_owned_reference(code)
9750            code.putln(
9751                "%s = %s;" % (
9752                    Naming.retval_cname,
9753                    self.arg.result_as(py_object_type)))
9754            self.arg.generate_post_assignment_code(code)
9755            self.arg.free_temps(code)
9756        else:
9757            code.put_init_to_py_none(Naming.retval_cname, py_object_type)
9758        self.generate_yield_code(code)
9759
9760    def generate_yield_code(self, code):
9761        """
9762        Generate the code to return the argument in 'Naming.retval_cname'
9763        and to continue at the yield label.
9764        """
9765        label_num, label_name = code.new_yield_label(
9766            self.expr_keyword.replace(' ', '_'))
9767        code.use_label(label_name)
9768
9769        saved = []
9770        code.funcstate.closure_temps.reset()
9771        for cname, type, manage_ref in code.funcstate.temps_in_use():
9772            save_cname = code.funcstate.closure_temps.allocate_temp(type)
9773            saved.append((cname, save_cname, type))
9774            if type.is_pyobject:
9775                code.put_xgiveref(cname)
9776            code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
9777
9778        code.put_xgiveref(Naming.retval_cname)
9779        profile = code.globalstate.directives['profile']
9780        linetrace = code.globalstate.directives['linetrace']
9781        if profile or linetrace:
9782            code.put_trace_return(Naming.retval_cname,
9783                                  nogil=not code.funcstate.gil_owned)
9784        code.put_finish_refcount_context()
9785
9786        if code.funcstate.current_except is not None:
9787            # inside of an except block => save away currently handled exception
9788            code.putln("__Pyx_Coroutine_SwapException(%s);" % Naming.generator_cname)
9789        else:
9790            # no exceptions being handled => restore exception state of caller
9791            code.putln("__Pyx_Coroutine_ResetAndClearException(%s);" % Naming.generator_cname)
9792
9793        code.putln("/* return from %sgenerator, %sing value */" % (
9794            'async ' if self.in_async_gen else '',
9795            'await' if self.is_await else 'yield'))
9796        code.putln("%s->resume_label = %d;" % (
9797            Naming.generator_cname, label_num))
9798        if self.in_async_gen and not self.is_await:
9799            # __Pyx__PyAsyncGenValueWrapperNew() steals a reference to the return value
9800            code.putln("return __Pyx__PyAsyncGenValueWrapperNew(%s);" % Naming.retval_cname)
9801        else:
9802            code.putln("return %s;" % Naming.retval_cname)
9803
9804        code.put_label(label_name)
9805        for cname, save_cname, type in saved:
9806            code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
9807            if type.is_pyobject:
9808                code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
9809                code.put_xgotref(cname)
9810        self.generate_sent_value_handling_code(code, Naming.sent_value_cname)
9811        if self.result_is_used:
9812            self.allocate_temp_result(code)
9813            code.put('%s = %s; ' % (self.result(), Naming.sent_value_cname))
9814            code.put_incref(self.result(), py_object_type)
9815
9816    def generate_sent_value_handling_code(self, code, value_cname):
9817        code.putln(code.error_goto_if_null(value_cname, self.pos))
9818
9819
9820class _YieldDelegationExprNode(YieldExprNode):
9821    def yield_from_func(self, code):
9822        raise NotImplementedError()
9823
9824    def generate_evaluation_code(self, code, source_cname=None, decref_source=False):
9825        if source_cname is None:
9826            self.arg.generate_evaluation_code(code)
9827        code.putln("%s = %s(%s, %s);" % (
9828            Naming.retval_cname,
9829            self.yield_from_func(code),
9830            Naming.generator_cname,
9831            self.arg.py_result() if source_cname is None else source_cname))
9832        if source_cname is None:
9833            self.arg.generate_disposal_code(code)
9834            self.arg.free_temps(code)
9835        elif decref_source:
9836            code.put_decref_clear(source_cname, py_object_type)
9837        code.put_xgotref(Naming.retval_cname)
9838
9839        code.putln("if (likely(%s)) {" % Naming.retval_cname)
9840        self.generate_yield_code(code)
9841        code.putln("} else {")
9842        # either error or sub-generator has normally terminated: return value => node result
9843        if self.result_is_used:
9844            self.fetch_iteration_result(code)
9845        else:
9846            self.handle_iteration_exception(code)
9847        code.putln("}")
9848
9849    def fetch_iteration_result(self, code):
9850        # YieldExprNode has allocated the result temp for us
9851        code.putln("%s = NULL;" % self.result())
9852        code.put_error_if_neg(self.pos, "__Pyx_PyGen_FetchStopIterationValue(&%s)" % self.result())
9853        code.put_gotref(self.result())
9854
9855    def handle_iteration_exception(self, code):
9856        code.putln("PyObject* exc_type = __Pyx_PyErr_Occurred();")
9857        code.putln("if (exc_type) {")
9858        code.putln("if (likely(exc_type == PyExc_StopIteration || (exc_type != PyExc_GeneratorExit &&"
9859                   " __Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)))) PyErr_Clear();")
9860        code.putln("else %s" % code.error_goto(self.pos))
9861        code.putln("}")
9862
9863
9864class YieldFromExprNode(_YieldDelegationExprNode):
9865    # "yield from GEN" expression
9866    is_yield_from = True
9867    expr_keyword = 'yield from'
9868
9869    def coerce_yield_argument(self, env):
9870        if not self.arg.type.is_string:
9871            # FIXME: support C arrays and C++ iterators?
9872            error(self.pos, "yielding from non-Python object not supported")
9873        self.arg = self.arg.coerce_to_pyobject(env)
9874
9875    def yield_from_func(self, code):
9876        code.globalstate.use_utility_code(UtilityCode.load_cached("GeneratorYieldFrom", "Coroutine.c"))
9877        return "__Pyx_Generator_Yield_From"
9878
9879
9880class AwaitExprNode(_YieldDelegationExprNode):
9881    # 'await' expression node
9882    #
9883    # arg         ExprNode   the Awaitable value to await
9884    # label_num   integer    yield label number
9885
9886    is_await = True
9887    expr_keyword = 'await'
9888
9889    def coerce_yield_argument(self, env):
9890        if self.arg is not None:
9891            # FIXME: use same check as in YieldFromExprNode.coerce_yield_argument() ?
9892            self.arg = self.arg.coerce_to_pyobject(env)
9893
9894    def yield_from_func(self, code):
9895        code.globalstate.use_utility_code(UtilityCode.load_cached("CoroutineYieldFrom", "Coroutine.c"))
9896        return "__Pyx_Coroutine_Yield_From"
9897
9898
9899class AwaitIterNextExprNode(AwaitExprNode):
9900    # 'await' expression node as part of 'async for' iteration
9901    #
9902    # Breaks out of loop on StopAsyncIteration exception.
9903
9904    def _generate_break(self, code):
9905        code.globalstate.use_utility_code(UtilityCode.load_cached("StopAsyncIteration", "Coroutine.c"))
9906        code.putln("PyObject* exc_type = __Pyx_PyErr_Occurred();")
9907        code.putln("if (unlikely(exc_type && (exc_type == __Pyx_PyExc_StopAsyncIteration || ("
9908                   " exc_type != PyExc_StopIteration && exc_type != PyExc_GeneratorExit &&"
9909                   " __Pyx_PyErr_GivenExceptionMatches(exc_type, __Pyx_PyExc_StopAsyncIteration))))) {")
9910        code.putln("PyErr_Clear();")
9911        code.putln("break;")
9912        code.putln("}")
9913
9914    def fetch_iteration_result(self, code):
9915        assert code.break_label, "AwaitIterNextExprNode outside of 'async for' loop"
9916        self._generate_break(code)
9917        super(AwaitIterNextExprNode, self).fetch_iteration_result(code)
9918
9919    def generate_sent_value_handling_code(self, code, value_cname):
9920        assert code.break_label, "AwaitIterNextExprNode outside of 'async for' loop"
9921        code.putln("if (unlikely(!%s)) {" % value_cname)
9922        self._generate_break(code)
9923        # all non-break exceptions are errors, as in parent class
9924        code.putln(code.error_goto(self.pos))
9925        code.putln("}")
9926
9927
9928class GlobalsExprNode(AtomicExprNode):
9929    type = dict_type
9930    is_temp = 1
9931
9932    def analyse_types(self, env):
9933        env.use_utility_code(Builtin.globals_utility_code)
9934        return self
9935
9936    gil_message = "Constructing globals dict"
9937
9938    def may_be_none(self):
9939        return False
9940
9941    def generate_result_code(self, code):
9942        code.putln('%s = __Pyx_Globals(); %s' % (
9943            self.result(),
9944            code.error_goto_if_null(self.result(), self.pos)))
9945        code.put_gotref(self.result())
9946
9947
9948class LocalsDictItemNode(DictItemNode):
9949    def analyse_types(self, env):
9950        self.key = self.key.analyse_types(env)
9951        self.value = self.value.analyse_types(env)
9952        self.key = self.key.coerce_to_pyobject(env)
9953        if self.value.type.can_coerce_to_pyobject(env):
9954            self.value = self.value.coerce_to_pyobject(env)
9955        else:
9956            self.value = None
9957        return self
9958
9959
9960class FuncLocalsExprNode(DictNode):
9961    def __init__(self, pos, env):
9962        local_vars = sorted([
9963            entry.name for entry in env.entries.values() if entry.name])
9964        items = [LocalsDictItemNode(
9965            pos, key=IdentifierStringNode(pos, value=var),
9966            value=NameNode(pos, name=var, allow_null=True))
9967                 for var in local_vars]
9968        DictNode.__init__(self, pos, key_value_pairs=items,
9969                          exclude_null_values=True)
9970
9971    def analyse_types(self, env):
9972        node = super(FuncLocalsExprNode, self).analyse_types(env)
9973        node.key_value_pairs = [ i for i in node.key_value_pairs
9974                                 if i.value is not None ]
9975        return node
9976
9977
9978class PyClassLocalsExprNode(AtomicExprNode):
9979    def __init__(self, pos, pyclass_dict):
9980        AtomicExprNode.__init__(self, pos)
9981        self.pyclass_dict = pyclass_dict
9982
9983    def analyse_types(self, env):
9984        self.type = self.pyclass_dict.type
9985        self.is_temp = False
9986        return self
9987
9988    def may_be_none(self):
9989        return False
9990
9991    def result(self):
9992        return self.pyclass_dict.result()
9993
9994    def generate_result_code(self, code):
9995        pass
9996
9997
9998def LocalsExprNode(pos, scope_node, env):
9999    if env.is_module_scope:
10000        return GlobalsExprNode(pos)
10001    if env.is_py_class_scope:
10002        return PyClassLocalsExprNode(pos, scope_node.dict)
10003    return FuncLocalsExprNode(pos, env)
10004
10005
10006#-------------------------------------------------------------------
10007#
10008#  Unary operator nodes
10009#
10010#-------------------------------------------------------------------
10011
10012compile_time_unary_operators = {
10013    'not': operator.not_,
10014    '~': operator.inv,
10015    '-': operator.neg,
10016    '+': operator.pos,
10017}
10018
10019class UnopNode(ExprNode):
10020    #  operator     string
10021    #  operand      ExprNode
10022    #
10023    #  Processing during analyse_expressions phase:
10024    #
10025    #    analyse_c_operation
10026    #      Called when the operand is not a pyobject.
10027    #      - Check operand type and coerce if needed.
10028    #      - Determine result type and result code fragment.
10029    #      - Allocate temporary for result if needed.
10030
10031    subexprs = ['operand']
10032    infix = True
10033
10034    def calculate_constant_result(self):
10035        func = compile_time_unary_operators[self.operator]
10036        self.constant_result = func(self.operand.constant_result)
10037
10038    def compile_time_value(self, denv):
10039        func = compile_time_unary_operators.get(self.operator)
10040        if not func:
10041            error(self.pos,
10042                "Unary '%s' not supported in compile-time expression"
10043                    % self.operator)
10044        operand = self.operand.compile_time_value(denv)
10045        try:
10046            return func(operand)
10047        except Exception as e:
10048            self.compile_time_value_error(e)
10049
10050    def infer_type(self, env):
10051        operand_type = self.operand.infer_type(env)
10052        if operand_type.is_cpp_class or operand_type.is_ptr:
10053            cpp_type = operand_type.find_cpp_operation_type(self.operator)
10054            if cpp_type is not None:
10055                return cpp_type
10056        return self.infer_unop_type(env, operand_type)
10057
10058    def infer_unop_type(self, env, operand_type):
10059        if operand_type.is_pyobject:
10060            return py_object_type
10061        else:
10062            return operand_type
10063
10064    def may_be_none(self):
10065        if self.operand.type and self.operand.type.is_builtin_type:
10066            if self.operand.type is not type_type:
10067                return False
10068        return ExprNode.may_be_none(self)
10069
10070    def analyse_types(self, env):
10071        self.operand = self.operand.analyse_types(env)
10072        if self.is_pythran_operation(env):
10073            self.type = PythranExpr(pythran_unaryop_type(self.operator, self.operand.type))
10074            self.is_temp = 1
10075        elif self.is_py_operation():
10076            self.coerce_operand_to_pyobject(env)
10077            self.type = py_object_type
10078            self.is_temp = 1
10079        elif self.is_cpp_operation():
10080            self.analyse_cpp_operation(env)
10081        else:
10082            self.analyse_c_operation(env)
10083        return self
10084
10085    def check_const(self):
10086        return self.operand.check_const()
10087
10088    def is_py_operation(self):
10089        return self.operand.type.is_pyobject or self.operand.type.is_ctuple
10090
10091    def is_pythran_operation(self, env):
10092        np_pythran = has_np_pythran(env)
10093        op_type = self.operand.type
10094        return np_pythran and (op_type.is_buffer or op_type.is_pythran_expr)
10095
10096    def nogil_check(self, env):
10097        if self.is_py_operation():
10098            self.gil_error()
10099
10100    def is_cpp_operation(self):
10101        type = self.operand.type
10102        return type.is_cpp_class
10103
10104    def coerce_operand_to_pyobject(self, env):
10105        self.operand = self.operand.coerce_to_pyobject(env)
10106
10107    def generate_result_code(self, code):
10108        if self.type.is_pythran_expr:
10109            code.putln("// Pythran unaryop")
10110            code.putln("__Pyx_call_destructor(%s);" % self.result())
10111            code.putln("new (&%s) decltype(%s){%s%s};" % (
10112                self.result(),
10113                self.result(),
10114                self.operator,
10115                self.operand.pythran_result()))
10116        elif self.operand.type.is_pyobject:
10117            self.generate_py_operation_code(code)
10118        elif self.is_temp:
10119            if self.is_cpp_operation() and self.exception_check == '+':
10120                translate_cpp_exception(code, self.pos,
10121                    "%s = %s %s;" % (self.result(), self.operator, self.operand.result()),
10122                    self.result() if self.type.is_pyobject else None,
10123                    self.exception_value, self.in_nogil_context)
10124            else:
10125                code.putln("%s = %s %s;" % (self.result(), self.operator, self.operand.result()))
10126
10127    def generate_py_operation_code(self, code):
10128        function = self.py_operation_function(code)
10129        code.putln(
10130            "%s = %s(%s); %s" % (
10131                self.result(),
10132                function,
10133                self.operand.py_result(),
10134                code.error_goto_if_null(self.result(), self.pos)))
10135        code.put_gotref(self.py_result())
10136
10137    def type_error(self):
10138        if not self.operand.type.is_error:
10139            error(self.pos, "Invalid operand type for '%s' (%s)" %
10140                (self.operator, self.operand.type))
10141        self.type = PyrexTypes.error_type
10142
10143    def analyse_cpp_operation(self, env, overload_check=True):
10144        entry = env.lookup_operator(self.operator, [self.operand])
10145        if overload_check and not entry:
10146            self.type_error()
10147            return
10148        if entry:
10149            self.exception_check = entry.type.exception_check
10150            self.exception_value = entry.type.exception_value
10151            if self.exception_check == '+':
10152                self.is_temp = True
10153                if self.exception_value is None:
10154                    env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
10155        else:
10156            self.exception_check = ''
10157            self.exception_value = ''
10158        cpp_type = self.operand.type.find_cpp_operation_type(self.operator)
10159        if overload_check and cpp_type is None:
10160            error(self.pos, "'%s' operator not defined for %s" % (
10161                self.operator, type))
10162            self.type_error()
10163            return
10164        self.type = cpp_type
10165
10166
10167class NotNode(UnopNode):
10168    #  'not' operator
10169    #
10170    #  operand   ExprNode
10171    operator = '!'
10172
10173    type = PyrexTypes.c_bint_type
10174
10175    def calculate_constant_result(self):
10176        self.constant_result = not self.operand.constant_result
10177
10178    def compile_time_value(self, denv):
10179        operand = self.operand.compile_time_value(denv)
10180        try:
10181            return not operand
10182        except Exception as e:
10183            self.compile_time_value_error(e)
10184
10185    def infer_unop_type(self, env, operand_type):
10186        return PyrexTypes.c_bint_type
10187
10188    def analyse_types(self, env):
10189        self.operand = self.operand.analyse_types(env)
10190        operand_type = self.operand.type
10191        if operand_type.is_cpp_class:
10192            self.analyse_cpp_operation(env)
10193        else:
10194            self.operand = self.operand.coerce_to_boolean(env)
10195        return self
10196
10197    def calculate_result_code(self):
10198        return "(!%s)" % self.operand.result()
10199
10200
10201class UnaryPlusNode(UnopNode):
10202    #  unary '+' operator
10203
10204    operator = '+'
10205
10206    def analyse_c_operation(self, env):
10207        self.type = PyrexTypes.widest_numeric_type(
10208            self.operand.type, PyrexTypes.c_int_type)
10209
10210    def py_operation_function(self, code):
10211        return "PyNumber_Positive"
10212
10213    def calculate_result_code(self):
10214        if self.is_cpp_operation():
10215            return "(+%s)" % self.operand.result()
10216        else:
10217            return self.operand.result()
10218
10219
10220class UnaryMinusNode(UnopNode):
10221    #  unary '-' operator
10222
10223    operator = '-'
10224
10225    def analyse_c_operation(self, env):
10226        if self.operand.type.is_numeric:
10227            self.type = PyrexTypes.widest_numeric_type(
10228                self.operand.type, PyrexTypes.c_int_type)
10229        elif self.operand.type.is_enum:
10230            self.type = PyrexTypes.c_int_type
10231        else:
10232            self.type_error()
10233        if self.type.is_complex:
10234            self.infix = False
10235
10236    def py_operation_function(self, code):
10237        return "PyNumber_Negative"
10238
10239    def calculate_result_code(self):
10240        if self.infix:
10241            return "(-%s)" % self.operand.result()
10242        else:
10243            return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
10244
10245    def get_constant_c_result_code(self):
10246        value = self.operand.get_constant_c_result_code()
10247        if value:
10248            return "(-%s)" % value
10249
10250class TildeNode(UnopNode):
10251    #  unary '~' operator
10252
10253    def analyse_c_operation(self, env):
10254        if self.operand.type.is_int:
10255            self.type = PyrexTypes.widest_numeric_type(
10256                self.operand.type, PyrexTypes.c_int_type)
10257        elif self.operand.type.is_enum:
10258            self.type = PyrexTypes.c_int_type
10259        else:
10260            self.type_error()
10261
10262    def py_operation_function(self, code):
10263        return "PyNumber_Invert"
10264
10265    def calculate_result_code(self):
10266        return "(~%s)" % self.operand.result()
10267
10268
10269class CUnopNode(UnopNode):
10270
10271    def is_py_operation(self):
10272        return False
10273
10274class DereferenceNode(CUnopNode):
10275    #  unary * operator
10276
10277    operator = '*'
10278
10279    def infer_unop_type(self, env, operand_type):
10280        if operand_type.is_ptr:
10281            return operand_type.base_type
10282        else:
10283            return PyrexTypes.error_type
10284
10285    def analyse_c_operation(self, env):
10286        if self.operand.type.is_ptr:
10287            self.type = self.operand.type.base_type
10288        else:
10289            self.type_error()
10290
10291    def calculate_result_code(self):
10292        return "(*%s)" % self.operand.result()
10293
10294
10295class DecrementIncrementNode(CUnopNode):
10296    #  unary ++/-- operator
10297
10298    def analyse_c_operation(self, env):
10299        if self.operand.type.is_numeric:
10300            self.type = PyrexTypes.widest_numeric_type(
10301                self.operand.type, PyrexTypes.c_int_type)
10302        elif self.operand.type.is_ptr:
10303            self.type = self.operand.type
10304        else:
10305            self.type_error()
10306
10307    def calculate_result_code(self):
10308        if self.is_prefix:
10309            return "(%s%s)" % (self.operator, self.operand.result())
10310        else:
10311            return "(%s%s)" % (self.operand.result(), self.operator)
10312
10313def inc_dec_constructor(is_prefix, operator):
10314    return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
10315
10316
10317class AmpersandNode(CUnopNode):
10318    #  The C address-of operator.
10319    #
10320    #  operand  ExprNode
10321    operator = '&'
10322
10323    def infer_unop_type(self, env, operand_type):
10324        return PyrexTypes.c_ptr_type(operand_type)
10325
10326    def analyse_types(self, env):
10327        self.operand = self.operand.analyse_types(env)
10328        argtype = self.operand.type
10329        if argtype.is_cpp_class:
10330            self.analyse_cpp_operation(env, overload_check=False)
10331        if not (argtype.is_cfunction or argtype.is_reference or self.operand.is_addressable()):
10332            if argtype.is_memoryviewslice:
10333                self.error("Cannot take address of memoryview slice")
10334            else:
10335                self.error("Taking address of non-lvalue (type %s)" % argtype)
10336            return self
10337        if argtype.is_pyobject:
10338            self.error("Cannot take address of Python %s" % (
10339                "variable '%s'" % self.operand.name if self.operand.is_name else
10340                "object attribute '%s'" % self.operand.attribute if self.operand.is_attribute else
10341                "object"))
10342            return self
10343        if not argtype.is_cpp_class or not self.type:
10344            self.type = PyrexTypes.c_ptr_type(argtype)
10345        return self
10346
10347    def check_const(self):
10348        return self.operand.check_const_addr()
10349
10350    def error(self, mess):
10351        error(self.pos, mess)
10352        self.type = PyrexTypes.error_type
10353        self.result_code = "<error>"
10354
10355    def calculate_result_code(self):
10356        return "(&%s)" % self.operand.result()
10357
10358    def generate_result_code(self, code):
10359        if (self.operand.type.is_cpp_class and self.exception_check == '+'):
10360            translate_cpp_exception(code, self.pos,
10361                "%s = %s %s;" % (self.result(), self.operator, self.operand.result()),
10362                self.result() if self.type.is_pyobject else None,
10363                self.exception_value, self.in_nogil_context)
10364
10365
10366unop_node_classes = {
10367    "+":  UnaryPlusNode,
10368    "-":  UnaryMinusNode,
10369    "~":  TildeNode,
10370}
10371
10372def unop_node(pos, operator, operand):
10373    # Construct unnop node of appropriate class for
10374    # given operator.
10375    if isinstance(operand, IntNode) and operator == '-':
10376        return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)),
10377                       longness=operand.longness, unsigned=operand.unsigned)
10378    elif isinstance(operand, UnopNode) and operand.operator == operator in '+-':
10379        warning(pos, "Python has no increment/decrement operator: %s%sx == %s(%sx) == x" % ((operator,)*4), 5)
10380    return unop_node_classes[operator](pos,
10381        operator = operator,
10382        operand = operand)
10383
10384
10385class TypecastNode(ExprNode):
10386    #  C type cast
10387    #
10388    #  operand      ExprNode
10389    #  base_type    CBaseTypeNode
10390    #  declarator   CDeclaratorNode
10391    #  typecheck    boolean
10392    #
10393    #  If used from a transform, one can if wanted specify the attribute
10394    #  "type" directly and leave base_type and declarator to None
10395
10396    subexprs = ['operand']
10397    base_type = declarator = type = None
10398
10399    def type_dependencies(self, env):
10400        return ()
10401
10402    def infer_type(self, env):
10403        if self.type is None:
10404            base_type = self.base_type.analyse(env)
10405            _, self.type = self.declarator.analyse(base_type, env)
10406        return self.type
10407
10408    def analyse_types(self, env):
10409        if self.type is None:
10410            base_type = self.base_type.analyse(env)
10411            _, self.type = self.declarator.analyse(base_type, env)
10412        if self.operand.has_constant_result():
10413            # Must be done after self.type is resolved.
10414            self.calculate_constant_result()
10415        if self.type.is_cfunction:
10416            error(self.pos,
10417                "Cannot cast to a function type")
10418            self.type = PyrexTypes.error_type
10419        self.operand = self.operand.analyse_types(env)
10420        if self.type is PyrexTypes.c_bint_type:
10421            # short circuit this to a coercion
10422            return self.operand.coerce_to_boolean(env)
10423        to_py = self.type.is_pyobject
10424        from_py = self.operand.type.is_pyobject
10425        if from_py and not to_py and self.operand.is_ephemeral():
10426            if not self.type.is_numeric and not self.type.is_cpp_class:
10427                error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
10428        if to_py and not from_py:
10429            if self.type is bytes_type and self.operand.type.is_int:
10430                return CoerceIntToBytesNode(self.operand, env)
10431            elif self.operand.type.can_coerce_to_pyobject(env):
10432                self.result_ctype = py_object_type
10433                self.operand = self.operand.coerce_to(self.type, env)
10434            else:
10435                if self.operand.type.is_ptr:
10436                    if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
10437                        error(self.pos, "Python objects cannot be cast from pointers of primitive types")
10438                else:
10439                    # Should this be an error?
10440                    warning(self.pos, "No conversion from %s to %s, python object pointer used." % (
10441                        self.operand.type, self.type))
10442                self.operand = self.operand.coerce_to_simple(env)
10443        elif from_py and not to_py:
10444            if self.type.create_from_py_utility_code(env):
10445                self.operand = self.operand.coerce_to(self.type, env)
10446            elif self.type.is_ptr:
10447                if not (self.type.base_type.is_void or self.type.base_type.is_struct):
10448                    error(self.pos, "Python objects cannot be cast to pointers of primitive types")
10449            else:
10450                warning(self.pos, "No conversion from %s to %s, python object pointer used." % (
10451                    self.type, self.operand.type))
10452        elif from_py and to_py:
10453            if self.typecheck:
10454                self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
10455            elif isinstance(self.operand, SliceIndexNode):
10456                # This cast can influence the created type of string slices.
10457                self.operand = self.operand.coerce_to(self.type, env)
10458        elif self.type.is_complex and self.operand.type.is_complex:
10459            self.operand = self.operand.coerce_to_simple(env)
10460        elif self.operand.type.is_fused:
10461            self.operand = self.operand.coerce_to(self.type, env)
10462            #self.type = self.operand.type
10463        if self.type.is_ptr and self.type.base_type.is_cfunction and self.type.base_type.nogil:
10464            op_type = self.operand.type
10465            if op_type.is_ptr:
10466                op_type = op_type.base_type
10467            if op_type.is_cfunction and not op_type.nogil:
10468                warning(self.pos,
10469                        "Casting a GIL-requiring function into a nogil function circumvents GIL validation", 1)
10470        return self
10471
10472    def is_simple(self):
10473        # either temp or a C cast => no side effects other than the operand's
10474        return self.operand.is_simple()
10475
10476    def is_ephemeral(self):
10477        # either temp or a C cast => no side effects other than the operand's
10478        return self.operand.is_ephemeral()
10479
10480    def nonlocally_immutable(self):
10481        return self.is_temp or self.operand.nonlocally_immutable()
10482
10483    def nogil_check(self, env):
10484        if self.type and self.type.is_pyobject and self.is_temp:
10485            self.gil_error()
10486
10487    def check_const(self):
10488        return self.operand.check_const()
10489
10490    def calculate_constant_result(self):
10491        self.constant_result = self.calculate_result_code(self.operand.constant_result)
10492
10493    def calculate_result_code(self, operand_result = None):
10494        if operand_result is None:
10495            operand_result = self.operand.result()
10496        if self.type.is_complex:
10497            operand_result = self.operand.result()
10498            if self.operand.type.is_complex:
10499                real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
10500                imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
10501            else:
10502                real_part = self.type.real_type.cast_code(operand_result)
10503                imag_part = "0"
10504            return "%s(%s, %s)" % (
10505                    self.type.from_parts,
10506                    real_part,
10507                    imag_part)
10508        else:
10509            return self.type.cast_code(operand_result)
10510
10511    def get_constant_c_result_code(self):
10512        operand_result = self.operand.get_constant_c_result_code()
10513        if operand_result:
10514            return self.type.cast_code(operand_result)
10515
10516    def result_as(self, type):
10517        if self.type.is_pyobject and not self.is_temp:
10518            #  Optimise away some unnecessary casting
10519            return self.operand.result_as(type)
10520        else:
10521            return ExprNode.result_as(self, type)
10522
10523    def generate_result_code(self, code):
10524        if self.is_temp:
10525            code.putln(
10526                "%s = (PyObject *)%s;" % (
10527                    self.result(),
10528                    self.operand.result()))
10529            code.put_incref(self.result(), self.ctype())
10530
10531
10532ERR_START = "Start may not be given"
10533ERR_NOT_STOP = "Stop must be provided to indicate shape"
10534ERR_STEPS = ("Strides may only be given to indicate contiguity. "
10535             "Consider slicing it after conversion")
10536ERR_NOT_POINTER = "Can only create cython.array from pointer or array"
10537ERR_BASE_TYPE = "Pointer base type does not match cython.array base type"
10538
10539
10540class CythonArrayNode(ExprNode):
10541    """
10542    Used when a pointer of base_type is cast to a memoryviewslice with that
10543    base type. i.e.
10544
10545        <int[:M:1, :N]> p
10546
10547    creates a fortran-contiguous cython.array.
10548
10549    We leave the type set to object so coercions to object are more efficient
10550    and less work. Acquiring a memoryviewslice from this will be just as
10551    efficient. ExprNode.coerce_to() will do the additional typecheck on
10552    self.compile_time_type
10553
10554    This also handles <int[:, :]> my_c_array
10555
10556
10557    operand             ExprNode                 the thing we're casting
10558    base_type_node      MemoryViewSliceTypeNode  the cast expression node
10559    """
10560
10561    subexprs = ['operand', 'shapes']
10562
10563    shapes = None
10564    is_temp = True
10565    mode = "c"
10566    array_dtype = None
10567
10568    shape_type = PyrexTypes.c_py_ssize_t_type
10569
10570    def analyse_types(self, env):
10571        from . import MemoryView
10572
10573        self.operand = self.operand.analyse_types(env)
10574        if self.array_dtype:
10575            array_dtype = self.array_dtype
10576        else:
10577            array_dtype = self.base_type_node.base_type_node.analyse(env)
10578        axes = self.base_type_node.axes
10579
10580        self.type = error_type
10581        self.shapes = []
10582        ndim = len(axes)
10583
10584        # Base type of the pointer or C array we are converting
10585        base_type = self.operand.type
10586
10587        if not self.operand.type.is_ptr and not self.operand.type.is_array:
10588            error(self.operand.pos, ERR_NOT_POINTER)
10589            return self
10590
10591        # Dimension sizes of C array
10592        array_dimension_sizes = []
10593        if base_type.is_array:
10594            while base_type.is_array:
10595                array_dimension_sizes.append(base_type.size)
10596                base_type = base_type.base_type
10597        elif base_type.is_ptr:
10598            base_type = base_type.base_type
10599        else:
10600            error(self.pos, "unexpected base type %s found" % base_type)
10601            return self
10602
10603        if not (base_type.same_as(array_dtype) or base_type.is_void):
10604            error(self.operand.pos, ERR_BASE_TYPE)
10605            return self
10606        elif self.operand.type.is_array and len(array_dimension_sizes) != ndim:
10607            error(self.operand.pos,
10608                  "Expected %d dimensions, array has %d dimensions" %
10609                                            (ndim, len(array_dimension_sizes)))
10610            return self
10611
10612        # Verify the start, stop and step values
10613        # In case of a C array, use the size of C array in each dimension to
10614        # get an automatic cast
10615        for axis_no, axis in enumerate(axes):
10616            if not axis.start.is_none:
10617                error(axis.start.pos, ERR_START)
10618                return self
10619
10620            if axis.stop.is_none:
10621                if array_dimension_sizes:
10622                    dimsize = array_dimension_sizes[axis_no]
10623                    axis.stop = IntNode(self.pos, value=str(dimsize),
10624                                        constant_result=dimsize,
10625                                        type=PyrexTypes.c_int_type)
10626                else:
10627                    error(axis.pos, ERR_NOT_STOP)
10628                    return self
10629
10630            axis.stop = axis.stop.analyse_types(env)
10631            shape = axis.stop.coerce_to(self.shape_type, env)
10632            if not shape.is_literal:
10633                shape.coerce_to_temp(env)
10634
10635            self.shapes.append(shape)
10636
10637            first_or_last = axis_no in (0, ndim - 1)
10638            if not axis.step.is_none and first_or_last:
10639                # '1' in the first or last dimension denotes F or C contiguity
10640                axis.step = axis.step.analyse_types(env)
10641                if (not axis.step.type.is_int and axis.step.is_literal and not
10642                        axis.step.type.is_error):
10643                    error(axis.step.pos, "Expected an integer literal")
10644                    return self
10645
10646                if axis.step.compile_time_value(env) != 1:
10647                    error(axis.step.pos, ERR_STEPS)
10648                    return self
10649
10650                if axis_no == 0:
10651                    self.mode = "fortran"
10652
10653            elif not axis.step.is_none and not first_or_last:
10654                # step provided in some other dimension
10655                error(axis.step.pos, ERR_STEPS)
10656                return self
10657
10658        if not self.operand.is_name:
10659            self.operand = self.operand.coerce_to_temp(env)
10660
10661        axes = [('direct', 'follow')] * len(axes)
10662        if self.mode == "fortran":
10663            axes[0] = ('direct', 'contig')
10664        else:
10665            axes[-1] = ('direct', 'contig')
10666
10667        self.coercion_type = PyrexTypes.MemoryViewSliceType(array_dtype, axes)
10668        self.coercion_type.validate_memslice_dtype(self.pos)
10669        self.type = self.get_cython_array_type(env)
10670        MemoryView.use_cython_array_utility_code(env)
10671        env.use_utility_code(MemoryView.typeinfo_to_format_code)
10672        return self
10673
10674    def allocate_temp_result(self, code):
10675        if self.temp_code:
10676            raise RuntimeError("temp allocated multiple times")
10677
10678        self.temp_code = code.funcstate.allocate_temp(self.type, True)
10679
10680    def infer_type(self, env):
10681        return self.get_cython_array_type(env)
10682
10683    def get_cython_array_type(self, env):
10684        cython_scope = env.global_scope().context.cython_scope
10685        cython_scope.load_cythonscope()
10686        return cython_scope.viewscope.lookup("array").type
10687
10688    def generate_result_code(self, code):
10689        from . import Buffer
10690
10691        shapes = [self.shape_type.cast_code(shape.result())
10692                      for shape in self.shapes]
10693        dtype = self.coercion_type.dtype
10694
10695        shapes_temp = code.funcstate.allocate_temp(py_object_type, True)
10696        format_temp = code.funcstate.allocate_temp(py_object_type, True)
10697
10698        itemsize = "sizeof(%s)" % dtype.empty_declaration_code()
10699        type_info = Buffer.get_type_information_cname(code, dtype)
10700
10701        if self.operand.type.is_ptr:
10702            code.putln("if (!%s) {" % self.operand.result())
10703            code.putln(    'PyErr_SetString(PyExc_ValueError,'
10704                                '"Cannot create cython.array from NULL pointer");')
10705            code.putln(code.error_goto(self.operand.pos))
10706            code.putln("}")
10707
10708        code.putln("%s = __pyx_format_from_typeinfo(&%s); %s" % (
10709            format_temp,
10710            type_info,
10711            code.error_goto_if_null(format_temp, self.pos),
10712        ))
10713        code.put_gotref(format_temp)
10714
10715        buildvalue_fmt = " __PYX_BUILD_PY_SSIZE_T " * len(shapes)
10716        code.putln('%s = Py_BuildValue((char*) "(" %s ")", %s); %s' % (
10717            shapes_temp,
10718            buildvalue_fmt,
10719            ", ".join(shapes),
10720            code.error_goto_if_null(shapes_temp, self.pos),
10721        ))
10722        code.put_gotref(shapes_temp)
10723
10724        tup = (self.result(), shapes_temp, itemsize, format_temp,
10725               self.mode, self.operand.result())
10726        code.putln('%s = __pyx_array_new('
10727                            '%s, %s, PyBytes_AS_STRING(%s), '
10728                            '(char *) "%s", (char *) %s);' % tup)
10729        code.putln(code.error_goto_if_null(self.result(), self.pos))
10730        code.put_gotref(self.result())
10731
10732        def dispose(temp):
10733            code.put_decref_clear(temp, py_object_type)
10734            code.funcstate.release_temp(temp)
10735
10736        dispose(shapes_temp)
10737        dispose(format_temp)
10738
10739    @classmethod
10740    def from_carray(cls, src_node, env):
10741        """
10742        Given a C array type, return a CythonArrayNode
10743        """
10744        pos = src_node.pos
10745        base_type = src_node.type
10746
10747        none_node = NoneNode(pos)
10748        axes = []
10749
10750        while base_type.is_array:
10751            axes.append(SliceNode(pos, start=none_node, stop=none_node,
10752                                       step=none_node))
10753            base_type = base_type.base_type
10754        axes[-1].step = IntNode(pos, value="1", is_c_literal=True)
10755
10756        memslicenode = Nodes.MemoryViewSliceTypeNode(pos, axes=axes,
10757                                                     base_type_node=base_type)
10758        result = CythonArrayNode(pos, base_type_node=memslicenode,
10759                                 operand=src_node, array_dtype=base_type)
10760        result = result.analyse_types(env)
10761        return result
10762
10763class SizeofNode(ExprNode):
10764    #  Abstract base class for sizeof(x) expression nodes.
10765
10766    type = PyrexTypes.c_size_t_type
10767
10768    def check_const(self):
10769        return True
10770
10771    def generate_result_code(self, code):
10772        pass
10773
10774
10775class SizeofTypeNode(SizeofNode):
10776    #  C sizeof function applied to a type
10777    #
10778    #  base_type   CBaseTypeNode
10779    #  declarator  CDeclaratorNode
10780
10781    subexprs = []
10782    arg_type = None
10783
10784    def analyse_types(self, env):
10785        # we may have incorrectly interpreted a dotted name as a type rather than an attribute
10786        # this could be better handled by more uniformly treating types as runtime-available objects
10787        if 0 and self.base_type.module_path:
10788            path = self.base_type.module_path
10789            obj = env.lookup(path[0])
10790            if obj.as_module is None:
10791                operand = NameNode(pos=self.pos, name=path[0])
10792                for attr in path[1:]:
10793                    operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
10794                operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
10795                node = SizeofVarNode(self.pos, operand=operand).analyse_types(env)
10796                return node
10797        if self.arg_type is None:
10798            base_type = self.base_type.analyse(env)
10799            _, arg_type = self.declarator.analyse(base_type, env)
10800            self.arg_type = arg_type
10801        self.check_type()
10802        return self
10803
10804    def check_type(self):
10805        arg_type = self.arg_type
10806        if not arg_type:
10807            return
10808        if arg_type.is_pyobject and not arg_type.is_extension_type:
10809            error(self.pos, "Cannot take sizeof Python object")
10810        elif arg_type.is_void:
10811            error(self.pos, "Cannot take sizeof void")
10812        elif not arg_type.is_complete():
10813            error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
10814
10815    def calculate_result_code(self):
10816        if self.arg_type.is_extension_type:
10817            # the size of the pointer is boring
10818            # we want the size of the actual struct
10819            arg_code = self.arg_type.declaration_code("", deref=1)
10820        else:
10821            arg_code = self.arg_type.empty_declaration_code()
10822        return "(sizeof(%s))" % arg_code
10823
10824
10825class SizeofVarNode(SizeofNode):
10826    #  C sizeof function applied to a variable
10827    #
10828    #  operand   ExprNode
10829
10830    subexprs = ['operand']
10831
10832    def analyse_types(self, env):
10833        # We may actually be looking at a type rather than a variable...
10834        # If we are, traditional analysis would fail...
10835        operand_as_type = self.operand.analyse_as_type(env)
10836        if operand_as_type:
10837            self.arg_type = operand_as_type
10838            if self.arg_type.is_fused:
10839                self.arg_type = self.arg_type.specialize(env.fused_to_specific)
10840            self.__class__ = SizeofTypeNode
10841            self.check_type()
10842        else:
10843            self.operand = self.operand.analyse_types(env)
10844        return self
10845
10846    def calculate_result_code(self):
10847        return "(sizeof(%s))" % self.operand.result()
10848
10849    def generate_result_code(self, code):
10850        pass
10851
10852
10853class TypeidNode(ExprNode):
10854    #  C++ typeid operator applied to a type or variable
10855    #
10856    #  operand       ExprNode
10857    #  arg_type      ExprNode
10858    #  is_variable   boolean
10859
10860    type = PyrexTypes.error_type
10861
10862    subexprs = ['operand']
10863
10864    arg_type = None
10865    is_variable = None
10866    is_temp = 1
10867
10868    def get_type_info_type(self, env):
10869        env_module = env
10870        while not env_module.is_module_scope:
10871            env_module = env_module.outer_scope
10872        typeinfo_module = env_module.find_module('libcpp.typeinfo', self.pos)
10873        typeinfo_entry = typeinfo_module.lookup('type_info')
10874        return PyrexTypes.CFakeReferenceType(PyrexTypes.c_const_type(typeinfo_entry.type))
10875
10876    cpp_message = 'typeid operator'
10877
10878    def analyse_types(self, env):
10879        self.cpp_check(env)
10880        type_info = self.get_type_info_type(env)
10881        if not type_info:
10882            self.error("The 'libcpp.typeinfo' module must be cimported to use the typeid() operator")
10883            return self
10884        self.type = type_info
10885        as_type = self.operand.analyse_as_type(env)
10886        if as_type:
10887            self.arg_type = as_type
10888            self.is_type = True
10889        else:
10890            self.arg_type = self.operand.analyse_types(env)
10891            self.is_type = False
10892            if self.arg_type.type.is_pyobject:
10893                self.error("Cannot use typeid on a Python object")
10894                return self
10895            elif self.arg_type.type.is_void:
10896                self.error("Cannot use typeid on void")
10897                return self
10898            elif not self.arg_type.type.is_complete():
10899                self.error("Cannot use typeid on incomplete type '%s'" % self.arg_type.type)
10900                return self
10901        env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
10902        return self
10903
10904    def error(self, mess):
10905        error(self.pos, mess)
10906        self.type = PyrexTypes.error_type
10907        self.result_code = "<error>"
10908
10909    def check_const(self):
10910        return True
10911
10912    def calculate_result_code(self):
10913        return self.temp_code
10914
10915    def generate_result_code(self, code):
10916        if self.is_type:
10917            arg_code = self.arg_type.empty_declaration_code()
10918        else:
10919            arg_code = self.arg_type.result()
10920        translate_cpp_exception(code, self.pos,
10921            "%s = typeid(%s);" % (self.temp_code, arg_code),
10922            None, None, self.in_nogil_context)
10923
10924class TypeofNode(ExprNode):
10925    #  Compile-time type of an expression, as a string.
10926    #
10927    #  operand   ExprNode
10928    #  literal   StringNode # internal
10929
10930    literal = None
10931    type = py_object_type
10932
10933    subexprs = ['literal'] # 'operand' will be ignored after type analysis!
10934
10935    def analyse_types(self, env):
10936        self.operand = self.operand.analyse_types(env)
10937        value = StringEncoding.EncodedString(str(self.operand.type)) #self.operand.type.typeof_name())
10938        literal = StringNode(self.pos, value=value)
10939        literal = literal.analyse_types(env)
10940        self.literal = literal.coerce_to_pyobject(env)
10941        return self
10942
10943    def analyse_as_type(self, env):
10944        self.operand = self.operand.analyse_types(env)
10945        return self.operand.type
10946
10947    def may_be_none(self):
10948        return False
10949
10950    def generate_evaluation_code(self, code):
10951        self.literal.generate_evaluation_code(code)
10952
10953    def calculate_result_code(self):
10954        return self.literal.calculate_result_code()
10955
10956#-------------------------------------------------------------------
10957#
10958#  Binary operator nodes
10959#
10960#-------------------------------------------------------------------
10961
10962try:
10963    matmul_operator = operator.matmul
10964except AttributeError:
10965    def matmul_operator(a, b):
10966        try:
10967            func = a.__matmul__
10968        except AttributeError:
10969            func = b.__rmatmul__
10970        return func(a, b)
10971
10972compile_time_binary_operators = {
10973    '<': operator.lt,
10974    '<=': operator.le,
10975    '==': operator.eq,
10976    '!=': operator.ne,
10977    '>=': operator.ge,
10978    '>': operator.gt,
10979    'is': operator.is_,
10980    'is_not': operator.is_not,
10981    '+': operator.add,
10982    '&': operator.and_,
10983    '/': operator.truediv,
10984    '//': operator.floordiv,
10985    '<<': operator.lshift,
10986    '%': operator.mod,
10987    '*': operator.mul,
10988    '|': operator.or_,
10989    '**': operator.pow,
10990    '>>': operator.rshift,
10991    '-': operator.sub,
10992    '^': operator.xor,
10993    '@': matmul_operator,
10994    'in': lambda x, seq: x in seq,
10995    'not_in': lambda x, seq: x not in seq,
10996}
10997
10998def get_compile_time_binop(node):
10999    func = compile_time_binary_operators.get(node.operator)
11000    if not func:
11001        error(node.pos,
11002            "Binary '%s' not supported in compile-time expression"
11003                % node.operator)
11004    return func
11005
11006
11007class BinopNode(ExprNode):
11008    #  operator     string
11009    #  operand1     ExprNode
11010    #  operand2     ExprNode
11011    #
11012    #  Processing during analyse_expressions phase:
11013    #
11014    #    analyse_c_operation
11015    #      Called when neither operand is a pyobject.
11016    #      - Check operand types and coerce if needed.
11017    #      - Determine result type and result code fragment.
11018    #      - Allocate temporary for result if needed.
11019
11020    subexprs = ['operand1', 'operand2']
11021    inplace = False
11022
11023    def calculate_constant_result(self):
11024        func = compile_time_binary_operators[self.operator]
11025        self.constant_result = func(
11026            self.operand1.constant_result,
11027            self.operand2.constant_result)
11028
11029    def compile_time_value(self, denv):
11030        func = get_compile_time_binop(self)
11031        operand1 = self.operand1.compile_time_value(denv)
11032        operand2 = self.operand2.compile_time_value(denv)
11033        try:
11034            return func(operand1, operand2)
11035        except Exception as e:
11036            self.compile_time_value_error(e)
11037
11038    def infer_type(self, env):
11039        return self.result_type(self.operand1.infer_type(env),
11040                                self.operand2.infer_type(env), env)
11041
11042    def analyse_types(self, env):
11043        self.operand1 = self.operand1.analyse_types(env)
11044        self.operand2 = self.operand2.analyse_types(env)
11045        self.analyse_operation(env)
11046        return self
11047
11048    def analyse_operation(self, env):
11049        if self.is_pythran_operation(env):
11050            self.type = self.result_type(self.operand1.type,
11051                                         self.operand2.type, env)
11052            assert self.type.is_pythran_expr
11053            self.is_temp = 1
11054        elif self.is_py_operation():
11055            self.coerce_operands_to_pyobjects(env)
11056            self.type = self.result_type(self.operand1.type,
11057                                         self.operand2.type, env)
11058            assert self.type.is_pyobject
11059            self.is_temp = 1
11060        elif self.is_cpp_operation():
11061            self.analyse_cpp_operation(env)
11062        else:
11063            self.analyse_c_operation(env)
11064
11065    def is_py_operation(self):
11066        return self.is_py_operation_types(self.operand1.type, self.operand2.type)
11067
11068    def is_py_operation_types(self, type1, type2):
11069        return type1.is_pyobject or type2.is_pyobject or type1.is_ctuple or type2.is_ctuple
11070
11071    def is_pythran_operation(self, env):
11072        return self.is_pythran_operation_types(self.operand1.type, self.operand2.type, env)
11073
11074    def is_pythran_operation_types(self, type1, type2, env):
11075        # Support only expr op supported_type, or supported_type op expr
11076        return has_np_pythran(env) and \
11077               (is_pythran_supported_operation_type(type1) and is_pythran_supported_operation_type(type2)) and \
11078               (is_pythran_expr(type1) or is_pythran_expr(type2))
11079
11080    def is_cpp_operation(self):
11081        return (self.operand1.type.is_cpp_class
11082            or self.operand2.type.is_cpp_class)
11083
11084    def analyse_cpp_operation(self, env):
11085        entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
11086        if not entry:
11087            self.type_error()
11088            return
11089        func_type = entry.type
11090        self.exception_check = func_type.exception_check
11091        self.exception_value = func_type.exception_value
11092        if self.exception_check == '+':
11093            # Used by NumBinopNodes to break up expressions involving multiple
11094            # operators so that exceptions can be handled properly.
11095            self.is_temp = 1
11096            if self.exception_value is None:
11097                env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
11098        if func_type.is_ptr:
11099            func_type = func_type.base_type
11100        if len(func_type.args) == 1:
11101            self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
11102        else:
11103            self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
11104            self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
11105        self.type = func_type.return_type
11106
11107    def result_type(self, type1, type2, env):
11108        if self.is_pythran_operation_types(type1, type2, env):
11109            return PythranExpr(pythran_binop_type(self.operator, type1, type2))
11110        if self.is_py_operation_types(type1, type2):
11111            if type2.is_string:
11112                type2 = Builtin.bytes_type
11113            elif type2.is_pyunicode_ptr:
11114                type2 = Builtin.unicode_type
11115            if type1.is_string:
11116                type1 = Builtin.bytes_type
11117            elif type1.is_pyunicode_ptr:
11118                type1 = Builtin.unicode_type
11119            if type1.is_builtin_type or type2.is_builtin_type:
11120                if type1 is type2 and self.operator in '**%+|&^':
11121                    # FIXME: at least these operators should be safe - others?
11122                    return type1
11123                result_type = self.infer_builtin_types_operation(type1, type2)
11124                if result_type is not None:
11125                    return result_type
11126            return py_object_type
11127        elif type1.is_error or type2.is_error:
11128            return PyrexTypes.error_type
11129        else:
11130            return self.compute_c_result_type(type1, type2)
11131
11132    def infer_builtin_types_operation(self, type1, type2):
11133        return None
11134
11135    def nogil_check(self, env):
11136        if self.is_py_operation():
11137            self.gil_error()
11138
11139    def coerce_operands_to_pyobjects(self, env):
11140        self.operand1 = self.operand1.coerce_to_pyobject(env)
11141        self.operand2 = self.operand2.coerce_to_pyobject(env)
11142
11143    def check_const(self):
11144        return self.operand1.check_const() and self.operand2.check_const()
11145
11146    def is_ephemeral(self):
11147        return (super(BinopNode, self).is_ephemeral() or
11148                self.operand1.is_ephemeral() or self.operand2.is_ephemeral())
11149
11150    def generate_result_code(self, code):
11151        if self.type.is_pythran_expr:
11152            code.putln("// Pythran binop")
11153            code.putln("__Pyx_call_destructor(%s);" % self.result())
11154            if self.operator == '**':
11155                code.putln("new (&%s) decltype(%s){pythonic::numpy::functor::power{}(%s, %s)};" % (
11156                    self.result(),
11157                    self.result(),
11158                    self.operand1.pythran_result(),
11159                    self.operand2.pythran_result()))
11160            else:
11161                code.putln("new (&%s) decltype(%s){%s %s %s};" % (
11162                    self.result(),
11163                    self.result(),
11164                    self.operand1.pythran_result(),
11165                    self.operator,
11166                    self.operand2.pythran_result()))
11167        elif self.operand1.type.is_pyobject:
11168            function = self.py_operation_function(code)
11169            if self.operator == '**':
11170                extra_args = ", Py_None"
11171            else:
11172                extra_args = ""
11173            code.putln(
11174                "%s = %s(%s, %s%s); %s" % (
11175                    self.result(),
11176                    function,
11177                    self.operand1.py_result(),
11178                    self.operand2.py_result(),
11179                    extra_args,
11180                    code.error_goto_if_null(self.result(), self.pos)))
11181            code.put_gotref(self.py_result())
11182        elif self.is_temp:
11183            # C++ overloaded operators with exception values are currently all
11184            # handled through temporaries.
11185            if self.is_cpp_operation() and self.exception_check == '+':
11186                translate_cpp_exception(code, self.pos,
11187                                        "%s = %s;" % (self.result(), self.calculate_result_code()),
11188                                        self.result() if self.type.is_pyobject else None,
11189                                        self.exception_value, self.in_nogil_context)
11190            else:
11191                code.putln("%s = %s;" % (self.result(), self.calculate_result_code()))
11192
11193    def type_error(self):
11194        if not (self.operand1.type.is_error
11195                or self.operand2.type.is_error):
11196            error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
11197                (self.operator, self.operand1.type,
11198                    self.operand2.type))
11199        self.type = PyrexTypes.error_type
11200
11201
11202class CBinopNode(BinopNode):
11203
11204    def analyse_types(self, env):
11205        node = BinopNode.analyse_types(self, env)
11206        if node.is_py_operation():
11207            node.type = PyrexTypes.error_type
11208        return node
11209
11210    def py_operation_function(self, code):
11211        return ""
11212
11213    def calculate_result_code(self):
11214        return "(%s %s %s)" % (
11215            self.operand1.result(),
11216            self.operator,
11217            self.operand2.result())
11218
11219    def compute_c_result_type(self, type1, type2):
11220        cpp_type = None
11221        if type1.is_cpp_class or type1.is_ptr:
11222            cpp_type = type1.find_cpp_operation_type(self.operator, type2)
11223        if cpp_type is None and (type2.is_cpp_class or type2.is_ptr):
11224            cpp_type = type2.find_cpp_operation_type(self.operator, type1)
11225        # FIXME: do we need to handle other cases here?
11226        return cpp_type
11227
11228
11229def c_binop_constructor(operator):
11230    def make_binop_node(pos, **operands):
11231        return CBinopNode(pos, operator=operator, **operands)
11232    return make_binop_node
11233
11234class NumBinopNode(BinopNode):
11235    #  Binary operation taking numeric arguments.
11236
11237    infix = True
11238    overflow_check = False
11239    overflow_bit_node = None
11240
11241    def analyse_c_operation(self, env):
11242        type1 = self.operand1.type
11243        type2 = self.operand2.type
11244        self.type = self.compute_c_result_type(type1, type2)
11245        if not self.type:
11246            self.type_error()
11247            return
11248        if self.type.is_complex:
11249            self.infix = False
11250        if (self.type.is_int
11251                and env.directives['overflowcheck']
11252                and self.operator in self.overflow_op_names):
11253            if (self.operator in ('+', '*')
11254                    and self.operand1.has_constant_result()
11255                    and not self.operand2.has_constant_result()):
11256                self.operand1, self.operand2 = self.operand2, self.operand1
11257            self.overflow_check = True
11258            self.overflow_fold = env.directives['overflowcheck.fold']
11259            self.func = self.type.overflow_check_binop(
11260                self.overflow_op_names[self.operator],
11261                env,
11262                const_rhs = self.operand2.has_constant_result())
11263            self.is_temp = True
11264        if not self.infix or (type1.is_numeric and type2.is_numeric):
11265            self.operand1 = self.operand1.coerce_to(self.type, env)
11266            self.operand2 = self.operand2.coerce_to(self.type, env)
11267
11268    def compute_c_result_type(self, type1, type2):
11269        if self.c_types_okay(type1, type2):
11270            widest_type = PyrexTypes.widest_numeric_type(type1, type2)
11271            if widest_type is PyrexTypes.c_bint_type:
11272                if self.operator not in '|^&':
11273                    # False + False == 0 # not False!
11274                    widest_type = PyrexTypes.c_int_type
11275            else:
11276                widest_type = PyrexTypes.widest_numeric_type(
11277                    widest_type, PyrexTypes.c_int_type)
11278            return widest_type
11279        else:
11280            return None
11281
11282    def may_be_none(self):
11283        if self.type and self.type.is_builtin_type:
11284            # if we know the result type, we know the operation, so it can't be None
11285            return False
11286        type1 = self.operand1.type
11287        type2 = self.operand2.type
11288        if type1 and type1.is_builtin_type and type2 and type2.is_builtin_type:
11289            # XXX: I can't think of any case where a binary operation
11290            # on builtin types evaluates to None - add a special case
11291            # here if there is one.
11292            return False
11293        return super(NumBinopNode, self).may_be_none()
11294
11295    def get_constant_c_result_code(self):
11296        value1 = self.operand1.get_constant_c_result_code()
11297        value2 = self.operand2.get_constant_c_result_code()
11298        if value1 and value2:
11299            return "(%s %s %s)" % (value1, self.operator, value2)
11300        else:
11301            return None
11302
11303    def c_types_okay(self, type1, type2):
11304        #print "NumBinopNode.c_types_okay:", type1, type2 ###
11305        return (type1.is_numeric  or type1.is_enum) \
11306            and (type2.is_numeric  or type2.is_enum)
11307
11308    def generate_evaluation_code(self, code):
11309        if self.overflow_check:
11310            self.overflow_bit_node = self
11311            self.overflow_bit = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
11312            code.putln("%s = 0;" % self.overflow_bit)
11313        super(NumBinopNode, self).generate_evaluation_code(code)
11314        if self.overflow_check:
11315            code.putln("if (unlikely(%s)) {" % self.overflow_bit)
11316            code.putln('PyErr_SetString(PyExc_OverflowError, "value too large");')
11317            code.putln(code.error_goto(self.pos))
11318            code.putln("}")
11319            code.funcstate.release_temp(self.overflow_bit)
11320
11321    def calculate_result_code(self):
11322        if self.overflow_bit_node is not None:
11323            return "%s(%s, %s, &%s)" % (
11324                self.func,
11325                self.operand1.result(),
11326                self.operand2.result(),
11327                self.overflow_bit_node.overflow_bit)
11328        elif self.type.is_cpp_class or self.infix:
11329            if is_pythran_expr(self.type):
11330                result1, result2 = self.operand1.pythran_result(), self.operand2.pythran_result()
11331            else:
11332                result1, result2 = self.operand1.result(), self.operand2.result()
11333            return "(%s %s %s)" % (result1, self.operator, result2)
11334        else:
11335            func = self.type.binary_op(self.operator)
11336            if func is None:
11337                error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
11338            return "%s(%s, %s)" % (
11339                func,
11340                self.operand1.result(),
11341                self.operand2.result())
11342
11343    def is_py_operation_types(self, type1, type2):
11344        return (type1.is_unicode_char or
11345                type2.is_unicode_char or
11346                BinopNode.is_py_operation_types(self, type1, type2))
11347
11348    def py_operation_function(self, code):
11349        function_name = self.py_functions[self.operator]
11350        if self.inplace:
11351            function_name = function_name.replace('PyNumber_', 'PyNumber_InPlace')
11352        return function_name
11353
11354    py_functions = {
11355        "|":        "PyNumber_Or",
11356        "^":        "PyNumber_Xor",
11357        "&":        "PyNumber_And",
11358        "<<":       "PyNumber_Lshift",
11359        ">>":       "PyNumber_Rshift",
11360        "+":        "PyNumber_Add",
11361        "-":        "PyNumber_Subtract",
11362        "*":        "PyNumber_Multiply",
11363        "@":        "__Pyx_PyNumber_MatrixMultiply",
11364        "/":        "__Pyx_PyNumber_Divide",
11365        "//":       "PyNumber_FloorDivide",
11366        "%":        "PyNumber_Remainder",
11367        "**":       "PyNumber_Power",
11368    }
11369
11370    overflow_op_names = {
11371        "+":  "add",
11372        "-":  "sub",
11373        "*":  "mul",
11374        "<<":  "lshift",
11375    }
11376
11377
11378class IntBinopNode(NumBinopNode):
11379    #  Binary operation taking integer arguments.
11380
11381    def c_types_okay(self, type1, type2):
11382        #print "IntBinopNode.c_types_okay:", type1, type2 ###
11383        return (type1.is_int or type1.is_enum) \
11384            and (type2.is_int or type2.is_enum)
11385
11386
11387class AddNode(NumBinopNode):
11388    #  '+' operator.
11389
11390    def is_py_operation_types(self, type1, type2):
11391        if type1.is_string and type2.is_string or type1.is_pyunicode_ptr and type2.is_pyunicode_ptr:
11392            return 1
11393        else:
11394            return NumBinopNode.is_py_operation_types(self, type1, type2)
11395
11396    def infer_builtin_types_operation(self, type1, type2):
11397        # b'abc' + 'abc' raises an exception in Py3,
11398        # so we can safely infer the Py2 type for bytes here
11399        string_types = (bytes_type, bytearray_type, str_type, basestring_type, unicode_type)
11400        if type1 in string_types and type2 in string_types:
11401            return string_types[max(string_types.index(type1),
11402                                    string_types.index(type2))]
11403        return None
11404
11405    def compute_c_result_type(self, type1, type2):
11406        #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
11407        if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
11408            return type1
11409        elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
11410            return type2
11411        else:
11412            return NumBinopNode.compute_c_result_type(
11413                self, type1, type2)
11414
11415    def py_operation_function(self, code):
11416        type1, type2 = self.operand1.type, self.operand2.type
11417
11418        if type1 is unicode_type or type2 is unicode_type:
11419            if type1 in (unicode_type, str_type) and type2 in (unicode_type, str_type):
11420                is_unicode_concat = True
11421            elif isinstance(self.operand1, FormattedValueNode) or isinstance(self.operand2, FormattedValueNode):
11422                # Assume that even if we don't know the second type, it's going to be a string.
11423                is_unicode_concat = True
11424            else:
11425                # Operation depends on the second type.
11426                is_unicode_concat = False
11427
11428            if is_unicode_concat:
11429                if self.operand1.may_be_none() or self.operand2.may_be_none():
11430                    return '__Pyx_PyUnicode_ConcatSafe'
11431                else:
11432                    return '__Pyx_PyUnicode_Concat'
11433
11434        return super(AddNode, self).py_operation_function(code)
11435
11436
11437class SubNode(NumBinopNode):
11438    #  '-' operator.
11439
11440    def compute_c_result_type(self, type1, type2):
11441        if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
11442            return type1
11443        elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
11444            return PyrexTypes.c_ptrdiff_t_type
11445        else:
11446            return NumBinopNode.compute_c_result_type(
11447                self, type1, type2)
11448
11449
11450class MulNode(NumBinopNode):
11451    #  '*' operator.
11452
11453    def is_py_operation_types(self, type1, type2):
11454        if ((type1.is_string and type2.is_int) or
11455                (type2.is_string and type1.is_int)):
11456            return 1
11457        else:
11458            return NumBinopNode.is_py_operation_types(self, type1, type2)
11459
11460    def infer_builtin_types_operation(self, type1, type2):
11461        # let's assume that whatever builtin type you multiply a string with
11462        # will either return a string of the same type or fail with an exception
11463        string_types = (bytes_type, bytearray_type, str_type, basestring_type, unicode_type)
11464        if type1 in string_types and type2.is_builtin_type:
11465            return type1
11466        if type2 in string_types and type1.is_builtin_type:
11467            return type2
11468        # multiplication of containers/numbers with an integer value
11469        # always (?) returns the same type
11470        if type1.is_int:
11471            return type2
11472        if type2.is_int:
11473            return type1
11474        return None
11475
11476
11477class MatMultNode(NumBinopNode):
11478    #  '@' operator.
11479
11480    def is_py_operation_types(self, type1, type2):
11481        return True
11482
11483    def generate_evaluation_code(self, code):
11484        code.globalstate.use_utility_code(UtilityCode.load_cached("MatrixMultiply", "ObjectHandling.c"))
11485        super(MatMultNode, self).generate_evaluation_code(code)
11486
11487
11488class DivNode(NumBinopNode):
11489    #  '/' or '//' operator.
11490
11491    cdivision = None
11492    truedivision = None   # == "unknown" if operator == '/'
11493    ctruedivision = False
11494    cdivision_warnings = False
11495    zerodivision_check = None
11496
11497    def find_compile_time_binary_operator(self, op1, op2):
11498        func = compile_time_binary_operators[self.operator]
11499        if self.operator == '/' and self.truedivision is None:
11500            # => true div for floats, floor div for integers
11501            if isinstance(op1, _py_int_types) and isinstance(op2, _py_int_types):
11502                func = compile_time_binary_operators['//']
11503        return func
11504
11505    def calculate_constant_result(self):
11506        op1 = self.operand1.constant_result
11507        op2 = self.operand2.constant_result
11508        func = self.find_compile_time_binary_operator(op1, op2)
11509        self.constant_result = func(
11510            self.operand1.constant_result,
11511            self.operand2.constant_result)
11512
11513    def compile_time_value(self, denv):
11514        operand1 = self.operand1.compile_time_value(denv)
11515        operand2 = self.operand2.compile_time_value(denv)
11516        try:
11517            func = self.find_compile_time_binary_operator(
11518                operand1, operand2)
11519            return func(operand1, operand2)
11520        except Exception as e:
11521            self.compile_time_value_error(e)
11522
11523    def _check_truedivision(self, env):
11524        if self.cdivision or env.directives['cdivision']:
11525            self.ctruedivision = False
11526        else:
11527            self.ctruedivision = self.truedivision
11528
11529    def infer_type(self, env):
11530        self._check_truedivision(env)
11531        return self.result_type(
11532            self.operand1.infer_type(env),
11533            self.operand2.infer_type(env), env)
11534
11535    def analyse_operation(self, env):
11536        self._check_truedivision(env)
11537        NumBinopNode.analyse_operation(self, env)
11538        if self.is_cpp_operation():
11539            self.cdivision = True
11540        if not self.type.is_pyobject:
11541            self.zerodivision_check = (
11542                self.cdivision is None and not env.directives['cdivision']
11543                and (not self.operand2.has_constant_result() or
11544                     self.operand2.constant_result == 0))
11545            if self.zerodivision_check or env.directives['cdivision_warnings']:
11546                # Need to check ahead of time to warn or raise zero division error
11547                self.operand1 = self.operand1.coerce_to_simple(env)
11548                self.operand2 = self.operand2.coerce_to_simple(env)
11549
11550    def compute_c_result_type(self, type1, type2):
11551        if self.operator == '/' and self.ctruedivision and not type1.is_cpp_class and not type2.is_cpp_class:
11552            if not type1.is_float and not type2.is_float:
11553                widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
11554                widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
11555                return widest_type
11556        return NumBinopNode.compute_c_result_type(self, type1, type2)
11557
11558    def zero_division_message(self):
11559        if self.type.is_int:
11560            return "integer division or modulo by zero"
11561        else:
11562            return "float division"
11563
11564    def generate_evaluation_code(self, code):
11565        if not self.type.is_pyobject and not self.type.is_complex:
11566            if self.cdivision is None:
11567                self.cdivision = (
11568                    code.globalstate.directives['cdivision']
11569                    or self.type.is_float
11570                    or ((self.type.is_numeric or self.type.is_enum) and not self.type.signed)
11571                )
11572            if not self.cdivision:
11573                code.globalstate.use_utility_code(
11574                    UtilityCode.load_cached("DivInt", "CMath.c").specialize(self.type))
11575        NumBinopNode.generate_evaluation_code(self, code)
11576        self.generate_div_warning_code(code)
11577
11578    def generate_div_warning_code(self, code):
11579        in_nogil = self.in_nogil_context
11580        if not self.type.is_pyobject:
11581            if self.zerodivision_check:
11582                if not self.infix:
11583                    zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
11584                else:
11585                    zero_test = "%s == 0" % self.operand2.result()
11586                code.putln("if (unlikely(%s)) {" % zero_test)
11587                if in_nogil:
11588                    code.put_ensure_gil()
11589                code.putln('PyErr_SetString(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
11590                if in_nogil:
11591                    code.put_release_ensured_gil()
11592                code.putln(code.error_goto(self.pos))
11593                code.putln("}")
11594                if self.type.is_int and self.type.signed and self.operator != '%':
11595                    code.globalstate.use_utility_code(UtilityCode.load_cached("UnaryNegOverflows", "Overflow.c"))
11596                    if self.operand2.type.signed == 2:
11597                        # explicitly signed, no runtime check needed
11598                        minus1_check = 'unlikely(%s == -1)' % self.operand2.result()
11599                    else:
11600                        type_of_op2 = self.operand2.type.empty_declaration_code()
11601                        minus1_check = '(!(((%s)-1) > 0)) && unlikely(%s == (%s)-1)' % (
11602                            type_of_op2, self.operand2.result(), type_of_op2)
11603                    code.putln("else if (sizeof(%s) == sizeof(long) && %s "
11604                               " && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
11605                               self.type.empty_declaration_code(),
11606                               minus1_check,
11607                               self.operand1.result()))
11608                    if in_nogil:
11609                        code.put_ensure_gil()
11610                    code.putln('PyErr_SetString(PyExc_OverflowError, "value too large to perform division");')
11611                    if in_nogil:
11612                        code.put_release_ensured_gil()
11613                    code.putln(code.error_goto(self.pos))
11614                    code.putln("}")
11615            if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
11616                code.globalstate.use_utility_code(
11617                    UtilityCode.load_cached("CDivisionWarning", "CMath.c"))
11618                code.putln("if (unlikely((%s < 0) ^ (%s < 0))) {" % (
11619                                self.operand1.result(),
11620                                self.operand2.result()))
11621                warning_code = "__Pyx_cdivision_warning(%(FILENAME)s, %(LINENO)s)" % {
11622                    'FILENAME': Naming.filename_cname,
11623                    'LINENO':  Naming.lineno_cname,
11624                }
11625
11626                if in_nogil:
11627                    result_code = 'result'
11628                    code.putln("int %s;" % result_code)
11629                    code.put_ensure_gil()
11630                    code.putln(code.set_error_info(self.pos, used=True))
11631                    code.putln("%s = %s;" % (result_code, warning_code))
11632                    code.put_release_ensured_gil()
11633                else:
11634                    result_code = warning_code
11635                    code.putln(code.set_error_info(self.pos, used=True))
11636
11637                code.put("if (unlikely(%s)) " % result_code)
11638                code.put_goto(code.error_label)
11639                code.putln("}")
11640
11641    def calculate_result_code(self):
11642        if self.type.is_complex or self.is_cpp_operation():
11643            return NumBinopNode.calculate_result_code(self)
11644        elif self.type.is_float and self.operator == '//':
11645            return "floor(%s / %s)" % (
11646                self.operand1.result(),
11647                self.operand2.result())
11648        elif self.truedivision or self.cdivision:
11649            op1 = self.operand1.result()
11650            op2 = self.operand2.result()
11651            if self.truedivision:
11652                if self.type != self.operand1.type:
11653                    op1 = self.type.cast_code(op1)
11654                if self.type != self.operand2.type:
11655                    op2 = self.type.cast_code(op2)
11656            return "(%s / %s)" % (op1, op2)
11657        else:
11658            return "__Pyx_div_%s(%s, %s)" % (
11659                self.type.specialization_name(),
11660                self.operand1.result(),
11661                self.operand2.result())
11662
11663
11664_find_formatting_types = re.compile(
11665    br"%"
11666    br"(?:%|"  # %%
11667    br"(?:\([^)]+\))?"  # %(name)
11668    br"[-+#,0-9 ]*([a-z])"  # %.2f  etc.
11669    br")").findall
11670
11671# These format conversion types can never trigger a Unicode string conversion in Py2.
11672_safe_bytes_formats = set([
11673    # Excludes 's' and 'r', which can generate non-bytes strings.
11674    b'd', b'i', b'o', b'u', b'x', b'X', b'e', b'E', b'f', b'F', b'g', b'G', b'c', b'b', b'a',
11675])
11676
11677
11678class ModNode(DivNode):
11679    #  '%' operator.
11680
11681    def is_py_operation_types(self, type1, type2):
11682        return (type1.is_string
11683                or type2.is_string
11684                or NumBinopNode.is_py_operation_types(self, type1, type2))
11685
11686    def infer_builtin_types_operation(self, type1, type2):
11687        # b'%s' % xyz  raises an exception in Py3<3.5, so it's safe to infer the type for Py2 and later Py3's.
11688        if type1 is unicode_type:
11689            # None + xyz  may be implemented by RHS
11690            if type2.is_builtin_type or not self.operand1.may_be_none():
11691                return type1
11692        elif type1 in (bytes_type, str_type, basestring_type):
11693            if type2 is unicode_type:
11694                return type2
11695            elif type2.is_numeric:
11696                return type1
11697            elif self.operand1.is_string_literal:
11698                if type1 is str_type or type1 is bytes_type:
11699                    if set(_find_formatting_types(self.operand1.value)) <= _safe_bytes_formats:
11700                        return type1
11701                return basestring_type
11702            elif type1 is bytes_type and not type2.is_builtin_type:
11703                return None   # RHS might implement '% operator differently in Py3
11704            else:
11705                return basestring_type  # either str or unicode, can't tell
11706        return None
11707
11708    def zero_division_message(self):
11709        if self.type.is_int:
11710            return "integer division or modulo by zero"
11711        else:
11712            return "float divmod()"
11713
11714    def analyse_operation(self, env):
11715        DivNode.analyse_operation(self, env)
11716        if not self.type.is_pyobject:
11717            if self.cdivision is None:
11718                self.cdivision = env.directives['cdivision'] or not self.type.signed
11719            if not self.cdivision and not self.type.is_int and not self.type.is_float:
11720                error(self.pos, "mod operator not supported for type '%s'" % self.type)
11721
11722    def generate_evaluation_code(self, code):
11723        if not self.type.is_pyobject and not self.cdivision:
11724            if self.type.is_int:
11725                code.globalstate.use_utility_code(
11726                    UtilityCode.load_cached("ModInt", "CMath.c").specialize(self.type))
11727            else:  # float
11728                code.globalstate.use_utility_code(
11729                    UtilityCode.load_cached("ModFloat", "CMath.c").specialize(
11730                        self.type, math_h_modifier=self.type.math_h_modifier))
11731        # NOTE: skipping over DivNode here
11732        NumBinopNode.generate_evaluation_code(self, code)
11733        self.generate_div_warning_code(code)
11734
11735    def calculate_result_code(self):
11736        if self.cdivision:
11737            if self.type.is_float:
11738                return "fmod%s(%s, %s)" % (
11739                    self.type.math_h_modifier,
11740                    self.operand1.result(),
11741                    self.operand2.result())
11742            else:
11743                return "(%s %% %s)" % (
11744                    self.operand1.result(),
11745                    self.operand2.result())
11746        else:
11747            return "__Pyx_mod_%s(%s, %s)" % (
11748                    self.type.specialization_name(),
11749                    self.operand1.result(),
11750                    self.operand2.result())
11751
11752    def py_operation_function(self, code):
11753        type1, type2 = self.operand1.type, self.operand2.type
11754        # ("..." % x)  must call "x.__rmod__()" for string subtypes.
11755        if type1 is unicode_type:
11756            if self.operand1.may_be_none() or (
11757                    type2.is_extension_type and type2.subtype_of(type1) or
11758                    type2 is py_object_type and not isinstance(self.operand2, CoerceToPyTypeNode)):
11759                return '__Pyx_PyUnicode_FormatSafe'
11760            else:
11761                return 'PyUnicode_Format'
11762        elif type1 is str_type:
11763            if self.operand1.may_be_none() or (
11764                    type2.is_extension_type and type2.subtype_of(type1) or
11765                    type2 is py_object_type and not isinstance(self.operand2, CoerceToPyTypeNode)):
11766                return '__Pyx_PyString_FormatSafe'
11767            else:
11768                return '__Pyx_PyString_Format'
11769        return super(ModNode, self).py_operation_function(code)
11770
11771
11772class PowNode(NumBinopNode):
11773    #  '**' operator.
11774
11775    def analyse_c_operation(self, env):
11776        NumBinopNode.analyse_c_operation(self, env)
11777        if self.type.is_complex:
11778            if self.type.real_type.is_float:
11779                self.operand1 = self.operand1.coerce_to(self.type, env)
11780                self.operand2 = self.operand2.coerce_to(self.type, env)
11781                self.pow_func = self.type.binary_op('**')
11782            else:
11783                error(self.pos, "complex int powers not supported")
11784                self.pow_func = "<error>"
11785        elif self.type.is_float:
11786            self.pow_func = "pow" + self.type.math_h_modifier
11787        elif self.type.is_int:
11788            self.pow_func = "__Pyx_pow_%s" % self.type.empty_declaration_code().replace(' ', '_')
11789            env.use_utility_code(
11790                UtilityCode.load_cached("IntPow", "CMath.c").specialize(
11791                    func_name=self.pow_func,
11792                    type=self.type.empty_declaration_code(),
11793                    signed=self.type.signed and 1 or 0))
11794        elif not self.type.is_error:
11795            error(self.pos, "got unexpected types for C power operator: %s, %s" %
11796                            (self.operand1.type, self.operand2.type))
11797
11798    def calculate_result_code(self):
11799        # Work around MSVC overloading ambiguity.
11800        def typecast(operand):
11801            if self.type == operand.type:
11802                return operand.result()
11803            else:
11804                return self.type.cast_code(operand.result())
11805        return "%s(%s, %s)" % (
11806            self.pow_func,
11807            typecast(self.operand1),
11808            typecast(self.operand2))
11809
11810    def py_operation_function(self, code):
11811        if (self.type.is_pyobject and
11812                self.operand1.constant_result == 2 and
11813                isinstance(self.operand1.constant_result, _py_int_types) and
11814                self.operand2.type is py_object_type):
11815            code.globalstate.use_utility_code(UtilityCode.load_cached('PyNumberPow2', 'Optimize.c'))
11816            if self.inplace:
11817                return '__Pyx_PyNumber_InPlacePowerOf2'
11818            else:
11819                return '__Pyx_PyNumber_PowerOf2'
11820        return super(PowNode, self).py_operation_function(code)
11821
11822
11823class BoolBinopNode(ExprNode):
11824    """
11825    Short-circuiting boolean operation.
11826
11827    Note that this node provides the same code generation method as
11828    BoolBinopResultNode to simplify expression nesting.
11829
11830    operator  string                              "and"/"or"
11831    operand1  BoolBinopNode/BoolBinopResultNode   left operand
11832    operand2  BoolBinopNode/BoolBinopResultNode   right operand
11833    """
11834    subexprs = ['operand1', 'operand2']
11835    is_temp = True
11836    operator = None
11837    operand1 = None
11838    operand2 = None
11839
11840    def infer_type(self, env):
11841        type1 = self.operand1.infer_type(env)
11842        type2 = self.operand2.infer_type(env)
11843        return PyrexTypes.independent_spanning_type(type1, type2)
11844
11845    def may_be_none(self):
11846        if self.operator == 'or':
11847            return self.operand2.may_be_none()
11848        else:
11849            return self.operand1.may_be_none() or self.operand2.may_be_none()
11850
11851    def calculate_constant_result(self):
11852        operand1 = self.operand1.constant_result
11853        operand2 = self.operand2.constant_result
11854        if self.operator == 'and':
11855            self.constant_result = operand1 and operand2
11856        else:
11857            self.constant_result = operand1 or operand2
11858
11859    def compile_time_value(self, denv):
11860        operand1 = self.operand1.compile_time_value(denv)
11861        operand2 = self.operand2.compile_time_value(denv)
11862        if self.operator == 'and':
11863            return operand1 and operand2
11864        else:
11865            return operand1 or operand2
11866
11867    def is_ephemeral(self):
11868        return self.operand1.is_ephemeral() or self.operand2.is_ephemeral()
11869
11870    def analyse_types(self, env):
11871        # Note: we do not do any coercion here as we most likely do not know the final type anyway.
11872        # We even accept to set self.type to ErrorType if both operands do not have a spanning type.
11873        # The coercion to the final type and to a "simple" value is left to coerce_to().
11874        operand1 = self.operand1.analyse_types(env)
11875        operand2 = self.operand2.analyse_types(env)
11876        self.type = PyrexTypes.independent_spanning_type(
11877            operand1.type, operand2.type)
11878        self.operand1 = self._wrap_operand(operand1, env)
11879        self.operand2 = self._wrap_operand(operand2, env)
11880        return self
11881
11882    def _wrap_operand(self, operand, env):
11883        if not isinstance(operand, (BoolBinopNode, BoolBinopResultNode)):
11884            operand = BoolBinopResultNode(operand, self.type, env)
11885        return operand
11886
11887    def wrap_operands(self, env):
11888        """
11889        Must get called by transforms that want to create a correct BoolBinopNode
11890        after the type analysis phase.
11891        """
11892        self.operand1 = self._wrap_operand(self.operand1, env)
11893        self.operand2 = self._wrap_operand(self.operand2, env)
11894
11895    def coerce_to_boolean(self, env):
11896        return self.coerce_to(PyrexTypes.c_bint_type, env)
11897
11898    def coerce_to(self, dst_type, env):
11899        operand1 = self.operand1.coerce_to(dst_type, env)
11900        operand2 = self.operand2.coerce_to(dst_type, env)
11901        return BoolBinopNode.from_node(
11902            self, type=dst_type,
11903            operator=self.operator,
11904            operand1=operand1, operand2=operand2)
11905
11906    def generate_bool_evaluation_code(self, code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through):
11907        code.mark_pos(self.pos)
11908
11909        outer_labels = (and_label, or_label)
11910        if self.operator == 'and':
11911            my_label = and_label = code.new_label('next_and')
11912        else:
11913            my_label = or_label = code.new_label('next_or')
11914        self.operand1.generate_bool_evaluation_code(
11915            code, final_result_temp, final_result_type, and_label, or_label, end_label, my_label)
11916
11917        and_label, or_label = outer_labels
11918
11919        code.put_label(my_label)
11920        self.operand2.generate_bool_evaluation_code(
11921            code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through)
11922
11923    def generate_evaluation_code(self, code):
11924        self.allocate_temp_result(code)
11925        result_type = PyrexTypes.py_object_type if self.type.is_pyobject else self.type
11926        or_label = and_label = None
11927        end_label = code.new_label('bool_binop_done')
11928        self.generate_bool_evaluation_code(code, self.result(), result_type, and_label, or_label, end_label, end_label)
11929        code.put_label(end_label)
11930
11931    gil_message = "Truth-testing Python object"
11932
11933    def check_const(self):
11934        return self.operand1.check_const() and self.operand2.check_const()
11935
11936    def generate_subexpr_disposal_code(self, code):
11937        pass  # nothing to do here, all done in generate_evaluation_code()
11938
11939    def free_subexpr_temps(self, code):
11940        pass  # nothing to do here, all done in generate_evaluation_code()
11941
11942    def generate_operand1_test(self, code):
11943        #  Generate code to test the truth of the first operand.
11944        if self.type.is_pyobject:
11945            test_result = code.funcstate.allocate_temp(
11946                PyrexTypes.c_bint_type, manage_ref=False)
11947            code.putln(
11948                "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
11949                    test_result,
11950                    self.operand1.py_result(),
11951                    code.error_goto_if_neg(test_result, self.pos)))
11952        else:
11953            test_result = self.operand1.result()
11954        return (test_result, self.type.is_pyobject)
11955
11956
11957class BoolBinopResultNode(ExprNode):
11958    """
11959    Intermediate result of a short-circuiting and/or expression.
11960    Tests the result for 'truthiness' and takes care of coercing the final result
11961    of the overall expression to the target type.
11962
11963    Note that this node provides the same code generation method as
11964    BoolBinopNode to simplify expression nesting.
11965
11966    arg     ExprNode    the argument to test
11967    value   ExprNode    the coerced result value node
11968    """
11969
11970    subexprs = ['arg', 'value']
11971    is_temp = True
11972    arg = None
11973    value = None
11974
11975    def __init__(self, arg, result_type, env):
11976        # using 'arg' multiple times, so it must be a simple/temp value
11977        arg = arg.coerce_to_simple(env)
11978        # wrap in ProxyNode, in case a transform wants to replace self.arg later
11979        arg = ProxyNode(arg)
11980        super(BoolBinopResultNode, self).__init__(
11981            arg.pos, arg=arg, type=result_type,
11982            value=CloneNode(arg).coerce_to(result_type, env))
11983
11984    def coerce_to_boolean(self, env):
11985        return self.coerce_to(PyrexTypes.c_bint_type, env)
11986
11987    def coerce_to(self, dst_type, env):
11988        # unwrap, coerce, rewrap
11989        arg = self.arg.arg
11990        if dst_type is PyrexTypes.c_bint_type:
11991            arg = arg.coerce_to_boolean(env)
11992        # TODO: unwrap more coercion nodes?
11993        return BoolBinopResultNode(arg, dst_type, env)
11994
11995    def nogil_check(self, env):
11996        # let's leave all errors to BoolBinopNode
11997        pass
11998
11999    def generate_operand_test(self, code):
12000        #  Generate code to test the truth of the first operand.
12001        if self.arg.type.is_pyobject:
12002            test_result = code.funcstate.allocate_temp(
12003                PyrexTypes.c_bint_type, manage_ref=False)
12004            code.putln(
12005                "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
12006                    test_result,
12007                    self.arg.py_result(),
12008                    code.error_goto_if_neg(test_result, self.pos)))
12009        else:
12010            test_result = self.arg.result()
12011        return (test_result, self.arg.type.is_pyobject)
12012
12013    def generate_bool_evaluation_code(self, code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through):
12014        code.mark_pos(self.pos)
12015
12016        # x => x
12017        # x and ... or ... => next 'and' / 'or'
12018        # False ... or x => next 'or'
12019        # True and x => next 'and'
12020        # True or x => True (operand)
12021
12022        self.arg.generate_evaluation_code(code)
12023        if and_label or or_label:
12024            test_result, uses_temp = self.generate_operand_test(code)
12025            if uses_temp and (and_label and or_label):
12026                # cannot become final result => free early
12027                # disposal: uses_temp and (and_label and or_label)
12028                self.arg.generate_disposal_code(code)
12029            sense = '!' if or_label else ''
12030            code.putln("if (%s%s) {" % (sense, test_result))
12031            if uses_temp:
12032                code.funcstate.release_temp(test_result)
12033            if not uses_temp or not (and_label and or_label):
12034                # disposal: (not uses_temp) or {not (and_label and or_label) [if]}
12035                self.arg.generate_disposal_code(code)
12036
12037            if or_label and or_label != fall_through:
12038                # value is false => short-circuit to next 'or'
12039                code.put_goto(or_label)
12040            if and_label:
12041                # value is true => go to next 'and'
12042                if or_label:
12043                    code.putln("} else {")
12044                    if not uses_temp:
12045                        # disposal: (not uses_temp) and {(and_label and or_label) [else]}
12046                        self.arg.generate_disposal_code(code)
12047                if and_label != fall_through:
12048                    code.put_goto(and_label)
12049
12050        if not and_label or not or_label:
12051            # if no next 'and' or 'or', we provide the result
12052            if and_label or or_label:
12053                code.putln("} else {")
12054            self.value.generate_evaluation_code(code)
12055            self.value.make_owned_reference(code)
12056            code.putln("%s = %s;" % (final_result_temp, self.value.result_as(final_result_type)))
12057            self.value.generate_post_assignment_code(code)
12058            # disposal: {not (and_label and or_label) [else]}
12059            self.arg.generate_disposal_code(code)
12060            self.value.free_temps(code)
12061            if end_label != fall_through:
12062                code.put_goto(end_label)
12063
12064        if and_label or or_label:
12065            code.putln("}")
12066        self.arg.free_temps(code)
12067
12068
12069class CondExprNode(ExprNode):
12070    #  Short-circuiting conditional expression.
12071    #
12072    #  test        ExprNode
12073    #  true_val    ExprNode
12074    #  false_val   ExprNode
12075
12076    true_val = None
12077    false_val = None
12078    is_temp = True
12079
12080    subexprs = ['test', 'true_val', 'false_val']
12081
12082    def type_dependencies(self, env):
12083        return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
12084
12085    def infer_type(self, env):
12086        return PyrexTypes.independent_spanning_type(
12087            self.true_val.infer_type(env),
12088            self.false_val.infer_type(env))
12089
12090    def calculate_constant_result(self):
12091        if self.test.constant_result:
12092            self.constant_result = self.true_val.constant_result
12093        else:
12094            self.constant_result = self.false_val.constant_result
12095
12096    def is_ephemeral(self):
12097        return self.true_val.is_ephemeral() or self.false_val.is_ephemeral()
12098
12099    def analyse_types(self, env):
12100        self.test = self.test.analyse_types(env).coerce_to_boolean(env)
12101        self.true_val = self.true_val.analyse_types(env)
12102        self.false_val = self.false_val.analyse_types(env)
12103        return self.analyse_result_type(env)
12104
12105    def analyse_result_type(self, env):
12106        self.type = PyrexTypes.independent_spanning_type(
12107            self.true_val.type, self.false_val.type)
12108        if self.type.is_reference:
12109            self.type = PyrexTypes.CFakeReferenceType(self.type.ref_base_type)
12110        if self.type.is_pyobject:
12111            self.result_ctype = py_object_type
12112        elif self.true_val.is_ephemeral() or self.false_val.is_ephemeral():
12113            error(self.pos, "Unsafe C derivative of temporary Python reference used in conditional expression")
12114        if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
12115            self.true_val = self.true_val.coerce_to(self.type, env)
12116            self.false_val = self.false_val.coerce_to(self.type, env)
12117        if self.type.is_error:
12118            self.type_error()
12119        return self
12120
12121    def coerce_to_integer(self, env):
12122        self.true_val = self.true_val.coerce_to_integer(env)
12123        self.false_val = self.false_val.coerce_to_integer(env)
12124        self.result_ctype = None
12125        return self.analyse_result_type(env)
12126
12127    def coerce_to(self, dst_type, env):
12128        self.true_val = self.true_val.coerce_to(dst_type, env)
12129        self.false_val = self.false_val.coerce_to(dst_type, env)
12130        self.result_ctype = None
12131        return self.analyse_result_type(env)
12132
12133    def type_error(self):
12134        if not (self.true_val.type.is_error or self.false_val.type.is_error):
12135            error(self.pos, "Incompatible types in conditional expression (%s; %s)" %
12136                (self.true_val.type, self.false_val.type))
12137        self.type = PyrexTypes.error_type
12138
12139    def check_const(self):
12140        return (self.test.check_const()
12141            and self.true_val.check_const()
12142            and self.false_val.check_const())
12143
12144    def generate_evaluation_code(self, code):
12145        # Because subexprs may not be evaluated we can use a more optimal
12146        # subexpr allocation strategy than the default, so override evaluation_code.
12147
12148        code.mark_pos(self.pos)
12149        self.allocate_temp_result(code)
12150        self.test.generate_evaluation_code(code)
12151        code.putln("if (%s) {" % self.test.result())
12152        self.eval_and_get(code, self.true_val)
12153        code.putln("} else {")
12154        self.eval_and_get(code, self.false_val)
12155        code.putln("}")
12156        self.test.generate_disposal_code(code)
12157        self.test.free_temps(code)
12158
12159    def eval_and_get(self, code, expr):
12160        expr.generate_evaluation_code(code)
12161        if self.type.is_memoryviewslice:
12162            expr.make_owned_memoryviewslice(code)
12163        else:
12164            expr.make_owned_reference(code)
12165        code.putln('%s = %s;' % (self.result(), expr.result_as(self.ctype())))
12166        expr.generate_post_assignment_code(code)
12167        expr.free_temps(code)
12168
12169    def generate_subexpr_disposal_code(self, code):
12170        pass  # done explicitly above (cleanup must separately happen within the if/else blocks)
12171
12172    def free_subexpr_temps(self, code):
12173        pass  # done explicitly above (cleanup must separately happen within the if/else blocks)
12174
12175
12176richcmp_constants = {
12177    "<" : "Py_LT",
12178    "<=": "Py_LE",
12179    "==": "Py_EQ",
12180    "!=": "Py_NE",
12181    "<>": "Py_NE",
12182    ">" : "Py_GT",
12183    ">=": "Py_GE",
12184    # the following are faked by special compare functions
12185    "in"    : "Py_EQ",
12186    "not_in": "Py_NE",
12187}
12188
12189class CmpNode(object):
12190    #  Mixin class containing code common to PrimaryCmpNodes
12191    #  and CascadedCmpNodes.
12192
12193    special_bool_cmp_function = None
12194    special_bool_cmp_utility_code = None
12195
12196    def infer_type(self, env):
12197        # TODO: Actually implement this (after merging with -unstable).
12198        return py_object_type
12199
12200    def calculate_cascaded_constant_result(self, operand1_result):
12201        func = compile_time_binary_operators[self.operator]
12202        operand2_result = self.operand2.constant_result
12203        if (isinstance(operand1_result, any_string_type) and
12204                isinstance(operand2_result, any_string_type) and
12205                type(operand1_result) != type(operand2_result)):
12206            # string comparison of different types isn't portable
12207            return
12208
12209        if self.operator in ('in', 'not_in'):
12210            if isinstance(self.operand2, (ListNode, TupleNode, SetNode)):
12211                if not self.operand2.args:
12212                    self.constant_result = self.operator == 'not_in'
12213                    return
12214                elif isinstance(self.operand2, ListNode) and not self.cascade:
12215                    # tuples are more efficient to store than lists
12216                    self.operand2 = self.operand2.as_tuple()
12217            elif isinstance(self.operand2, DictNode):
12218                if not self.operand2.key_value_pairs:
12219                    self.constant_result = self.operator == 'not_in'
12220                    return
12221
12222        self.constant_result = func(operand1_result, operand2_result)
12223
12224    def cascaded_compile_time_value(self, operand1, denv):
12225        func = get_compile_time_binop(self)
12226        operand2 = self.operand2.compile_time_value(denv)
12227        try:
12228            result = func(operand1, operand2)
12229        except Exception as e:
12230            self.compile_time_value_error(e)
12231            result = None
12232        if result:
12233            cascade = self.cascade
12234            if cascade:
12235                result = result and cascade.cascaded_compile_time_value(operand2, denv)
12236        return result
12237
12238    def is_cpp_comparison(self):
12239        return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
12240
12241    def find_common_int_type(self, env, op, operand1, operand2):
12242        # type1 != type2 and at least one of the types is not a C int
12243        type1 = operand1.type
12244        type2 = operand2.type
12245        type1_can_be_int = False
12246        type2_can_be_int = False
12247
12248        if operand1.is_string_literal and operand1.can_coerce_to_char_literal():
12249            type1_can_be_int = True
12250        if operand2.is_string_literal and operand2.can_coerce_to_char_literal():
12251            type2_can_be_int = True
12252
12253        if type1.is_int:
12254            if type2_can_be_int:
12255                return type1
12256        elif type2.is_int:
12257            if type1_can_be_int:
12258                return type2
12259        elif type1_can_be_int:
12260            if type2_can_be_int:
12261                if Builtin.unicode_type in (type1, type2):
12262                    return PyrexTypes.c_py_ucs4_type
12263                else:
12264                    return PyrexTypes.c_uchar_type
12265
12266        return None
12267
12268    def find_common_type(self, env, op, operand1, common_type=None):
12269        operand2 = self.operand2
12270        type1 = operand1.type
12271        type2 = operand2.type
12272
12273        new_common_type = None
12274
12275        # catch general errors
12276        if (type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or
12277                type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type))):
12278            error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
12279            new_common_type = error_type
12280
12281        # try to use numeric comparisons where possible
12282        elif type1.is_complex or type2.is_complex:
12283            if (op not in ('==', '!=')
12284                    and (type1.is_complex or type1.is_numeric)
12285                    and (type2.is_complex or type2.is_numeric)):
12286                error(self.pos, "complex types are unordered")
12287                new_common_type = error_type
12288            elif type1.is_pyobject:
12289                new_common_type = Builtin.complex_type if type1.subtype_of(Builtin.complex_type) else py_object_type
12290            elif type2.is_pyobject:
12291                new_common_type = Builtin.complex_type if type2.subtype_of(Builtin.complex_type) else py_object_type
12292            else:
12293                new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
12294        elif type1.is_numeric and type2.is_numeric:
12295            new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
12296        elif common_type is None or not common_type.is_pyobject:
12297            new_common_type = self.find_common_int_type(env, op, operand1, operand2)
12298
12299        if new_common_type is None:
12300            # fall back to generic type compatibility tests
12301            if type1.is_ctuple or type2.is_ctuple:
12302                new_common_type = py_object_type
12303            elif type1 == type2:
12304                new_common_type = type1
12305            elif type1.is_pyobject or type2.is_pyobject:
12306                if type2.is_numeric or type2.is_string:
12307                    if operand2.check_for_coercion_error(type1, env):
12308                        new_common_type = error_type
12309                    else:
12310                        new_common_type = py_object_type
12311                elif type1.is_numeric or type1.is_string:
12312                    if operand1.check_for_coercion_error(type2, env):
12313                        new_common_type = error_type
12314                    else:
12315                        new_common_type = py_object_type
12316                elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
12317                    new_common_type = py_object_type
12318                else:
12319                    # one Python type and one non-Python type, not assignable
12320                    self.invalid_types_error(operand1, op, operand2)
12321                    new_common_type = error_type
12322            elif type1.assignable_from(type2):
12323                new_common_type = type1
12324            elif type2.assignable_from(type1):
12325                new_common_type = type2
12326            else:
12327                # C types that we couldn't handle up to here are an error
12328                self.invalid_types_error(operand1, op, operand2)
12329                new_common_type = error_type
12330
12331        if new_common_type.is_string and (isinstance(operand1, BytesNode) or
12332                                          isinstance(operand2, BytesNode)):
12333            # special case when comparing char* to bytes literal: must
12334            # compare string values!
12335            new_common_type = bytes_type
12336
12337        # recursively merge types
12338        if common_type is None or new_common_type.is_error:
12339            common_type = new_common_type
12340        else:
12341            # we could do a lot better by splitting the comparison
12342            # into a non-Python part and a Python part, but this is
12343            # safer for now
12344            common_type = PyrexTypes.spanning_type(common_type, new_common_type)
12345
12346        if self.cascade:
12347            common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
12348
12349        return common_type
12350
12351    def invalid_types_error(self, operand1, op, operand2):
12352        error(self.pos, "Invalid types for '%s' (%s, %s)" %
12353              (op, operand1.type, operand2.type))
12354
12355    def is_python_comparison(self):
12356        return (not self.is_ptr_contains()
12357            and not self.is_c_string_contains()
12358            and (self.has_python_operands()
12359                 or (self.cascade and self.cascade.is_python_comparison())
12360                 or self.operator in ('in', 'not_in')))
12361
12362    def coerce_operands_to(self, dst_type, env):
12363        operand2 = self.operand2
12364        if operand2.type != dst_type:
12365            self.operand2 = operand2.coerce_to(dst_type, env)
12366        if self.cascade:
12367            self.cascade.coerce_operands_to(dst_type, env)
12368
12369    def is_python_result(self):
12370        return ((self.has_python_operands() and
12371                 self.special_bool_cmp_function is None and
12372                 self.operator not in ('is', 'is_not', 'in', 'not_in') and
12373                 not self.is_c_string_contains() and
12374                 not self.is_ptr_contains())
12375            or (self.cascade and self.cascade.is_python_result()))
12376
12377    def is_c_string_contains(self):
12378        return self.operator in ('in', 'not_in') and \
12379               ((self.operand1.type.is_int
12380                 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
12381                (self.operand1.type.is_unicode_char
12382                 and self.operand2.type is unicode_type))
12383
12384    def is_ptr_contains(self):
12385        if self.operator in ('in', 'not_in'):
12386            container_type = self.operand2.type
12387            return (container_type.is_ptr or container_type.is_array) \
12388                and not container_type.is_string
12389
12390    def find_special_bool_compare_function(self, env, operand1, result_is_bool=False):
12391        # note: currently operand1 must get coerced to a Python object if we succeed here!
12392        if self.operator in ('==', '!='):
12393            type1, type2 = operand1.type, self.operand2.type
12394            if result_is_bool or (type1.is_builtin_type and type2.is_builtin_type):
12395                if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
12396                    self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
12397                    self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
12398                    return True
12399                elif type1 is Builtin.bytes_type or type2 is Builtin.bytes_type:
12400                    self.special_bool_cmp_utility_code = UtilityCode.load_cached("BytesEquals", "StringTools.c")
12401                    self.special_bool_cmp_function = "__Pyx_PyBytes_Equals"
12402                    return True
12403                elif type1 is Builtin.basestring_type or type2 is Builtin.basestring_type:
12404                    self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
12405                    self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
12406                    return True
12407                elif type1 is Builtin.str_type or type2 is Builtin.str_type:
12408                    self.special_bool_cmp_utility_code = UtilityCode.load_cached("StrEquals", "StringTools.c")
12409                    self.special_bool_cmp_function = "__Pyx_PyString_Equals"
12410                    return True
12411        elif self.operator in ('in', 'not_in'):
12412            if self.operand2.type is Builtin.dict_type:
12413                self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
12414                self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyDictContains", "ObjectHandling.c")
12415                self.special_bool_cmp_function = "__Pyx_PyDict_ContainsTF"
12416                return True
12417            elif self.operand2.type is Builtin.set_type:
12418                self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
12419                self.special_bool_cmp_utility_code = UtilityCode.load_cached("PySetContains", "ObjectHandling.c")
12420                self.special_bool_cmp_function = "__Pyx_PySet_ContainsTF"
12421                return True
12422            elif self.operand2.type is Builtin.unicode_type:
12423                self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
12424                self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyUnicodeContains", "StringTools.c")
12425                self.special_bool_cmp_function = "__Pyx_PyUnicode_ContainsTF"
12426                return True
12427            else:
12428                if not self.operand2.type.is_pyobject:
12429                    self.operand2 = self.operand2.coerce_to_pyobject(env)
12430                self.special_bool_cmp_utility_code = UtilityCode.load_cached("PySequenceContains", "ObjectHandling.c")
12431                self.special_bool_cmp_function = "__Pyx_PySequence_ContainsTF"
12432                return True
12433        return False
12434
12435    def generate_operation_code(self, code, result_code,
12436            operand1, op , operand2):
12437        if self.type.is_pyobject:
12438            error_clause = code.error_goto_if_null
12439            got_ref = "__Pyx_XGOTREF(%s); " % result_code
12440            if self.special_bool_cmp_function:
12441                code.globalstate.use_utility_code(
12442                    UtilityCode.load_cached("PyBoolOrNullFromLong", "ObjectHandling.c"))
12443                coerce_result = "__Pyx_PyBoolOrNull_FromLong"
12444            else:
12445                coerce_result = "__Pyx_PyBool_FromLong"
12446        else:
12447            error_clause = code.error_goto_if_neg
12448            got_ref = ""
12449            coerce_result = ""
12450
12451        if self.special_bool_cmp_function:
12452            if operand1.type.is_pyobject:
12453                result1 = operand1.py_result()
12454            else:
12455                result1 = operand1.result()
12456            if operand2.type.is_pyobject:
12457                result2 = operand2.py_result()
12458            else:
12459                result2 = operand2.result()
12460            if self.special_bool_cmp_utility_code:
12461                code.globalstate.use_utility_code(self.special_bool_cmp_utility_code)
12462            code.putln(
12463                "%s = %s(%s(%s, %s, %s)); %s%s" % (
12464                    result_code,
12465                    coerce_result,
12466                    self.special_bool_cmp_function,
12467                    result1, result2, richcmp_constants[op],
12468                    got_ref,
12469                    error_clause(result_code, self.pos)))
12470
12471        elif operand1.type.is_pyobject and op not in ('is', 'is_not'):
12472            assert op not in ('in', 'not_in'), op
12473            code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s%s" % (
12474                    result_code,
12475                    operand1.py_result(),
12476                    operand2.py_result(),
12477                    richcmp_constants[op],
12478                    got_ref,
12479                    error_clause(result_code, self.pos)))
12480
12481        elif operand1.type.is_complex:
12482            code.putln("%s = %s(%s%s(%s, %s));" % (
12483                result_code,
12484                coerce_result,
12485                op == "!=" and "!" or "",
12486                operand1.type.unary_op('eq'),
12487                operand1.result(),
12488                operand2.result()))
12489
12490        else:
12491            type1 = operand1.type
12492            type2 = operand2.type
12493            if (type1.is_extension_type or type2.is_extension_type) \
12494                    and not type1.same_as(type2):
12495                common_type = py_object_type
12496            elif type1.is_numeric:
12497                common_type = PyrexTypes.widest_numeric_type(type1, type2)
12498            else:
12499                common_type = type1
12500            code1 = operand1.result_as(common_type)
12501            code2 = operand2.result_as(common_type)
12502            statement = "%s = %s(%s %s %s);" % (
12503                result_code,
12504                coerce_result,
12505                code1,
12506                self.c_operator(op),
12507                code2)
12508            if self.is_cpp_comparison() and self.exception_check == '+':
12509                translate_cpp_exception(
12510                    code,
12511                    self.pos,
12512                    statement,
12513                    result_code if self.type.is_pyobject else None,
12514                    self.exception_value,
12515                    self.in_nogil_context)
12516            else:
12517                code.putln(statement)
12518
12519    def c_operator(self, op):
12520        if op == 'is':
12521            return "=="
12522        elif op == 'is_not':
12523            return "!="
12524        else:
12525            return op
12526
12527class PrimaryCmpNode(ExprNode, CmpNode):
12528    #  Non-cascaded comparison or first comparison of
12529    #  a cascaded sequence.
12530    #
12531    #  operator      string
12532    #  operand1      ExprNode
12533    #  operand2      ExprNode
12534    #  cascade       CascadedCmpNode
12535
12536    #  We don't use the subexprs mechanism, because
12537    #  things here are too complicated for it to handle.
12538    #  Instead, we override all the framework methods
12539    #  which use it.
12540
12541    child_attrs = ['operand1', 'operand2', 'coerced_operand2', 'cascade']
12542
12543    cascade = None
12544    coerced_operand2 = None
12545    is_memslice_nonecheck = False
12546
12547    def infer_type(self, env):
12548        type1 = self.operand1.infer_type(env)
12549        type2 = self.operand2.infer_type(env)
12550
12551        if is_pythran_expr(type1) or is_pythran_expr(type2):
12552            if is_pythran_supported_type(type1) and is_pythran_supported_type(type2):
12553                return PythranExpr(pythran_binop_type(self.operator, type1, type2))
12554
12555        # TODO: implement this for other types.
12556        return py_object_type
12557
12558    def type_dependencies(self, env):
12559        return ()
12560
12561    def calculate_constant_result(self):
12562        assert not self.cascade
12563        self.calculate_cascaded_constant_result(self.operand1.constant_result)
12564
12565    def compile_time_value(self, denv):
12566        operand1 = self.operand1.compile_time_value(denv)
12567        return self.cascaded_compile_time_value(operand1, denv)
12568
12569    def analyse_types(self, env):
12570        self.operand1 = self.operand1.analyse_types(env)
12571        self.operand2 = self.operand2.analyse_types(env)
12572        if self.is_cpp_comparison():
12573            self.analyse_cpp_comparison(env)
12574            if self.cascade:
12575                error(self.pos, "Cascading comparison not yet supported for cpp types.")
12576            return self
12577
12578        type1 = self.operand1.type
12579        type2 = self.operand2.type
12580        if is_pythran_expr(type1) or is_pythran_expr(type2):
12581            if is_pythran_supported_type(type1) and is_pythran_supported_type(type2):
12582                self.type = PythranExpr(pythran_binop_type(self.operator, type1, type2))
12583                self.is_pycmp = False
12584                return self
12585
12586        if self.analyse_memoryviewslice_comparison(env):
12587            return self
12588
12589        if self.cascade:
12590            self.cascade = self.cascade.analyse_types(env)
12591
12592        if self.operator in ('in', 'not_in'):
12593            if self.is_c_string_contains():
12594                self.is_pycmp = False
12595                common_type = None
12596                if self.cascade:
12597                    error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
12598                    return self
12599                if self.operand2.type is unicode_type:
12600                    env.use_utility_code(UtilityCode.load_cached("PyUCS4InUnicode", "StringTools.c"))
12601                else:
12602                    if self.operand1.type is PyrexTypes.c_uchar_type:
12603                        self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
12604                    if self.operand2.type is not bytes_type:
12605                        self.operand2 = self.operand2.coerce_to(bytes_type, env)
12606                    env.use_utility_code(UtilityCode.load_cached("BytesContains", "StringTools.c"))
12607                self.operand2 = self.operand2.as_none_safe_node(
12608                    "argument of type 'NoneType' is not iterable")
12609            elif self.is_ptr_contains():
12610                if self.cascade:
12611                    error(self.pos, "Cascading comparison not supported for 'val in sliced pointer'.")
12612                self.type = PyrexTypes.c_bint_type
12613                # Will be transformed by IterationTransform
12614                return self
12615            elif self.find_special_bool_compare_function(env, self.operand1):
12616                if not self.operand1.type.is_pyobject:
12617                    self.operand1 = self.operand1.coerce_to_pyobject(env)
12618                common_type = None # if coercion needed, the method call above has already done it
12619                self.is_pycmp = False # result is bint
12620            else:
12621                common_type = py_object_type
12622                self.is_pycmp = True
12623        elif self.find_special_bool_compare_function(env, self.operand1):
12624            if not self.operand1.type.is_pyobject:
12625                self.operand1 = self.operand1.coerce_to_pyobject(env)
12626            common_type = None # if coercion needed, the method call above has already done it
12627            self.is_pycmp = False # result is bint
12628        else:
12629            common_type = self.find_common_type(env, self.operator, self.operand1)
12630            self.is_pycmp = common_type.is_pyobject
12631
12632        if common_type is not None and not common_type.is_error:
12633            if self.operand1.type != common_type:
12634                self.operand1 = self.operand1.coerce_to(common_type, env)
12635            self.coerce_operands_to(common_type, env)
12636
12637        if self.cascade:
12638            self.operand2 = self.operand2.coerce_to_simple(env)
12639            self.cascade.coerce_cascaded_operands_to_temp(env)
12640            operand2 = self.cascade.optimise_comparison(self.operand2, env)
12641            if operand2 is not self.operand2:
12642                self.coerced_operand2 = operand2
12643        if self.is_python_result():
12644            self.type = PyrexTypes.py_object_type
12645        else:
12646            self.type = PyrexTypes.c_bint_type
12647        cdr = self.cascade
12648        while cdr:
12649            cdr.type = self.type
12650            cdr = cdr.cascade
12651        if self.is_pycmp or self.cascade or self.special_bool_cmp_function:
12652            # 1) owned reference, 2) reused value, 3) potential function error return value
12653            self.is_temp = 1
12654        return self
12655
12656    def analyse_cpp_comparison(self, env):
12657        type1 = self.operand1.type
12658        type2 = self.operand2.type
12659        self.is_pycmp = False
12660        entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
12661        if entry is None:
12662            error(self.pos, "Invalid types for '%s' (%s, %s)" %
12663                (self.operator, type1, type2))
12664            self.type = PyrexTypes.error_type
12665            self.result_code = "<error>"
12666            return
12667        func_type = entry.type
12668        if func_type.is_ptr:
12669            func_type = func_type.base_type
12670        self.exception_check = func_type.exception_check
12671        self.exception_value = func_type.exception_value
12672        if self.exception_check == '+':
12673            self.is_temp = True
12674            if self.exception_value is None:
12675                env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
12676        if len(func_type.args) == 1:
12677            self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
12678        else:
12679            self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
12680            self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
12681        self.type = func_type.return_type
12682
12683    def analyse_memoryviewslice_comparison(self, env):
12684        have_none = self.operand1.is_none or self.operand2.is_none
12685        have_slice = (self.operand1.type.is_memoryviewslice or
12686                      self.operand2.type.is_memoryviewslice)
12687        ops = ('==', '!=', 'is', 'is_not')
12688        if have_slice and have_none and self.operator in ops:
12689            self.is_pycmp = False
12690            self.type = PyrexTypes.c_bint_type
12691            self.is_memslice_nonecheck = True
12692            return True
12693
12694        return False
12695
12696    def coerce_to_boolean(self, env):
12697        if self.is_pycmp:
12698            # coercing to bool => may allow for more efficient comparison code
12699            if self.find_special_bool_compare_function(
12700                    env, self.operand1, result_is_bool=True):
12701                self.is_pycmp = False
12702                self.type = PyrexTypes.c_bint_type
12703                self.is_temp = 1
12704                if self.cascade:
12705                    operand2 = self.cascade.optimise_comparison(
12706                        self.operand2, env, result_is_bool=True)
12707                    if operand2 is not self.operand2:
12708                        self.coerced_operand2 = operand2
12709                return self
12710        # TODO: check if we can optimise parts of the cascade here
12711        return ExprNode.coerce_to_boolean(self, env)
12712
12713    def has_python_operands(self):
12714        return (self.operand1.type.is_pyobject
12715            or self.operand2.type.is_pyobject)
12716
12717    def check_const(self):
12718        if self.cascade:
12719            self.not_const()
12720            return False
12721        else:
12722            return self.operand1.check_const() and self.operand2.check_const()
12723
12724    def calculate_result_code(self):
12725        operand1, operand2 = self.operand1, self.operand2
12726        if operand1.type.is_complex:
12727            if self.operator == "!=":
12728                negation = "!"
12729            else:
12730                negation = ""
12731            return "(%s%s(%s, %s))" % (
12732                negation,
12733                operand1.type.binary_op('=='),
12734                operand1.result(),
12735                operand2.result())
12736        elif self.is_c_string_contains():
12737            if operand2.type is unicode_type:
12738                method = "__Pyx_UnicodeContainsUCS4"
12739            else:
12740                method = "__Pyx_BytesContains"
12741            if self.operator == "not_in":
12742                negation = "!"
12743            else:
12744                negation = ""
12745            return "(%s%s(%s, %s))" % (
12746                negation,
12747                method,
12748                operand2.result(),
12749                operand1.result())
12750        else:
12751            if is_pythran_expr(self.type):
12752                result1, result2 = operand1.pythran_result(), operand2.pythran_result()
12753            else:
12754                result1, result2 = operand1.result(), operand2.result()
12755                if self.is_memslice_nonecheck:
12756                    if operand1.type.is_memoryviewslice:
12757                        result1 = "((PyObject *) %s.memview)" % result1
12758                    else:
12759                        result2 = "((PyObject *) %s.memview)" % result2
12760
12761            return "(%s %s %s)" % (
12762                result1,
12763                self.c_operator(self.operator),
12764                result2)
12765
12766    def generate_evaluation_code(self, code):
12767        self.operand1.generate_evaluation_code(code)
12768        self.operand2.generate_evaluation_code(code)
12769        if self.is_temp:
12770            self.allocate_temp_result(code)
12771            self.generate_operation_code(code, self.result(),
12772                self.operand1, self.operator, self.operand2)
12773            if self.cascade:
12774                self.cascade.generate_evaluation_code(
12775                    code, self.result(), self.coerced_operand2 or self.operand2,
12776                    needs_evaluation=self.coerced_operand2 is not None)
12777            self.operand1.generate_disposal_code(code)
12778            self.operand1.free_temps(code)
12779            self.operand2.generate_disposal_code(code)
12780            self.operand2.free_temps(code)
12781
12782    def generate_subexpr_disposal_code(self, code):
12783        #  If this is called, it is a non-cascaded cmp,
12784        #  so only need to dispose of the two main operands.
12785        self.operand1.generate_disposal_code(code)
12786        self.operand2.generate_disposal_code(code)
12787
12788    def free_subexpr_temps(self, code):
12789        #  If this is called, it is a non-cascaded cmp,
12790        #  so only need to dispose of the two main operands.
12791        self.operand1.free_temps(code)
12792        self.operand2.free_temps(code)
12793
12794    def annotate(self, code):
12795        self.operand1.annotate(code)
12796        self.operand2.annotate(code)
12797        if self.cascade:
12798            self.cascade.annotate(code)
12799
12800
12801class CascadedCmpNode(Node, CmpNode):
12802    #  A CascadedCmpNode is not a complete expression node. It
12803    #  hangs off the side of another comparison node, shares
12804    #  its left operand with that node, and shares its result
12805    #  with the PrimaryCmpNode at the head of the chain.
12806    #
12807    #  operator      string
12808    #  operand2      ExprNode
12809    #  cascade       CascadedCmpNode
12810
12811    child_attrs = ['operand2', 'coerced_operand2', 'cascade']
12812
12813    cascade = None
12814    coerced_operand2 = None
12815    constant_result = constant_value_not_set # FIXME: where to calculate this?
12816
12817    def infer_type(self, env):
12818        # TODO: Actually implement this (after merging with -unstable).
12819        return py_object_type
12820
12821    def type_dependencies(self, env):
12822        return ()
12823
12824    def has_constant_result(self):
12825        return self.constant_result is not constant_value_not_set and \
12826               self.constant_result is not not_a_constant
12827
12828    def analyse_types(self, env):
12829        self.operand2 = self.operand2.analyse_types(env)
12830        if self.cascade:
12831            self.cascade = self.cascade.analyse_types(env)
12832        return self
12833
12834    def has_python_operands(self):
12835        return self.operand2.type.is_pyobject
12836
12837    def is_cpp_comparison(self):
12838        # cascaded comparisons aren't currently implemented for c++ classes.
12839        return False
12840
12841    def optimise_comparison(self, operand1, env, result_is_bool=False):
12842        if self.find_special_bool_compare_function(env, operand1, result_is_bool):
12843            self.is_pycmp = False
12844            self.type = PyrexTypes.c_bint_type
12845            if not operand1.type.is_pyobject:
12846                operand1 = operand1.coerce_to_pyobject(env)
12847        if self.cascade:
12848            operand2 = self.cascade.optimise_comparison(self.operand2, env, result_is_bool)
12849            if operand2 is not self.operand2:
12850                self.coerced_operand2 = operand2
12851        return operand1
12852
12853    def coerce_operands_to_pyobjects(self, env):
12854        self.operand2 = self.operand2.coerce_to_pyobject(env)
12855        if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
12856            self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
12857        if self.cascade:
12858            self.cascade.coerce_operands_to_pyobjects(env)
12859
12860    def coerce_cascaded_operands_to_temp(self, env):
12861        if self.cascade:
12862            #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
12863            self.operand2 = self.operand2.coerce_to_simple(env)
12864            self.cascade.coerce_cascaded_operands_to_temp(env)
12865
12866    def generate_evaluation_code(self, code, result, operand1, needs_evaluation=False):
12867        if self.type.is_pyobject:
12868            code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
12869            code.put_decref(result, self.type)
12870        else:
12871            code.putln("if (%s) {" % result)
12872        if needs_evaluation:
12873            operand1.generate_evaluation_code(code)
12874        self.operand2.generate_evaluation_code(code)
12875        self.generate_operation_code(code, result,
12876            operand1, self.operator, self.operand2)
12877        if self.cascade:
12878            self.cascade.generate_evaluation_code(
12879                code, result, self.coerced_operand2 or self.operand2,
12880                needs_evaluation=self.coerced_operand2 is not None)
12881        if needs_evaluation:
12882            operand1.generate_disposal_code(code)
12883            operand1.free_temps(code)
12884        # Cascaded cmp result is always temp
12885        self.operand2.generate_disposal_code(code)
12886        self.operand2.free_temps(code)
12887        code.putln("}")
12888
12889    def annotate(self, code):
12890        self.operand2.annotate(code)
12891        if self.cascade:
12892            self.cascade.annotate(code)
12893
12894
12895binop_node_classes = {
12896    "or":       BoolBinopNode,
12897    "and":      BoolBinopNode,
12898    "|":        IntBinopNode,
12899    "^":        IntBinopNode,
12900    "&":        IntBinopNode,
12901    "<<":       IntBinopNode,
12902    ">>":       IntBinopNode,
12903    "+":        AddNode,
12904    "-":        SubNode,
12905    "*":        MulNode,
12906    "@":        MatMultNode,
12907    "/":        DivNode,
12908    "//":       DivNode,
12909    "%":        ModNode,
12910    "**":       PowNode,
12911}
12912
12913
12914def binop_node(pos, operator, operand1, operand2, inplace=False, **kwargs):
12915    # Construct binop node of appropriate class for
12916    # given operator.
12917    return binop_node_classes[operator](
12918        pos,
12919        operator=operator,
12920        operand1=operand1,
12921        operand2=operand2,
12922        inplace=inplace,
12923        **kwargs)
12924
12925
12926#-------------------------------------------------------------------
12927#
12928#  Coercion nodes
12929#
12930#  Coercion nodes are special in that they are created during
12931#  the analyse_types phase of parse tree processing.
12932#  Their __init__ methods consequently incorporate some aspects
12933#  of that phase.
12934#
12935#-------------------------------------------------------------------
12936
12937class CoercionNode(ExprNode):
12938    #  Abstract base class for coercion nodes.
12939    #
12940    #  arg       ExprNode       node being coerced
12941
12942    subexprs = ['arg']
12943    constant_result = not_a_constant
12944
12945    def __init__(self, arg):
12946        super(CoercionNode, self).__init__(arg.pos)
12947        self.arg = arg
12948        if debug_coercion:
12949            print("%s Coercing %s" % (self, self.arg))
12950
12951    def calculate_constant_result(self):
12952        # constant folding can break type coercion, so this is disabled
12953        pass
12954
12955    def annotate(self, code):
12956        self.arg.annotate(code)
12957        if self.arg.type != self.type:
12958            file, line, col = self.pos
12959            code.annotate((file, line, col-1), AnnotationItem(
12960                style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
12961
12962
12963class CoerceToMemViewSliceNode(CoercionNode):
12964    """
12965    Coerce an object to a memoryview slice. This holds a new reference in
12966    a managed temp.
12967    """
12968
12969    def __init__(self, arg, dst_type, env):
12970        assert dst_type.is_memoryviewslice
12971        assert not arg.type.is_memoryviewslice
12972        CoercionNode.__init__(self, arg)
12973        self.type = dst_type
12974        self.is_temp = 1
12975        self.use_managed_ref = True
12976        self.arg = arg
12977        self.type.create_from_py_utility_code(env)
12978
12979    def generate_result_code(self, code):
12980        code.putln(self.type.from_py_call_code(
12981            self.arg.py_result(),
12982            self.result(),
12983            self.pos,
12984            code
12985        ))
12986
12987
12988class CastNode(CoercionNode):
12989    #  Wrap a node in a C type cast.
12990
12991    def __init__(self, arg, new_type):
12992        CoercionNode.__init__(self, arg)
12993        self.type = new_type
12994
12995    def may_be_none(self):
12996        return self.arg.may_be_none()
12997
12998    def calculate_result_code(self):
12999        return self.arg.result_as(self.type)
13000
13001    def generate_result_code(self, code):
13002        self.arg.generate_result_code(code)
13003
13004
13005class PyTypeTestNode(CoercionNode):
13006    #  This node is used to check that a generic Python
13007    #  object is an instance of a particular extension type.
13008    #  This node borrows the result of its argument node.
13009
13010    exact_builtin_type = True
13011
13012    def __init__(self, arg, dst_type, env, notnone=False):
13013        #  The arg is know to be a Python object, and
13014        #  the dst_type is known to be an extension type.
13015        assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
13016        CoercionNode.__init__(self, arg)
13017        self.type = dst_type
13018        self.result_ctype = arg.ctype()
13019        self.notnone = notnone
13020
13021    nogil_check = Node.gil_error
13022    gil_message = "Python type test"
13023
13024    def analyse_types(self, env):
13025        return self
13026
13027    def may_be_none(self):
13028        if self.notnone:
13029            return False
13030        return self.arg.may_be_none()
13031
13032    def is_simple(self):
13033        return self.arg.is_simple()
13034
13035    def result_in_temp(self):
13036        return self.arg.result_in_temp()
13037
13038    def is_ephemeral(self):
13039        return self.arg.is_ephemeral()
13040
13041    def nonlocally_immutable(self):
13042        return self.arg.nonlocally_immutable()
13043
13044    def reanalyse(self):
13045        if self.type != self.arg.type or not self.arg.is_temp:
13046            return self
13047        if not self.type.typeobj_is_available():
13048            return self
13049        if self.arg.may_be_none() and self.notnone:
13050            return self.arg.as_none_safe_node("Cannot convert NoneType to %.200s" % self.type.name)
13051        return self.arg
13052
13053    def calculate_constant_result(self):
13054        # FIXME
13055        pass
13056
13057    def calculate_result_code(self):
13058        return self.arg.result()
13059
13060    def generate_result_code(self, code):
13061        if self.type.typeobj_is_available():
13062            if self.type.is_builtin_type:
13063                type_test = self.type.type_test_code(
13064                    self.arg.py_result(),
13065                    self.notnone, exact=self.exact_builtin_type)
13066            else:
13067                type_test = self.type.type_test_code(
13068                    self.arg.py_result(), self.notnone)
13069                code.globalstate.use_utility_code(
13070                    UtilityCode.load_cached("ExtTypeTest", "ObjectHandling.c"))
13071            code.putln("if (!(%s)) %s" % (
13072                type_test, code.error_goto(self.pos)))
13073        else:
13074            error(self.pos, "Cannot test type of extern C class "
13075                "without type object name specification")
13076
13077    def generate_post_assignment_code(self, code):
13078        self.arg.generate_post_assignment_code(code)
13079
13080    def allocate_temp_result(self, code):
13081        pass
13082
13083    def release_temp_result(self, code):
13084        pass
13085
13086    def free_temps(self, code):
13087        self.arg.free_temps(code)
13088
13089    def free_subexpr_temps(self, code):
13090        self.arg.free_subexpr_temps(code)
13091
13092
13093class NoneCheckNode(CoercionNode):
13094    # This node is used to check that a Python object is not None and
13095    # raises an appropriate exception (as specified by the creating
13096    # transform).
13097
13098    is_nonecheck = True
13099
13100    def __init__(self, arg, exception_type_cname, exception_message,
13101                 exception_format_args=()):
13102        CoercionNode.__init__(self, arg)
13103        self.type = arg.type
13104        self.result_ctype = arg.ctype()
13105        self.exception_type_cname = exception_type_cname
13106        self.exception_message = exception_message
13107        self.exception_format_args = tuple(exception_format_args or ())
13108
13109    nogil_check = None # this node only guards an operation that would fail already
13110
13111    def analyse_types(self, env):
13112        return self
13113
13114    def may_be_none(self):
13115        return False
13116
13117    def is_simple(self):
13118        return self.arg.is_simple()
13119
13120    def result_in_temp(self):
13121        return self.arg.result_in_temp()
13122
13123    def nonlocally_immutable(self):
13124        return self.arg.nonlocally_immutable()
13125
13126    def calculate_result_code(self):
13127        return self.arg.result()
13128
13129    def condition(self):
13130        if self.type.is_pyobject:
13131            return self.arg.py_result()
13132        elif self.type.is_memoryviewslice:
13133            return "((PyObject *) %s.memview)" % self.arg.result()
13134        else:
13135            raise Exception("unsupported type")
13136
13137    @classmethod
13138    def generate(cls, arg, code, exception_message,
13139                 exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
13140        node = cls(arg, exception_type_cname, exception_message, exception_format_args)
13141        node.in_nogil_context = in_nogil_context
13142        node.put_nonecheck(code)
13143
13144    @classmethod
13145    def generate_if_needed(cls, arg, code, exception_message,
13146                           exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
13147        if arg.may_be_none():
13148            cls.generate(arg, code, exception_message, exception_type_cname, exception_format_args, in_nogil_context)
13149
13150    def put_nonecheck(self, code):
13151        code.putln(
13152            "if (unlikely(%s == Py_None)) {" % self.condition())
13153
13154        if self.in_nogil_context:
13155            code.put_ensure_gil()
13156
13157        escape = StringEncoding.escape_byte_string
13158        if self.exception_format_args:
13159            code.putln('PyErr_Format(%s, "%s", %s);' % (
13160                self.exception_type_cname,
13161                StringEncoding.escape_byte_string(
13162                    self.exception_message.encode('UTF-8')),
13163                ', '.join([ '"%s"' % escape(str(arg).encode('UTF-8'))
13164                            for arg in self.exception_format_args ])))
13165        else:
13166            code.putln('PyErr_SetString(%s, "%s");' % (
13167                self.exception_type_cname,
13168                escape(self.exception_message.encode('UTF-8'))))
13169
13170        if self.in_nogil_context:
13171            code.put_release_ensured_gil()
13172
13173        code.putln(code.error_goto(self.pos))
13174        code.putln("}")
13175
13176    def generate_result_code(self, code):
13177        self.put_nonecheck(code)
13178
13179    def generate_post_assignment_code(self, code):
13180        self.arg.generate_post_assignment_code(code)
13181
13182    def free_temps(self, code):
13183        self.arg.free_temps(code)
13184
13185
13186class CoerceToPyTypeNode(CoercionNode):
13187    #  This node is used to convert a C data type
13188    #  to a Python object.
13189
13190    type = py_object_type
13191    target_type = py_object_type
13192    is_temp = 1
13193
13194    def __init__(self, arg, env, type=py_object_type):
13195        if not arg.type.create_to_py_utility_code(env):
13196            error(arg.pos, "Cannot convert '%s' to Python object" % arg.type)
13197        elif arg.type.is_complex:
13198            # special case: complex coercion is so complex that it
13199            # uses a macro ("__pyx_PyComplex_FromComplex()"), for
13200            # which the argument must be simple
13201            arg = arg.coerce_to_simple(env)
13202        CoercionNode.__init__(self, arg)
13203        if type is py_object_type:
13204            # be specific about some known types
13205            if arg.type.is_string or arg.type.is_cpp_string:
13206                self.type = default_str_type(env)
13207            elif arg.type.is_pyunicode_ptr or arg.type.is_unicode_char:
13208                self.type = unicode_type
13209            elif arg.type.is_complex:
13210                self.type = Builtin.complex_type
13211            self.target_type = self.type
13212        elif arg.type.is_string or arg.type.is_cpp_string:
13213            if (type not in (bytes_type, bytearray_type)
13214                    and not env.directives['c_string_encoding']):
13215                error(arg.pos,
13216                    "default encoding required for conversion from '%s' to '%s'" %
13217                    (arg.type, type))
13218            self.type = self.target_type = type
13219        else:
13220            # FIXME: check that the target type and the resulting type are compatible
13221            self.target_type = type
13222
13223    gil_message = "Converting to Python object"
13224
13225    def may_be_none(self):
13226        # FIXME: is this always safe?
13227        return False
13228
13229    def coerce_to_boolean(self, env):
13230        arg_type = self.arg.type
13231        if (arg_type == PyrexTypes.c_bint_type or
13232            (arg_type.is_pyobject and arg_type.name == 'bool')):
13233            return self.arg.coerce_to_temp(env)
13234        else:
13235            return CoerceToBooleanNode(self, env)
13236
13237    def coerce_to_integer(self, env):
13238        # If not already some C integer type, coerce to longint.
13239        if self.arg.type.is_int:
13240            return self.arg
13241        else:
13242            return self.arg.coerce_to(PyrexTypes.c_long_type, env)
13243
13244    def analyse_types(self, env):
13245        # The arg is always already analysed
13246        return self
13247
13248    def generate_result_code(self, code):
13249        code.putln('%s; %s' % (
13250            self.arg.type.to_py_call_code(
13251                self.arg.result(),
13252                self.result(),
13253                self.target_type),
13254            code.error_goto_if_null(self.result(), self.pos)))
13255
13256        code.put_gotref(self.py_result())
13257
13258
13259class CoerceIntToBytesNode(CoerceToPyTypeNode):
13260    #  This node is used to convert a C int type to a Python bytes
13261    #  object.
13262
13263    is_temp = 1
13264
13265    def __init__(self, arg, env):
13266        arg = arg.coerce_to_simple(env)
13267        CoercionNode.__init__(self, arg)
13268        self.type = Builtin.bytes_type
13269
13270    def generate_result_code(self, code):
13271        arg = self.arg
13272        arg_result = arg.result()
13273        if arg.type not in (PyrexTypes.c_char_type,
13274                            PyrexTypes.c_uchar_type,
13275                            PyrexTypes.c_schar_type):
13276            if arg.type.signed:
13277                code.putln("if ((%s < 0) || (%s > 255)) {" % (
13278                    arg_result, arg_result))
13279            else:
13280                code.putln("if (%s > 255) {" % arg_result)
13281            code.putln('PyErr_SetString(PyExc_OverflowError, '
13282                       '"value too large to pack into a byte"); %s' % (
13283                           code.error_goto(self.pos)))
13284            code.putln('}')
13285        temp = None
13286        if arg.type is not PyrexTypes.c_char_type:
13287            temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
13288            code.putln("%s = (char)%s;" % (temp, arg_result))
13289            arg_result = temp
13290        code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
13291            self.result(),
13292            arg_result,
13293            code.error_goto_if_null(self.result(), self.pos)))
13294        if temp is not None:
13295            code.funcstate.release_temp(temp)
13296        code.put_gotref(self.py_result())
13297
13298
13299class CoerceFromPyTypeNode(CoercionNode):
13300    #  This node is used to convert a Python object
13301    #  to a C data type.
13302
13303    def __init__(self, result_type, arg, env):
13304        CoercionNode.__init__(self, arg)
13305        self.type = result_type
13306        self.is_temp = 1
13307        if not result_type.create_from_py_utility_code(env):
13308            error(arg.pos,
13309                  "Cannot convert Python object to '%s'" % result_type)
13310        if self.type.is_string or self.type.is_pyunicode_ptr:
13311            if self.arg.is_name and self.arg.entry and self.arg.entry.is_pyglobal:
13312                warning(arg.pos,
13313                        "Obtaining '%s' from externally modifiable global Python value" % result_type,
13314                        level=1)
13315
13316    def analyse_types(self, env):
13317        # The arg is always already analysed
13318        return self
13319
13320    def is_ephemeral(self):
13321        return (self.type.is_ptr and not self.type.is_array) and self.arg.is_ephemeral()
13322
13323    def generate_result_code(self, code):
13324        from_py_function = None
13325        # for certain source types, we can do better than the generic coercion
13326        if self.type.is_string and self.arg.type is bytes_type:
13327            if self.type.from_py_function.startswith('__Pyx_PyObject_As'):
13328                from_py_function = '__Pyx_PyBytes' + self.type.from_py_function[len('__Pyx_PyObject'):]
13329                NoneCheckNode.generate_if_needed(self.arg, code, "expected bytes, NoneType found")
13330
13331        code.putln(self.type.from_py_call_code(
13332            self.arg.py_result(), self.result(), self.pos, code, from_py_function=from_py_function))
13333        if self.type.is_pyobject:
13334            code.put_gotref(self.py_result())
13335
13336    def nogil_check(self, env):
13337        error(self.pos, "Coercion from Python not allowed without the GIL")
13338
13339
13340class CoerceToBooleanNode(CoercionNode):
13341    #  This node is used when a result needs to be used
13342    #  in a boolean context.
13343
13344    type = PyrexTypes.c_bint_type
13345
13346    _special_builtins = {
13347        Builtin.list_type:       'PyList_GET_SIZE',
13348        Builtin.tuple_type:      'PyTuple_GET_SIZE',
13349        Builtin.set_type:        'PySet_GET_SIZE',
13350        Builtin.frozenset_type:  'PySet_GET_SIZE',
13351        Builtin.bytes_type:      'PyBytes_GET_SIZE',
13352        Builtin.bytearray_type:  'PyByteArray_GET_SIZE',
13353        Builtin.unicode_type:    '__Pyx_PyUnicode_IS_TRUE',
13354    }
13355
13356    def __init__(self, arg, env):
13357        CoercionNode.__init__(self, arg)
13358        if arg.type.is_pyobject:
13359            self.is_temp = 1
13360
13361    def nogil_check(self, env):
13362        if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
13363            self.gil_error()
13364
13365    gil_message = "Truth-testing Python object"
13366
13367    def check_const(self):
13368        if self.is_temp:
13369            self.not_const()
13370            return False
13371        return self.arg.check_const()
13372
13373    def calculate_result_code(self):
13374        return "(%s != 0)" % self.arg.result()
13375
13376    def generate_result_code(self, code):
13377        if not self.is_temp:
13378            return
13379        test_func = self._special_builtins.get(self.arg.type)
13380        if test_func is not None:
13381            checks = ["(%s != Py_None)" % self.arg.py_result()] if self.arg.may_be_none() else []
13382            checks.append("(%s(%s) != 0)" % (test_func, self.arg.py_result()))
13383            code.putln("%s = %s;" % (self.result(), '&&'.join(checks)))
13384        else:
13385            code.putln(
13386                "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
13387                    self.result(),
13388                    self.arg.py_result(),
13389                    code.error_goto_if_neg(self.result(), self.pos)))
13390
13391
13392class CoerceToComplexNode(CoercionNode):
13393
13394    def __init__(self, arg, dst_type, env):
13395        if arg.type.is_complex:
13396            arg = arg.coerce_to_simple(env)
13397        self.type = dst_type
13398        CoercionNode.__init__(self, arg)
13399        dst_type.create_declaration_utility_code(env)
13400
13401    def calculate_result_code(self):
13402        if self.arg.type.is_complex:
13403            real_part = "__Pyx_CREAL(%s)" % self.arg.result()
13404            imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
13405        else:
13406            real_part = self.arg.result()
13407            imag_part = "0"
13408        return "%s(%s, %s)" % (
13409                self.type.from_parts,
13410                real_part,
13411                imag_part)
13412
13413    def generate_result_code(self, code):
13414        pass
13415
13416class CoerceToTempNode(CoercionNode):
13417    #  This node is used to force the result of another node
13418    #  to be stored in a temporary. It is only used if the
13419    #  argument node's result is not already in a temporary.
13420
13421    def __init__(self, arg, env):
13422        CoercionNode.__init__(self, arg)
13423        self.type = self.arg.type.as_argument_type()
13424        self.constant_result = self.arg.constant_result
13425        self.is_temp = 1
13426        if self.type.is_pyobject:
13427            self.result_ctype = py_object_type
13428
13429    gil_message = "Creating temporary Python reference"
13430
13431    def analyse_types(self, env):
13432        # The arg is always already analysed
13433        return self
13434
13435    def coerce_to_boolean(self, env):
13436        self.arg = self.arg.coerce_to_boolean(env)
13437        if self.arg.is_simple():
13438            return self.arg
13439        self.type = self.arg.type
13440        self.result_ctype = self.type
13441        return self
13442
13443    def generate_result_code(self, code):
13444        #self.arg.generate_evaluation_code(code) # Already done
13445        # by generic generate_subexpr_evaluation_code!
13446        code.putln("%s = %s;" % (
13447            self.result(), self.arg.result_as(self.ctype())))
13448        if self.use_managed_ref:
13449            if self.type.is_pyobject:
13450                code.put_incref(self.result(), self.ctype())
13451            elif self.type.is_memoryviewslice:
13452                code.put_incref_memoryviewslice(self.result(),
13453                                                not self.in_nogil_context)
13454
13455class ProxyNode(CoercionNode):
13456    """
13457    A node that should not be replaced by transforms or other means,
13458    and hence can be useful to wrap the argument to a clone node
13459
13460    MyNode    -> ProxyNode -> ArgNode
13461    CloneNode -^
13462    """
13463
13464    nogil_check = None
13465
13466    def __init__(self, arg):
13467        super(ProxyNode, self).__init__(arg)
13468        self.constant_result = arg.constant_result
13469        self._proxy_type()
13470
13471    def analyse_types(self, env):
13472        self.arg = self.arg.analyse_expressions(env)
13473        self._proxy_type()
13474        return self
13475
13476    def infer_type(self, env):
13477        return self.arg.infer_type(env)
13478
13479    def _proxy_type(self):
13480        if hasattr(self.arg, 'type'):
13481            self.type = self.arg.type
13482            self.result_ctype = self.arg.result_ctype
13483        if hasattr(self.arg, 'entry'):
13484            self.entry = self.arg.entry
13485
13486    def generate_result_code(self, code):
13487        self.arg.generate_result_code(code)
13488
13489    def result(self):
13490        return self.arg.result()
13491
13492    def is_simple(self):
13493        return self.arg.is_simple()
13494
13495    def may_be_none(self):
13496        return self.arg.may_be_none()
13497
13498    def generate_evaluation_code(self, code):
13499        self.arg.generate_evaluation_code(code)
13500
13501    def generate_disposal_code(self, code):
13502        self.arg.generate_disposal_code(code)
13503
13504    def free_temps(self, code):
13505        self.arg.free_temps(code)
13506
13507class CloneNode(CoercionNode):
13508    #  This node is employed when the result of another node needs
13509    #  to be used multiple times. The argument node's result must
13510    #  be in a temporary. This node "borrows" the result from the
13511    #  argument node, and does not generate any evaluation or
13512    #  disposal code for it. The original owner of the argument
13513    #  node is responsible for doing those things.
13514
13515    subexprs = [] # Arg is not considered a subexpr
13516    nogil_check = None
13517
13518    def __init__(self, arg):
13519        CoercionNode.__init__(self, arg)
13520        self.constant_result = arg.constant_result
13521        if hasattr(arg, 'type'):
13522            self.type = arg.type
13523            self.result_ctype = arg.result_ctype
13524        if hasattr(arg, 'entry'):
13525            self.entry = arg.entry
13526
13527    def result(self):
13528        return self.arg.result()
13529
13530    def may_be_none(self):
13531        return self.arg.may_be_none()
13532
13533    def type_dependencies(self, env):
13534        return self.arg.type_dependencies(env)
13535
13536    def infer_type(self, env):
13537        return self.arg.infer_type(env)
13538
13539    def analyse_types(self, env):
13540        self.type = self.arg.type
13541        self.result_ctype = self.arg.result_ctype
13542        self.is_temp = 1
13543        if hasattr(self.arg, 'entry'):
13544            self.entry = self.arg.entry
13545        return self
13546
13547    def coerce_to(self, dest_type, env):
13548        if self.arg.is_literal:
13549            return self.arg.coerce_to(dest_type, env)
13550        return super(CloneNode, self).coerce_to(dest_type, env)
13551
13552    def is_simple(self):
13553        return True # result is always in a temp (or a name)
13554
13555    def generate_evaluation_code(self, code):
13556        pass
13557
13558    def generate_result_code(self, code):
13559        pass
13560
13561    def generate_disposal_code(self, code):
13562        pass
13563
13564    def free_temps(self, code):
13565        pass
13566
13567
13568class CMethodSelfCloneNode(CloneNode):
13569    # Special CloneNode for the self argument of builtin C methods
13570    # that accepts subtypes of the builtin type.  This is safe only
13571    # for 'final' subtypes, as subtypes of the declared type may
13572    # override the C method.
13573
13574    def coerce_to(self, dst_type, env):
13575        if dst_type.is_builtin_type and self.type.subtype_of(dst_type):
13576            return self
13577        return CloneNode.coerce_to(self, dst_type, env)
13578
13579
13580class ModuleRefNode(ExprNode):
13581    # Simple returns the module object
13582
13583    type = py_object_type
13584    is_temp = False
13585    subexprs = []
13586
13587    def analyse_types(self, env):
13588        return self
13589
13590    def may_be_none(self):
13591        return False
13592
13593    def calculate_result_code(self):
13594        return Naming.module_cname
13595
13596    def generate_result_code(self, code):
13597        pass
13598
13599class DocstringRefNode(ExprNode):
13600    # Extracts the docstring of the body element
13601
13602    subexprs = ['body']
13603    type = py_object_type
13604    is_temp = True
13605
13606    def __init__(self, pos, body):
13607        ExprNode.__init__(self, pos)
13608        assert body.type.is_pyobject
13609        self.body = body
13610
13611    def analyse_types(self, env):
13612        return self
13613
13614    def generate_result_code(self, code):
13615        code.putln('%s = __Pyx_GetAttr(%s, %s); %s' % (
13616            self.result(), self.body.result(),
13617            code.intern_identifier(StringEncoding.EncodedString("__doc__")),
13618            code.error_goto_if_null(self.result(), self.pos)))
13619        code.put_gotref(self.result())
13620
13621
13622
13623#------------------------------------------------------------------------------------
13624#
13625#  Runtime support code
13626#
13627#------------------------------------------------------------------------------------
13628
13629pyerr_occurred_withgil_utility_code= UtilityCode(
13630proto = """
13631static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
13632""",
13633impl = """
13634static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
13635  int err;
13636  #ifdef WITH_THREAD
13637  PyGILState_STATE _save = PyGILState_Ensure();
13638  #endif
13639  err = !!PyErr_Occurred();
13640  #ifdef WITH_THREAD
13641  PyGILState_Release(_save);
13642  #endif
13643  return err;
13644}
13645"""
13646)
13647
13648#------------------------------------------------------------------------------------
13649
13650raise_unbound_local_error_utility_code = UtilityCode(
13651proto = """
13652static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
13653""",
13654impl = """
13655static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
13656    PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
13657}
13658""")
13659
13660raise_closure_name_error_utility_code = UtilityCode(
13661proto = """
13662static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);
13663""",
13664impl = """
13665static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) {
13666    PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname);
13667}
13668""")
13669
13670# Don't inline the function, it should really never be called in production
13671raise_unbound_memoryview_utility_code_nogil = UtilityCode(
13672proto = """
13673static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname);
13674""",
13675impl = """
13676static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname) {
13677    #ifdef WITH_THREAD
13678    PyGILState_STATE gilstate = PyGILState_Ensure();
13679    #endif
13680    __Pyx_RaiseUnboundLocalError(varname);
13681    #ifdef WITH_THREAD
13682    PyGILState_Release(gilstate);
13683    #endif
13684}
13685""",
13686requires = [raise_unbound_local_error_utility_code])
13687
13688#------------------------------------------------------------------------------------
13689
13690raise_too_many_values_to_unpack = UtilityCode.load_cached("RaiseTooManyValuesToUnpack", "ObjectHandling.c")
13691raise_need_more_values_to_unpack = UtilityCode.load_cached("RaiseNeedMoreValuesToUnpack", "ObjectHandling.c")
13692tuple_unpacking_error_code = UtilityCode.load_cached("UnpackTupleError", "ObjectHandling.c")
13693