Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / cython / src / Cython / Compiler / ExprNodes.py
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 """)