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