Function call returning a reference is an lvalue.
[cython.git] / Cython / Compiler / ExprNodes.py
1 #
2 #   Pyrex - Parse tree nodes for expressions
3 #
4
5 import operator
6
7 from Errors import error, warning, warn_once, InternalError
8 from Errors import hold_errors, release_errors, held_errors, report_error
9 from Code import UtilityCode
10 import StringEncoding
11 import Naming
12 import Nodes
13 from Nodes import Node
14 import PyrexTypes
15 from PyrexTypes import py_object_type, c_long_type, typecast, error_type, unspecified_type
16 from Builtin import list_type, tuple_type, set_type, dict_type, \
17      unicode_type, str_type, bytes_type, type_type
18 import Builtin
19 import Symtab
20 import Options
21 from Annotate import AnnotationItem
22
23 from Cython.Debugging import print_call_chain
24 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
25     debug_coercion
26
27 try:
28     set
29 except NameError:
30     from sets import Set as set
31
32 class NotConstant(object): pass # just for the name
33 not_a_constant = NotConstant()
34 constant_value_not_set = object()
35
36 # error messages when coercing from key[0] to key[1]
37 find_coercion_error = {
38     # string related errors
39     (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
40     (Builtin.unicode_type, Builtin.str_type)   : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
41     (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects do not support coercion to C types.",
42     (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
43     (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
44     (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
45     (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
46     (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
47     (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
48     (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
49     }.get
50
51
52 class ExprNode(Node):
53     #  subexprs     [string]     Class var holding names of subexpr node attrs
54     #  type         PyrexType    Type of the result
55     #  result_code  string       Code fragment
56     #  result_ctype string       C type of result_code if different from type
57     #  is_temp      boolean      Result is in a temporary variable
58     #  is_sequence_constructor  
59     #               boolean      Is a list or tuple constructor expression
60     #  is_starred   boolean      Is a starred expression (e.g. '*a')
61     #  saved_subexpr_nodes
62     #               [ExprNode or [ExprNode or None] or None]
63     #                            Cached result of subexpr_nodes()
64     #  use_managed_ref boolean   use ref-counted temps/assignments/etc.
65     
66     result_ctype = None
67     type = None
68     temp_code = None
69     old_temp = None # error checker for multiple frees etc.
70     use_managed_ref = True # can be set by optimisation transforms
71
72     #  The Analyse Expressions phase for expressions is split
73     #  into two sub-phases:
74     #
75     #    Analyse Types
76     #      Determines the result type of the expression based
77     #      on the types of its sub-expressions, and inserts
78     #      coercion nodes into the expression tree where needed.
79     #      Marks nodes which will need to have temporary variables
80     #      allocated.
81     #
82     #    Allocate Temps
83     #      Allocates temporary variables where needed, and fills
84     #      in the result_code field of each node.
85     #
86     #  ExprNode provides some convenience routines which
87     #  perform both of the above phases. These should only
88     #  be called from statement nodes, and only when no
89     #  coercion nodes need to be added around the expression
90     #  being analysed. In that case, the above two phases
91     #  should be invoked separately.
92     #
93     #  Framework code in ExprNode provides much of the common
94     #  processing for the various phases. It makes use of the
95     #  'subexprs' class attribute of ExprNodes, which should
96     #  contain a list of the names of attributes which can
97     #  hold sub-nodes or sequences of sub-nodes.
98     #  
99     #  The framework makes use of a number of abstract methods. 
100     #  Their responsibilities are as follows.
101     #
102     #    Declaration Analysis phase
103     #
104     #      analyse_target_declaration
105     #        Called during the Analyse Declarations phase to analyse
106     #        the LHS of an assignment or argument of a del statement.
107     #        Nodes which cannot be the LHS of an assignment need not
108     #        implement it.
109     #
110     #    Expression Analysis phase
111     #
112     #      analyse_types
113     #        - Call analyse_types on all sub-expressions.
114     #        - Check operand types, and wrap coercion nodes around
115     #          sub-expressions where needed.
116     #        - Set the type of this node.
117     #        - If a temporary variable will be required for the
118     #          result, set the is_temp flag of this node.
119     #
120     #      analyse_target_types
121     #        Called during the Analyse Types phase to analyse
122     #        the LHS of an assignment or argument of a del 
123     #        statement. Similar responsibilities to analyse_types.
124     #
125     #      target_code
126     #        Called by the default implementation of allocate_target_temps.
127     #        Should return a C lvalue for assigning to the node. The default
128     #        implementation calls calculate_result_code.
129     #
130     #      check_const
131     #        - Check that this node and its subnodes form a
132     #          legal constant expression. If so, do nothing,
133     #          otherwise call not_const. 
134     #
135     #        The default implementation of check_const 
136     #        assumes that the expression is not constant.
137     #
138     #      check_const_addr
139     #        - Same as check_const, except check that the
140     #          expression is a C lvalue whose address is
141     #          constant. Otherwise, call addr_not_const.
142     #
143     #        The default implementation of calc_const_addr
144     #        assumes that the expression is not a constant 
145     #        lvalue.
146     #
147     #   Code Generation phase
148     #
149     #      generate_evaluation_code
150     #        - Call generate_evaluation_code for sub-expressions.
151     #        - Perform the functions of generate_result_code
152     #          (see below).
153     #        - If result is temporary, call generate_disposal_code
154     #          on all sub-expressions.
155     #
156     #        A default implementation of generate_evaluation_code
157     #        is provided which uses the following abstract methods:
158     #
159     #          generate_result_code
160     #            - Generate any C statements necessary to calculate
161     #              the result of this node from the results of its
162     #              sub-expressions.
163     #
164     #          calculate_result_code
165     #            - Should return a C code fragment evaluating to the 
166     #              result. This is only called when the result is not 
167     #              a temporary.
168     #
169     #      generate_assignment_code
170     #        Called on the LHS of an assignment.
171     #        - Call generate_evaluation_code for sub-expressions.
172     #        - Generate code to perform the assignment.
173     #        - If the assignment absorbed a reference, call
174     #          generate_post_assignment_code on the RHS,
175     #          otherwise call generate_disposal_code on it.
176     #
177     #      generate_deletion_code
178     #        Called on an argument of a del statement.
179     #        - Call generate_evaluation_code for sub-expressions.
180     #        - Generate code to perform the deletion.
181     #        - Call generate_disposal_code on all sub-expressions.
182     #
183     #
184     
185     is_sequence_constructor = 0
186     is_attribute = 0
187     
188     saved_subexpr_nodes = None
189     is_temp = 0
190     is_target = 0
191     is_starred = 0
192
193     constant_result = constant_value_not_set
194
195     try:
196         _get_child_attrs = operator.attrgetter('subexprs')
197     except AttributeError:
198         # Python 2.3
199         def _get_child_attrs(self):
200             return self.subexprs
201     child_attrs = property(fget=_get_child_attrs)
202         
203     def not_implemented(self, method_name):
204         print_call_chain(method_name, "not implemented") ###
205         raise InternalError(
206             "%s.%s not implemented" %
207                 (self.__class__.__name__, method_name))
208                 
209     def is_lvalue(self):
210         return 0
211     
212     def is_ephemeral(self):
213         #  An ephemeral node is one whose result is in
214         #  a Python temporary and we suspect there are no
215         #  other references to it. Certain operations are
216         #  disallowed on such values, since they are
217         #  likely to result in a dangling pointer.
218         return self.type.is_pyobject and self.is_temp
219
220     def subexpr_nodes(self):
221         #  Extract a list of subexpression nodes based
222         #  on the contents of the subexprs class attribute.
223         nodes = []
224         for name in self.subexprs:
225             item = getattr(self, name)
226             if item is not None:
227                 if type(item) is list:
228                     nodes.extend(item)
229                 else:
230                     nodes.append(item)
231         return nodes
232         
233     def result(self):
234         if self.is_temp:
235             return self.temp_code
236         else:
237             return self.calculate_result_code()
238     
239     def result_as(self, type = None):
240         #  Return the result code cast to the specified C type.
241         return typecast(type, self.ctype(), self.result())
242     
243     def py_result(self):
244         #  Return the result code cast to PyObject *.
245         return self.result_as(py_object_type)
246     
247     def ctype(self):
248         #  Return the native C type of the result (i.e. the
249         #  C type of the result_code expression).
250         return self.result_ctype or self.type
251
252     def get_constant_c_result_code(self):
253         # Return the constant value of this node as a result code
254         # string, or None if the node is not constant.  This method
255         # can be called when the constant result code is required
256         # before the code generation phase.
257         #
258         # The return value is a string that can represent a simple C
259         # value, a constant C name or a constant C expression.  If the
260         # node type depends on Python code, this must return None.
261         return None
262
263     def calculate_constant_result(self):
264         # Calculate the constant compile time result value of this
265         # expression and store it in ``self.constant_result``.  Does
266         # nothing by default, thus leaving ``self.constant_result``
267         # unknown.  If valid, the result can be an arbitrary Python
268         # value.
269         #
270         # This must only be called when it is assured that all
271         # sub-expressions have a valid constant_result value.  The
272         # ConstantFolding transform will do this.
273         pass
274
275     def compile_time_value(self, denv):
276         #  Return value of compile-time expression, or report error.
277         error(self.pos, "Invalid compile-time expression")
278     
279     def compile_time_value_error(self, e):
280         error(self.pos, "Error in compile-time expression: %s: %s" % (
281             e.__class__.__name__, e))
282     
283     # ------------- Declaration Analysis ----------------
284     
285     def analyse_target_declaration(self, env):
286         error(self.pos, "Cannot assign to or delete this")
287     
288     # ------------- Expression Analysis ----------------
289     
290     def analyse_const_expression(self, env):
291         #  Called during the analyse_declarations phase of a
292         #  constant expression. Analyses the expression's type,
293         #  checks whether it is a legal const expression,
294         #  and determines its value.
295         self.analyse_types(env)
296         return self.check_const()
297     
298     def analyse_expressions(self, env):
299         #  Convenience routine performing both the Type
300         #  Analysis and Temp Allocation phases for a whole 
301         #  expression.
302         self.analyse_types(env)
303     
304     def analyse_target_expression(self, env, rhs):
305         #  Convenience routine performing both the Type
306         #  Analysis and Temp Allocation phases for the LHS of
307         #  an assignment.
308         self.analyse_target_types(env)
309     
310     def analyse_boolean_expression(self, env):
311         #  Analyse expression and coerce to a boolean.
312         self.analyse_types(env)
313         bool = self.coerce_to_boolean(env)
314         return bool
315     
316     def analyse_temp_boolean_expression(self, env):
317         #  Analyse boolean expression and coerce result into
318         #  a temporary. This is used when a branch is to be
319         #  performed on the result and we won't have an
320         #  opportunity to ensure disposal code is executed
321         #  afterwards. By forcing the result into a temporary,
322         #  we ensure that all disposal has been done by the
323         #  time we get the result.
324         self.analyse_types(env)
325         bool = self.coerce_to_boolean(env)
326         temp_bool = bool.coerce_to_temp(env)
327         return temp_bool
328     
329     # --------------- Type Inference -----------------
330     
331     def type_dependencies(self, env):
332         # Returns the list of entries whose types must be determined
333         # before the type of self can be infered.
334         if hasattr(self, 'type') and self.type is not None:
335             return ()
336         return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
337     
338     def infer_type(self, env):
339         # Attempt to deduce the type of self. 
340         # Differs from analyse_types as it avoids unnecessary 
341         # analysis of subexpressions, but can assume everything
342         # in self.type_dependencies() has been resolved.
343         if hasattr(self, 'type') and self.type is not None:
344             return self.type
345         elif hasattr(self, 'entry') and self.entry is not None:
346             return self.entry.type
347         else:
348             self.not_implemented("infer_type")
349     
350     # --------------- Type Analysis ------------------
351     
352     def analyse_as_module(self, env):
353         # If this node can be interpreted as a reference to a
354         # cimported module, return its scope, else None.
355         return None
356         
357     def analyse_as_type(self, env):
358         # If this node can be interpreted as a reference to a
359         # type, return that type, else None.
360         return None
361     
362     def analyse_as_extension_type(self, env):
363         # If this node can be interpreted as a reference to an
364         # extension type, return its type, else None.
365         return None
366     
367     def analyse_types(self, env):
368         self.not_implemented("analyse_types")
369     
370     def analyse_target_types(self, env):
371         self.analyse_types(env)
372
373     def nogil_check(self, env):
374         # By default, any expression based on Python objects is
375         # prevented in nogil environments.  Subtypes must override
376         # this if they can work without the GIL.
377         if self.type.is_pyobject:
378             self.gil_error()
379
380     def gil_assignment_check(self, env):
381         if env.nogil and self.type.is_pyobject:
382             error(self.pos, "Assignment of Python object not allowed without gil")
383
384     def check_const(self):
385         self.not_const()
386         return False
387     
388     def not_const(self):
389         error(self.pos, "Not allowed in a constant expression")
390     
391     def check_const_addr(self):
392         self.addr_not_const()
393         return False
394     
395     def addr_not_const(self):
396         error(self.pos, "Address is not constant")
397
398     # ----------------- Result Allocation -----------------
399     
400     def result_in_temp(self):
401         #  Return true if result is in a temporary owned by
402         #  this node or one of its subexpressions. Overridden
403         #  by certain nodes which can share the result of
404         #  a subnode.
405         return self.is_temp
406             
407     def target_code(self):
408         #  Return code fragment for use as LHS of a C assignment.
409         return self.calculate_result_code()
410     
411     def calculate_result_code(self):
412         self.not_implemented("calculate_result_code")
413     
414 #    def release_target_temp(self, env):
415 #        #  Release temporaries used by LHS of an assignment.
416 #        self.release_subexpr_temps(env)
417
418     def allocate_temp_result(self, code):
419         if self.temp_code:
420             raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
421         type = self.type
422         if not type.is_void:
423             if type.is_pyobject:
424                 type = PyrexTypes.py_object_type
425             self.temp_code = code.funcstate.allocate_temp(
426                 type, manage_ref=self.use_managed_ref)
427         else:
428             self.temp_code = None
429
430     def release_temp_result(self, code):
431         if not self.temp_code:
432             if self.old_temp:
433                 raise RuntimeError("temp %s released multiple times in %s" % (
434                         self.old_temp, self.__class__.__name__))
435             else:
436                 raise RuntimeError("no temp, but release requested in %s" % (
437                         self.__class__.__name__))
438         code.funcstate.release_temp(self.temp_code)
439         self.old_temp = self.temp_code
440         self.temp_code = None
441
442     # ---------------- Code Generation -----------------
443     
444     def make_owned_reference(self, code):
445         #  If result is a pyobject, make sure we own
446         #  a reference to it.
447         if self.type.is_pyobject and not self.result_in_temp():
448             code.put_incref(self.result(), self.ctype())
449     
450     def generate_evaluation_code(self, code):
451         code.mark_pos(self.pos)
452         
453         #  Generate code to evaluate this node and
454         #  its sub-expressions, and dispose of any
455         #  temporary results of its sub-expressions.
456         self.generate_subexpr_evaluation_code(code)
457
458         if self.is_temp:
459             self.allocate_temp_result(code)
460
461         self.generate_result_code(code)
462         if self.is_temp:
463             # If we are temp we do not need to wait until this node is disposed
464             # before disposing children.
465             self.generate_subexpr_disposal_code(code)
466             self.free_subexpr_temps(code)
467
468     def generate_subexpr_evaluation_code(self, code):
469         for node in self.subexpr_nodes():
470             node.generate_evaluation_code(code)
471     
472     def generate_result_code(self, code):
473         self.not_implemented("generate_result_code")
474     
475     def generate_disposal_code(self, code):
476         if self.is_temp:
477             if self.type.is_pyobject:
478                 code.put_decref_clear(self.result(), self.ctype())
479         else:
480             # Already done if self.is_temp
481             self.generate_subexpr_disposal_code(code)
482
483     def generate_subexpr_disposal_code(self, code):
484         #  Generate code to dispose of temporary results
485         #  of all sub-expressions.
486         for node in self.subexpr_nodes():
487             node.generate_disposal_code(code)
488     
489     def generate_post_assignment_code(self, code):
490         if self.is_temp:
491             if self.type.is_pyobject:
492                 code.putln("%s = 0;" % self.result())
493         else:
494             self.generate_subexpr_disposal_code(code)
495
496     def generate_assignment_code(self, rhs, code):
497         #  Stub method for nodes which are not legal as
498         #  the LHS of an assignment. An error will have 
499         #  been reported earlier.
500         pass
501     
502     def generate_deletion_code(self, code):
503         #  Stub method for nodes that are not legal as
504         #  the argument of a del statement. An error
505         #  will have been reported earlier.
506         pass
507
508     def free_temps(self, code):
509         if self.is_temp:
510             if not self.type.is_void:
511                 self.release_temp_result(code)
512         else:
513             self.free_subexpr_temps(code)
514     
515     def free_subexpr_temps(self, code):
516         for sub in self.subexpr_nodes():
517             sub.free_temps(code)
518
519     # ---------------- Annotation ---------------------
520     
521     def annotate(self, code):
522         for node in self.subexpr_nodes():
523             node.annotate(code)
524     
525     # ----------------- Coercion ----------------------
526     
527     def coerce_to(self, dst_type, env):
528         #   Coerce the result so that it can be assigned to
529         #   something of type dst_type. If processing is necessary,
530         #   wraps this node in a coercion node and returns that.
531         #   Otherwise, returns this node unchanged.
532         #
533         #   This method is called during the analyse_expressions
534         #   phase of the src_node's processing.
535         #
536         #   Note that subclasses that override this (especially
537         #   ConstNodes) must not (re-)set their own .type attribute
538         #   here.  Since expression nodes may turn up in different
539         #   places in the tree (e.g. inside of CloneNodes in cascaded
540         #   assignments), this method must return a new node instance
541         #   if it changes the type.
542         #
543         src = self
544         src_type = self.type
545         src_is_py_type = src_type.is_pyobject
546         dst_is_py_type = dst_type.is_pyobject
547
548         if self.check_for_coercion_error(dst_type):
549             return self
550
551         if dst_type.is_pyobject:
552             if not src.type.is_pyobject:
553                 src = CoerceToPyTypeNode(src, env)
554             if not src.type.subtype_of(dst_type):
555                 if not isinstance(src, NoneNode):
556                     src = PyTypeTestNode(src, dst_type, env)
557         elif src.type.is_pyobject:
558             src = CoerceFromPyTypeNode(dst_type, src, env)
559         elif (dst_type.is_complex 
560               and src_type != dst_type
561               and dst_type.assignable_from(src_type)):
562             src = CoerceToComplexNode(src, dst_type, env)
563         else: # neither src nor dst are py types
564             # Added the string comparison, since for c types that
565             # is enough, but Cython gets confused when the types are
566             # in different pxi files.
567             if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
568                 self.fail_assignment(dst_type)
569         return src
570
571     def fail_assignment(self, dst_type):
572         error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
573
574     def check_for_coercion_error(self, dst_type, fail=False, default=None):
575         if fail and not default:
576             default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
577         message = find_coercion_error((self.type, dst_type), default)
578         if message is not None:
579             error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
580             return True
581         if fail:
582             self.fail_assignment(dst_type)
583             return True
584         return False
585
586     def coerce_to_pyobject(self, env):
587         return self.coerce_to(PyrexTypes.py_object_type, env)
588
589     def coerce_to_boolean(self, env):
590         #  Coerce result to something acceptable as
591         #  a boolean value.
592         type = self.type
593         if type.is_pyobject or type.is_ptr or type.is_float:
594             return CoerceToBooleanNode(self, env)
595         else:
596             if not type.is_int and not type.is_error:
597                 error(self.pos, 
598                     "Type '%s' not acceptable as a boolean" % type)
599             return self
600     
601     def coerce_to_integer(self, env):
602         # If not already some C integer type, coerce to longint.
603         if self.type.is_int:
604             return self
605         else:
606             return self.coerce_to(PyrexTypes.c_long_type, env)
607     
608     def coerce_to_temp(self, env):
609         #  Ensure that the result is in a temporary.
610         if self.result_in_temp():
611             return self
612         else:
613             return CoerceToTempNode(self, env)
614     
615     def coerce_to_simple(self, env):
616         #  Ensure that the result is simple (see is_simple).
617         if self.is_simple():
618             return self
619         else:
620             return self.coerce_to_temp(env)
621     
622     def is_simple(self):
623         #  A node is simple if its result is something that can
624         #  be referred to without performing any operations, e.g.
625         #  a constant, local var, C global var, struct member
626         #  reference, or temporary.
627         return self.result_in_temp()
628         
629     def as_cython_attribute(self):
630         return None
631
632 class AtomicExprNode(ExprNode):
633     #  Abstract base class for expression nodes which have
634     #  no sub-expressions.
635     
636     subexprs = []
637
638     # Override to optimize -- we know we have no children
639     def generate_subexpr_evaluation_code(self, code):
640         pass
641     def generate_subexpr_disposal_code(self, code):
642         pass
643
644 class PyConstNode(AtomicExprNode):
645     #  Abstract base class for constant Python values.
646     
647     is_literal = 1
648     type = py_object_type
649     
650     def is_simple(self):
651         return 1
652     
653     def analyse_types(self, env):
654         pass
655     
656     def calculate_result_code(self):
657         return self.value
658
659     def generate_result_code(self, code):
660         pass
661
662
663 class NoneNode(PyConstNode):
664     #  The constant value None
665     
666     value = "Py_None"
667
668     constant_result = None
669     
670     nogil_check = None
671
672     def compile_time_value(self, denv):
673         return None
674     
675 class EllipsisNode(PyConstNode):
676     #  '...' in a subscript list.
677     
678     value = "Py_Ellipsis"
679
680     constant_result = Ellipsis
681
682     def compile_time_value(self, denv):
683         return Ellipsis
684
685
686 class ConstNode(AtomicExprNode):
687     # Abstract base type for literal constant nodes.
688     #
689     # value     string      C code fragment
690     
691     is_literal = 1
692     nogil_check = None
693
694     def is_simple(self):
695         return 1
696     
697     def analyse_types(self, env):
698         pass # Types are held in class variables
699     
700     def check_const(self):
701         return True
702     
703     def get_constant_c_result_code(self):
704         return self.calculate_result_code()
705
706     def calculate_result_code(self):
707         return str(self.value)
708
709     def generate_result_code(self, code):
710         pass
711
712
713 class BoolNode(ConstNode):
714     type = PyrexTypes.c_bint_type
715     #  The constant value True or False
716
717     def calculate_constant_result(self):
718         self.constant_result = self.value
719
720     def compile_time_value(self, denv):
721         return self.value
722     
723     def calculate_result_code(self):
724         return str(int(self.value))
725
726
727 class NullNode(ConstNode):
728     type = PyrexTypes.c_null_ptr_type
729     value = "NULL"
730     constant_result = 0
731
732     def get_constant_c_result_code(self):
733         return self.value
734
735
736 class CharNode(ConstNode):
737     type = PyrexTypes.c_char_type
738
739     def calculate_constant_result(self):
740         self.constant_result = ord(self.value)
741     
742     def compile_time_value(self, denv):
743         return ord(self.value)
744     
745     def calculate_result_code(self):
746         return "'%s'" % StringEncoding.escape_char(self.value)
747
748
749 class IntNode(ConstNode):
750
751     # unsigned     "" or "U"
752     # longness     "" or "L" or "LL"
753
754     unsigned = ""
755     longness = ""
756     type = PyrexTypes.c_long_type
757
758     def coerce_to(self, dst_type, env):
759         if self.type is dst_type:
760             return self
761         node = IntNode(self.pos, value=self.value,
762                        unsigned=self.unsigned, longness=self.longness)
763         if dst_type.is_numeric and not dst_type.is_complex:
764             return node
765         if dst_type.is_pyobject:
766             node.type = PyrexTypes.py_object_type
767         # We still need to perform normal coerce_to processing on the
768         # result, because we might be coercing to an extension type,
769         # in which case a type test node will be needed.
770         return ConstNode.coerce_to(node, dst_type, env)
771
772     def coerce_to_boolean(self, env):
773         return IntNode(
774             self.pos, value=self.value,
775             type = PyrexTypes.c_bint_type,
776             unsigned=self.unsigned, longness=self.longness)
777
778     def generate_evaluation_code(self, code):
779         if self.type.is_pyobject:
780             # pre-allocate a Python version of the number
781             self.result_code = code.get_py_num(self.value, self.longness)
782         else:
783             self.result_code = self.get_constant_c_result_code()
784     
785     def get_constant_c_result_code(self):
786         return str(self.value) + self.unsigned + self.longness
787
788     def calculate_result_code(self):
789         return self.result_code
790
791     def calculate_constant_result(self):
792         self.constant_result = int(self.value, 0)
793
794     def compile_time_value(self, denv):
795         return int(self.value, 0)
796
797
798 class FloatNode(ConstNode):
799     type = PyrexTypes.c_double_type
800
801     def calculate_constant_result(self):
802         self.constant_result = float(self.value)
803
804     def compile_time_value(self, denv):
805         return float(self.value)
806     
807     def calculate_result_code(self):
808         strval = repr(float(self.value))
809         if strval == 'nan':
810             return "(Py_HUGE_VAL * 0)"
811         elif strval == 'inf':
812             return "Py_HUGE_VAL"
813         elif strval == '-inf':
814             return "(-Py_HUGE_VAL)"
815         else:
816             return strval
817
818
819 class BytesNode(ConstNode):
820     # A char* or bytes literal
821     #
822     # value      BytesLiteral
823
824     type = PyrexTypes.c_char_ptr_type
825
826     def compile_time_value(self, denv):
827         return self.value
828
829     def analyse_as_type(self, env):
830         type = PyrexTypes.parse_basic_type(self.value)
831         if type is not None:    
832             return type
833         from TreeFragment import TreeFragment
834         pos = (self.pos[0], self.pos[1], self.pos[2]-7)
835         declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
836         sizeof_node = declaration.root.stats[0].expr
837         sizeof_node.analyse_types(env)
838         if isinstance(sizeof_node, SizeofTypeNode):
839             return sizeof_node.arg_type
840
841     def can_coerce_to_char_literal(self):
842         return len(self.value) == 1
843
844     def coerce_to(self, dst_type, env):
845         if dst_type.is_int:
846             if not self.can_coerce_to_char_literal():
847                 error(self.pos, "Only single-character strings can be coerced into ints.")
848                 return self
849             return CharNode(self.pos, value=self.value)
850
851         node = BytesNode(self.pos, value=self.value)
852         if dst_type == PyrexTypes.c_char_ptr_type:
853             node.type = PyrexTypes.c_char_ptr_type
854             return node
855         elif dst_type == PyrexTypes.c_uchar_ptr_type:
856             node.type = PyrexTypes.c_char_ptr_type
857             return CastNode(node, PyrexTypes.c_uchar_ptr_type)
858
859         if not self.type.is_pyobject:
860             if dst_type in (py_object_type, Builtin.bytes_type):
861                 node.type = Builtin.bytes_type
862             elif dst_type.is_pyobject:
863                 self.fail_assignment(dst_type)
864                 return self
865         elif dst_type.is_pyobject and dst_type is not py_object_type:
866             self.check_for_coercion_error(dst_type, fail=True)
867             return node
868
869         # We still need to perform normal coerce_to processing on the
870         # result, because we might be coercing to an extension type,
871         # in which case a type test node will be needed.
872         return ConstNode.coerce_to(node, dst_type, env)
873
874     def as_py_string_node(self, env):
875         # Return a new BytesNode with the same value as this node
876         # but whose type is a Python type instead of a C type.
877         return BytesNode(self.pos, value = self.value, type = Builtin.bytes_type)
878
879     def generate_evaluation_code(self, code):
880         if self.type.is_pyobject:
881             self.result_code = code.get_py_string_const(self.value)
882         else:
883             self.result_code = code.get_string_const(self.value)
884
885     def get_constant_c_result_code(self):
886         return None # FIXME
887     
888     def calculate_result_code(self):
889         return self.result_code
890
891
892 class UnicodeNode(PyConstNode):
893     # A Python unicode object
894     #
895     # value    EncodedString
896
897     type = unicode_type
898
899     def coerce_to(self, dst_type, env):
900         if dst_type is self.type:
901             pass
902         elif not dst_type.is_pyobject:
903             error(self.pos, "Unicode objects do not support coercion to C types.")
904         elif dst_type is not py_object_type:
905             if not self.check_for_coercion_error(dst_type):
906                 self.fail_assignment(dst_type)
907         return self
908
909     def generate_evaluation_code(self, code):
910         self.result_code = code.get_py_string_const(self.value)
911
912     def calculate_result_code(self):
913         return self.result_code
914         
915     def compile_time_value(self, env):
916         return self.value
917
918
919 class StringNode(PyConstNode):
920     # A Python str object, i.e. a byte string in Python 2.x and a
921     # unicode string in Python 3.x
922     #
923     # value          BytesLiteral or EncodedString
924     # is_identifier  boolean
925
926     type = str_type
927     is_identifier = None
928
929     def coerce_to(self, dst_type, env):
930         if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
931 #            if dst_type is Builtin.bytes_type:
932 #                # special case: bytes = 'str literal'
933 #                return BytesNode(self.pos, value=self.value)
934             if not dst_type.is_pyobject:
935                 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
936             self.check_for_coercion_error(dst_type, fail=True)
937
938         # this will be a unicode string in Py3, so make sure we can decode it
939         if self.value.encoding:
940             encoding = self.value.encoding
941             try:
942                 self.value.decode(encoding)
943             except UnicodeDecodeError:
944                 error(self.pos, "String decoding as '%s' failed. Consider using a byte string or unicode string explicitly, or adjust the source code encoding." % encoding)
945
946         return self
947
948     def can_coerce_to_char_literal(self):
949         return not self.is_identifier and len(self.value) == 1
950
951     def generate_evaluation_code(self, code):
952         self.result_code = code.get_py_string_const(
953             self.value, identifier=self.is_identifier, is_str=True)
954
955     def get_constant_c_result_code(self):
956         return None
957
958     def calculate_result_code(self):
959         return self.result_code
960         
961     def compile_time_value(self, env):
962         return self.value
963
964
965 class IdentifierStringNode(StringNode):
966     # A special str value that represents an identifier (bytes in Py2,
967     # unicode in Py3).
968     is_identifier = True
969
970
971 class LongNode(AtomicExprNode):
972     #  Python long integer literal
973     #
974     #  value   string
975
976     type = py_object_type
977
978     def calculate_constant_result(self):
979         self.constant_result = long(self.value)
980     
981     def compile_time_value(self, denv):
982         return long(self.value)
983     
984     def analyse_types(self, env):
985         self.is_temp = 1
986
987     gil_message = "Constructing Python long int"
988
989     def generate_result_code(self, code):
990         code.putln(
991             '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
992                 self.result(),
993                 self.value,
994                 code.error_goto_if_null(self.result(), self.pos)))
995         code.put_gotref(self.py_result())
996
997
998 class ImagNode(AtomicExprNode):
999     #  Imaginary number literal
1000     #
1001     #  value   float    imaginary part
1002     
1003     type = PyrexTypes.c_double_complex_type
1004
1005     def calculate_constant_result(self):
1006         self.constant_result = complex(0.0, self.value)
1007     
1008     def compile_time_value(self, denv):
1009         return complex(0.0, self.value)
1010     
1011     def analyse_types(self, env):
1012         self.type.create_declaration_utility_code(env)
1013
1014     def coerce_to(self, dst_type, env):
1015         if self.type is dst_type:
1016             return self
1017         node = ImagNode(self.pos, value=self.value)
1018         if dst_type.is_pyobject:
1019             node.is_temp = 1
1020             node.type = PyrexTypes.py_object_type
1021         # We still need to perform normal coerce_to processing on the
1022         # result, because we might be coercing to an extension type,
1023         # in which case a type test node will be needed.
1024         return AtomicExprNode.coerce_to(node, dst_type, env)
1025
1026     gil_message = "Constructing complex number"
1027
1028     def calculate_result_code(self):
1029         if self.type.is_pyobject:
1030             return self.result()
1031         else:
1032             return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1033
1034     def generate_result_code(self, code):
1035         if self.type.is_pyobject:
1036             code.putln(
1037                 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1038                     self.result(),
1039                     float(self.value),
1040                     code.error_goto_if_null(self.result(), self.pos)))
1041             code.put_gotref(self.py_result())
1042         
1043
1044 class NewExprNode(AtomicExprNode):
1045
1046     # C++ new statement
1047     #
1048     # cppclass              node                 c++ class to create
1049     
1050     type = None
1051     
1052     def infer_type(self, env):
1053         type = self.cppclass.analyse_as_type(env)
1054         if type is None or not type.is_cpp_class:
1055             error(self.pos, "new operator can only be applied to a C++ class")
1056             self.type = error_type
1057             return
1058         self.cpp_check(env)
1059         constructor = type.scope.lookup(u'<init>')
1060         if constructor is None:
1061             return_type = PyrexTypes.CFuncType(type, [])
1062             return_type = PyrexTypes.CPtrType(return_type)
1063             type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1064             constructor = type.scope.lookup(u'<init>')
1065         self.class_type = type
1066         self.entry = constructor
1067         self.type = constructor.type
1068         return self.type
1069     
1070     def analyse_types(self, env):
1071         if self.type is None:
1072             self.infer_type(env)
1073    
1074     def generate_result_code(self, code):
1075         pass
1076    
1077     def calculate_result_code(self):
1078         return "new " + self.class_type.declaration_code("")
1079
1080
1081 class NameNode(AtomicExprNode):
1082     #  Reference to a local or global variable name.
1083     #
1084     #  name            string    Python name of the variable
1085     #  entry           Entry     Symbol table entry
1086     #  type_entry      Entry     For extension type names, the original type entry
1087     
1088     is_name = True
1089     is_cython_module = False
1090     cython_attribute = None
1091     lhs_of_first_assignment = False
1092     is_used_as_rvalue = 0
1093     entry = None
1094     type_entry = None
1095
1096     def create_analysed_rvalue(pos, env, entry):
1097         node = NameNode(pos)
1098         node.analyse_types(env, entry=entry)
1099         return node
1100         
1101     def as_cython_attribute(self):
1102         return self.cython_attribute
1103     
1104     create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1105     
1106     def type_dependencies(self, env):
1107         if self.entry is None:
1108             self.entry = env.lookup(self.name)
1109         if self.entry is not None and self.entry.type.is_unspecified:
1110             return (self.entry,)
1111         else:
1112             return ()
1113     
1114     def infer_type(self, env):
1115         if self.entry is None:
1116             self.entry = env.lookup(self.name)
1117         if self.entry is None:
1118             return py_object_type
1119         elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1120                 self.name == self.entry.type.name:
1121             # Unfortunately the type attribute of type objects
1122             # is used for the pointer to the type they represent.
1123             return type_type
1124         else:
1125             return self.entry.type
1126     
1127     def compile_time_value(self, denv):
1128         try:
1129             return denv.lookup(self.name)
1130         except KeyError:
1131             error(self.pos, "Compile-time name '%s' not defined" % self.name)
1132
1133     def get_constant_c_result_code(self):
1134         if not self.entry or self.entry.type.is_pyobject:
1135             return None
1136         return self.entry.cname
1137     
1138     def coerce_to(self, dst_type, env):
1139         #  If coercing to a generic pyobject and this is a builtin
1140         #  C function with a Python equivalent, manufacture a NameNode
1141         #  referring to the Python builtin.
1142         #print "NameNode.coerce_to:", self.name, dst_type ###
1143         if dst_type is py_object_type:
1144             entry = self.entry
1145             if entry and entry.is_cfunction:
1146                 var_entry = entry.as_variable
1147                 if var_entry:
1148                     if var_entry.is_builtin and Options.cache_builtins:
1149                         var_entry = env.declare_builtin(var_entry.name, self.pos)
1150                     node = NameNode(self.pos, name = self.name)
1151                     node.entry = var_entry
1152                     node.analyse_rvalue_entry(env)
1153                     return node
1154         return super(NameNode, self).coerce_to(dst_type, env)
1155     
1156     def analyse_as_module(self, env):
1157         # Try to interpret this as a reference to a cimported module.
1158         # Returns the module scope, or None.
1159         entry = self.entry
1160         if not entry:
1161             entry = env.lookup(self.name)
1162         if entry and entry.as_module:
1163             return entry.as_module
1164         return None
1165         
1166     def analyse_as_type(self, env):
1167         if self.cython_attribute:
1168             type = PyrexTypes.parse_basic_type(self.cython_attribute)
1169         else:
1170             type = PyrexTypes.parse_basic_type(self.name)
1171         if type:
1172             return type
1173         entry = self.entry
1174         if not entry:
1175             entry = env.lookup(self.name)
1176         if entry and entry.is_type:
1177             return entry.type
1178         else:
1179             return None
1180     
1181     def analyse_as_extension_type(self, env):
1182         # Try to interpret this as a reference to an extension type.
1183         # Returns the extension type, or None.
1184         entry = self.entry
1185         if not entry:
1186             entry = env.lookup(self.name)
1187         if entry and entry.is_type and entry.type.is_extension_type:
1188             return entry.type
1189         else:
1190             return None
1191     
1192     def analyse_target_declaration(self, env):
1193         if not self.entry:
1194             self.entry = env.lookup_here(self.name)
1195         if not self.entry:
1196             if env.directives['warn.undeclared']:
1197                 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1198             if env.directives['infer_types'] != False:
1199                 type = unspecified_type
1200             else:
1201                 type = py_object_type
1202             self.entry = env.declare_var(self.name, type, self.pos)
1203         env.control_flow.set_state(self.pos, (self.name, 'initalized'), True)
1204         env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1205         if self.entry.is_declared_generic:
1206             self.result_ctype = py_object_type
1207     
1208     def analyse_types(self, env):
1209         if self.entry is None:
1210             self.entry = env.lookup(self.name)
1211         if not self.entry:
1212             self.entry = env.declare_builtin(self.name, self.pos)
1213         if not self.entry:
1214             self.type = PyrexTypes.error_type
1215             return
1216         entry = self.entry
1217         if entry:
1218             entry.used = 1
1219             if entry.type.is_buffer:
1220                 import Buffer
1221                 Buffer.used_buffer_aux_vars(entry)
1222             if entry.utility_code:
1223                 env.use_utility_code(entry.utility_code)
1224         self.analyse_rvalue_entry(env)
1225         
1226     def analyse_target_types(self, env):
1227         self.analyse_entry(env)
1228         if not self.is_lvalue():
1229             error(self.pos, "Assignment to non-lvalue '%s'"
1230                 % self.name)
1231             self.type = PyrexTypes.error_type
1232         self.entry.used = 1
1233         if self.entry.type.is_buffer:
1234             import Buffer
1235             Buffer.used_buffer_aux_vars(self.entry)
1236                 
1237     def analyse_rvalue_entry(self, env):
1238         #print "NameNode.analyse_rvalue_entry:", self.name ###
1239         #print "Entry:", self.entry.__dict__ ###
1240         self.analyse_entry(env)
1241         entry = self.entry
1242         if entry.is_declared_generic:
1243             self.result_ctype = py_object_type
1244         if entry.is_pyglobal or entry.is_builtin:
1245             if Options.cache_builtins and entry.is_builtin:
1246                 self.is_temp = 0
1247             else:
1248                 self.is_temp = 1
1249                 env.use_utility_code(get_name_interned_utility_code)
1250             self.is_used_as_rvalue = 1
1251
1252     def nogil_check(self, env):
1253         if self.is_used_as_rvalue:
1254             entry = self.entry
1255             if entry.is_builtin:
1256                 # if not Options.cache_builtins: # cached builtins are ok
1257                 self.gil_error()
1258             elif entry.is_pyglobal:
1259                 self.gil_error()
1260
1261     gil_message = "Accessing Python global or builtin"
1262
1263     def analyse_entry(self, env):
1264         #print "NameNode.analyse_entry:", self.name ###
1265         self.check_identifier_kind()
1266         entry = self.entry
1267         type = entry.type
1268         self.type = type
1269
1270     def check_identifier_kind(self):
1271         # Check that this is an appropriate kind of name for use in an
1272         # expression.  Also finds the variable entry associated with
1273         # an extension type.
1274         entry = self.entry
1275         if entry.is_type and entry.type.is_extension_type:
1276             self.type_entry = entry
1277         if not (entry.is_const or entry.is_variable 
1278             or entry.is_builtin or entry.is_cfunction
1279             or entry.is_cpp_class):
1280                 if self.entry.as_variable:
1281                     self.entry = self.entry.as_variable
1282                 else:
1283                     error(self.pos, 
1284                           "'%s' is not a constant, variable or function identifier" % self.name)
1285
1286     def is_simple(self):
1287         #  If it's not a C variable, it'll be in a temp.
1288         return 1
1289     
1290     def calculate_target_results(self, env):
1291         pass
1292     
1293     def check_const(self):
1294         entry = self.entry
1295         if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1296             self.not_const()
1297             return False
1298         return True
1299     
1300     def check_const_addr(self):
1301         entry = self.entry
1302         if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1303             self.addr_not_const()
1304             return False
1305         return True
1306
1307     def is_lvalue(self):
1308         return self.entry.is_variable and \
1309             not self.entry.type.is_array and \
1310             not self.entry.is_readonly
1311     
1312     def is_ephemeral(self):
1313         #  Name nodes are never ephemeral, even if the
1314         #  result is in a temporary.
1315         return 0
1316     
1317     def calculate_result_code(self):
1318         entry = self.entry
1319         if not entry:
1320             return "<error>" # There was an error earlier
1321         return entry.cname
1322     
1323     def generate_result_code(self, code):
1324         assert hasattr(self, 'entry')
1325         entry = self.entry
1326         if entry is None:
1327             return # There was an error earlier
1328         if entry.is_builtin and Options.cache_builtins:
1329             return # Lookup already cached
1330         elif entry.is_pyglobal or entry.is_builtin:
1331             assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1332             interned_cname = code.intern_identifier(self.entry.name)
1333             if entry.is_builtin:
1334                 namespace = Naming.builtins_cname
1335             else: # entry.is_pyglobal
1336                 namespace = entry.scope.namespace_cname
1337             code.globalstate.use_utility_code(get_name_interned_utility_code)
1338             code.putln(
1339                 '%s = __Pyx_GetName(%s, %s); %s' % (
1340                 self.result(),
1341                 namespace, 
1342                 interned_cname,
1343                 code.error_goto_if_null(self.result(), self.pos)))
1344             code.put_gotref(self.py_result())
1345             
1346         elif entry.is_local and False:
1347             # control flow not good enough yet
1348             assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
1349             if assigned is False:
1350                 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1351             elif not Options.init_local_none and assigned is None:
1352                 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1353                            (entry.cname, entry.name, code.error_goto(self.pos)))
1354                 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initalized'), True)
1355
1356     def generate_assignment_code(self, rhs, code):
1357         #print "NameNode.generate_assignment_code:", self.name ###
1358         entry = self.entry
1359         if entry is None:
1360             return # There was an error earlier
1361
1362         if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1363             and not self.lhs_of_first_assignment):
1364             error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1365         
1366         # is_pyglobal seems to be True for module level-globals only.
1367         # We use this to access class->tp_dict if necessary.
1368         if entry.is_pyglobal:
1369             assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1370             interned_cname = code.intern_identifier(self.entry.name)
1371             namespace = self.entry.scope.namespace_cname
1372             if entry.is_member:
1373                 # if the entry is a member we have to cheat: SetAttr does not work
1374                 # on types, so we create a descriptor which is then added to tp_dict
1375                 code.put_error_if_neg(self.pos,
1376                     'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1377                         namespace,
1378                         interned_cname,
1379                         rhs.py_result()))
1380                 rhs.generate_disposal_code(code)
1381                 rhs.free_temps(code)
1382                 # in Py2.6+, we need to invalidate the method cache
1383                 code.putln("PyType_Modified(%s);" %
1384                            entry.scope.parent_type.typeptr_cname)
1385             else: 
1386                 code.put_error_if_neg(self.pos,
1387                     'PyObject_SetAttr(%s, %s, %s)' % (
1388                         namespace,
1389                         interned_cname,
1390                         rhs.py_result()))
1391                 if debug_disposal_code:
1392                     print("NameNode.generate_assignment_code:")
1393                     print("...generating disposal code for %s" % rhs)
1394                 rhs.generate_disposal_code(code)
1395                 rhs.free_temps(code)
1396         else:
1397             if self.type.is_buffer:
1398                 # Generate code for doing the buffer release/acquisition.
1399                 # This might raise an exception in which case the assignment (done
1400                 # below) will not happen.
1401                 #
1402                 # The reason this is not in a typetest-like node is because the
1403                 # variables that the acquired buffer info is stored to is allocated
1404                 # per entry and coupled with it.
1405                 self.generate_acquire_buffer(rhs, code)
1406
1407             if self.type.is_pyobject:
1408                 #print "NameNode.generate_assignment_code: to", self.name ###
1409                 #print "...from", rhs ###
1410                 #print "...LHS type", self.type, "ctype", self.ctype() ###
1411                 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1412                 if self.use_managed_ref:
1413                     rhs.make_owned_reference(code)
1414                     if entry.is_cglobal:
1415                         code.put_gotref(self.py_result())
1416                 if self.use_managed_ref and not self.lhs_of_first_assignment:
1417                     if entry.is_local and not Options.init_local_none:
1418                         initalized = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
1419                         if initalized is True:
1420                             code.put_decref(self.result(), self.ctype())
1421                         elif initalized is None:
1422                             code.put_xdecref(self.result(), self.ctype())
1423                     else:
1424                         code.put_decref(self.result(), self.ctype())
1425                 if self.use_managed_ref:
1426                     if entry.is_cglobal:
1427                         code.put_giveref(rhs.py_result())
1428             code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
1429             if debug_disposal_code:
1430                 print("NameNode.generate_assignment_code:")
1431                 print("...generating post-assignment code for %s" % rhs)
1432             rhs.generate_post_assignment_code(code)
1433             rhs.free_temps(code)
1434
1435     def generate_acquire_buffer(self, rhs, code):
1436         # rhstmp is only used in case the rhs is a complicated expression leading to
1437         # the object, to avoid repeating the same C expression for every reference
1438         # to the rhs. It does NOT hold a reference.
1439         pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1440         if pretty_rhs:
1441             rhstmp = rhs.result_as(self.ctype())
1442         else:
1443             rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1444             code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1445
1446         buffer_aux = self.entry.buffer_aux
1447         bufstruct = buffer_aux.buffer_info_var.cname
1448         import Buffer
1449         Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1450                                     is_initialized=not self.lhs_of_first_assignment,
1451                                     pos=self.pos, code=code)
1452         
1453         if not pretty_rhs:
1454             code.putln("%s = 0;" % rhstmp)
1455             code.funcstate.release_temp(rhstmp)
1456     
1457     def generate_deletion_code(self, code):
1458         if self.entry is None:
1459             return # There was an error earlier
1460         if not self.entry.is_pyglobal:
1461             error(self.pos, "Deletion of local or C global name not supported")
1462             return
1463         code.put_error_if_neg(self.pos, 
1464             '__Pyx_DelAttrString(%s, "%s")' % (
1465                 Naming.module_cname,
1466                 self.entry.name))
1467                 
1468     def annotate(self, code):
1469         if hasattr(self, 'is_called') and self.is_called:
1470             pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1471             if self.type.is_pyobject:
1472                 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1473             else:
1474                 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1475             
1476 class BackquoteNode(ExprNode):
1477     #  `expr`
1478     #
1479     #  arg    ExprNode
1480     
1481     type = py_object_type
1482     
1483     subexprs = ['arg']
1484     
1485     def analyse_types(self, env):
1486         self.arg.analyse_types(env)
1487         self.arg = self.arg.coerce_to_pyobject(env)
1488         self.is_temp = 1
1489
1490     gil_message = "Backquote expression"
1491
1492     def calculate_constant_result(self):
1493         self.constant_result = repr(self.arg.constant_result)
1494
1495     def generate_result_code(self, code):
1496         code.putln(
1497             "%s = PyObject_Repr(%s); %s" % (
1498                 self.result(),
1499                 self.arg.py_result(),
1500                 code.error_goto_if_null(self.result(), self.pos)))
1501         code.put_gotref(self.py_result())
1502         
1503
1504
1505 class ImportNode(ExprNode):
1506     #  Used as part of import statement implementation.
1507     #  Implements result = 
1508     #    __import__(module_name, globals(), None, name_list)
1509     #
1510     #  module_name   StringNode            dotted name of module
1511     #  name_list     ListNode or None      list of names to be imported
1512     
1513     type = py_object_type
1514     
1515     subexprs = ['module_name', 'name_list']
1516     
1517     def analyse_types(self, env):
1518         self.module_name.analyse_types(env)
1519         self.module_name = self.module_name.coerce_to_pyobject(env)
1520         if self.name_list:
1521             self.name_list.analyse_types(env)
1522             self.name_list.coerce_to_pyobject(env)
1523         self.is_temp = 1
1524         env.use_utility_code(import_utility_code)
1525
1526     gil_message = "Python import"
1527
1528     def generate_result_code(self, code):
1529         if self.name_list:
1530             name_list_code = self.name_list.py_result()
1531         else:
1532             name_list_code = "0"
1533         code.putln(
1534             "%s = __Pyx_Import(%s, %s); %s" % (
1535                 self.result(),
1536                 self.module_name.py_result(),
1537                 name_list_code,
1538                 code.error_goto_if_null(self.result(), self.pos)))
1539         code.put_gotref(self.py_result())
1540
1541
1542 class IteratorNode(ExprNode):
1543     #  Used as part of for statement implementation.
1544     #
1545     #  allocate_counter_temp/release_counter_temp needs to be called
1546     #  by parent (ForInStatNode)
1547     #
1548     #  Implements result = iter(sequence)
1549     #
1550     #  sequence   ExprNode
1551     
1552     type = py_object_type
1553     
1554     subexprs = ['sequence']
1555     
1556     def analyse_types(self, env):
1557         self.sequence.analyse_types(env)
1558         if isinstance(self.sequence, SliceIndexNode) and \
1559                (self.sequence.base.type.is_array or self.sequence.base.type.is_ptr) \
1560                or self.sequence.type.is_array and self.sequence.type.size is not None:
1561             # C array iteration will be transformed later on
1562             pass
1563         else:
1564             self.sequence = self.sequence.coerce_to_pyobject(env)
1565         self.is_temp = 1
1566
1567     gil_message = "Iterating over Python object"
1568
1569     def allocate_counter_temp(self, code):
1570         self.counter_cname = code.funcstate.allocate_temp(
1571             PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1572
1573     def release_counter_temp(self, code):
1574         code.funcstate.release_temp(self.counter_cname)
1575
1576     def generate_result_code(self, code):
1577         is_builtin_sequence = self.sequence.type is list_type or \
1578                               self.sequence.type is tuple_type
1579         may_be_a_sequence = is_builtin_sequence or not self.sequence.type.is_builtin_type
1580         if is_builtin_sequence:
1581             code.putln(
1582                 "if (likely(%s != Py_None)) {" % self.sequence.py_result())
1583         elif may_be_a_sequence:
1584             code.putln(
1585                 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1586                     self.sequence.py_result(),
1587                     self.sequence.py_result()))
1588         if may_be_a_sequence:
1589             code.putln(
1590                 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1591                     self.counter_cname,
1592                     self.result(),
1593                     self.sequence.py_result(),
1594                     self.result()))
1595             code.putln("} else {")
1596         if is_builtin_sequence:
1597             code.putln(
1598                 'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
1599                 code.error_goto(self.pos))
1600         else:
1601             code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1602                     self.counter_cname,
1603                     self.result(),
1604                     self.sequence.py_result(),
1605                     code.error_goto_if_null(self.result(), self.pos)))
1606             code.put_gotref(self.py_result())
1607         if may_be_a_sequence:
1608             code.putln("}")
1609
1610
1611 class NextNode(AtomicExprNode):
1612     #  Used as part of for statement implementation.
1613     #  Implements result = iterator.next()
1614     #  Created during analyse_types phase.
1615     #  The iterator is not owned by this node.
1616     #
1617     #  iterator   ExprNode
1618     
1619     type = py_object_type
1620     
1621     def __init__(self, iterator, env):
1622         self.pos = iterator.pos
1623         self.iterator = iterator
1624         self.is_temp = 1
1625     
1626     def generate_result_code(self, code):
1627         sequence_type = self.iterator.sequence.type
1628         if sequence_type is list_type:
1629             type_checks = [(list_type, "List")]
1630         elif sequence_type is tuple_type:
1631             type_checks = [(tuple_type, "Tuple")]
1632         elif not sequence_type.is_builtin_type:
1633             type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1634         else:
1635             type_checks = []
1636
1637         for py_type, prefix in type_checks:
1638             if len(type_checks) > 1:
1639                 code.putln(
1640                     "if (likely(Py%s_CheckExact(%s))) {" % (
1641                         prefix, self.iterator.py_result()))
1642             code.putln(
1643                 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1644                     self.iterator.counter_cname,
1645                     prefix,
1646                     self.iterator.py_result()))
1647             code.putln(
1648                 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1649                     self.result(),
1650                     prefix,
1651                     self.iterator.py_result(),
1652                     self.iterator.counter_cname,
1653                     self.result(),
1654                     self.iterator.counter_cname))
1655             if len(type_checks) > 1:
1656                 code.put("} else ")
1657         if len(type_checks) == 1:
1658             return
1659         code.putln("{")
1660         code.putln(
1661             "%s = PyIter_Next(%s);" % (
1662                 self.result(),
1663                 self.iterator.py_result()))
1664         code.putln(
1665             "if (!%s) {" %
1666                 self.result())
1667         code.putln(code.error_goto_if_PyErr(self.pos))
1668         code.putln("break;")
1669         code.putln("}")
1670         code.put_gotref(self.py_result())
1671         code.putln("}")
1672
1673
1674 class ExcValueNode(AtomicExprNode):
1675     #  Node created during analyse_types phase
1676     #  of an ExceptClauseNode to fetch the current
1677     #  exception value.
1678     
1679     type = py_object_type
1680     
1681     def __init__(self, pos, env):
1682         ExprNode.__init__(self, pos)
1683
1684     def set_var(self, var):
1685         self.var = var
1686     
1687     def calculate_result_code(self):
1688         return self.var
1689
1690     def generate_result_code(self, code):
1691         pass
1692
1693     def analyse_types(self, env):
1694         pass
1695
1696
1697 class TempNode(ExprNode):
1698     # Node created during analyse_types phase
1699     # of some nodes to hold a temporary value.
1700     #
1701     # Note: One must call "allocate" and "release" on
1702     # the node during code generation to get/release the temp.
1703     # This is because the temp result is often used outside of
1704     # the regular cycle.
1705
1706     subexprs = []
1707     
1708     def __init__(self, pos, type, env):
1709         ExprNode.__init__(self, pos)
1710         self.type = type
1711         if type.is_pyobject:
1712             self.result_ctype = py_object_type
1713         self.is_temp = 1
1714         
1715     def analyse_types(self, env):
1716         return self.type
1717     
1718     def generate_result_code(self, code):
1719         pass
1720
1721     def allocate(self, code):
1722         self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1723
1724     def release(self, code):
1725         code.funcstate.release_temp(self.temp_cname)
1726         self.temp_cname = None
1727
1728     def result(self):
1729         try:
1730             return self.temp_cname
1731         except:
1732             assert False, "Remember to call allocate/release on TempNode"
1733             raise
1734
1735     # Do not participate in normal temp alloc/dealloc:
1736     def allocate_temp_result(self, code):
1737         pass
1738     
1739     def release_temp_result(self, code):
1740         pass
1741
1742 class PyTempNode(TempNode):
1743     #  TempNode holding a Python value.
1744     
1745     def __init__(self, pos, env):
1746         TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1747
1748 class RawCNameExprNode(ExprNode):
1749     subexprs = []
1750     
1751     def __init__(self, pos, type=None):
1752         self.pos = pos
1753         self.type = type
1754
1755     def analyse_types(self, env):
1756         return self.type
1757
1758     def set_cname(self, cname):
1759         self.cname = cname
1760
1761     def result(self):
1762         return self.cname
1763
1764     def generate_result_code(self, code):
1765         pass
1766
1767
1768 #-------------------------------------------------------------------
1769 #
1770 #  Trailer nodes
1771 #
1772 #-------------------------------------------------------------------
1773
1774 class IndexNode(ExprNode):
1775     #  Sequence indexing.
1776     #
1777     #  base     ExprNode
1778     #  index    ExprNode
1779     #  indices  [ExprNode]
1780     #  is_buffer_access boolean Whether this is a buffer access.
1781     #
1782     #  indices is used on buffer access, index on non-buffer access.
1783     #  The former contains a clean list of index parameters, the
1784     #  latter whatever Python object is needed for index access.
1785     
1786     subexprs = ['base', 'index', 'indices']
1787     indices = None
1788
1789     def __init__(self, pos, index, *args, **kw):
1790         ExprNode.__init__(self, pos, index=index, *args, **kw)
1791         self._index = index
1792
1793     def calculate_constant_result(self):
1794         self.constant_result = \
1795             self.base.constant_result[self.index.constant_result]
1796
1797     def compile_time_value(self, denv):
1798         base = self.base.compile_time_value(denv)
1799         index = self.index.compile_time_value(denv)
1800         try:
1801             return base[index]
1802         except Exception, e:
1803             self.compile_time_value_error(e)
1804     
1805     def is_ephemeral(self):
1806         return self.base.is_ephemeral()
1807     
1808     def analyse_target_declaration(self, env):
1809         pass
1810         
1811     def analyse_as_type(self, env):
1812         base_type = self.base.analyse_as_type(env)
1813         if base_type and not base_type.is_pyobject:
1814             if base_type.is_cpp_class:
1815                 if isinstance(self.index, TupleNode):
1816                     template_values = self.index.args
1817                 else:
1818                     template_values = [self.index]
1819                 import Nodes
1820                 type_node = Nodes.TemplatedTypeNode(
1821                     pos = self.pos, 
1822                     positional_args = template_values, 
1823                     keyword_args = None)
1824                 return type_node.analyse(env, base_type = base_type)
1825             else:
1826                 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
1827         return None
1828     
1829     def type_dependencies(self, env):
1830         return self.base.type_dependencies(env)
1831     
1832     def infer_type(self, env):
1833         if isinstance(self.base, (StringNode, UnicodeNode)): # FIXME: BytesNode?
1834             return py_object_type
1835         base_type = self.base.infer_type(env)
1836         if base_type.is_ptr or base_type.is_array:
1837             return base_type.base_type
1838         else:
1839             # TODO: Handle buffers (hopefully without too much redundancy).
1840             return py_object_type
1841     
1842     def analyse_types(self, env):
1843         self.analyse_base_and_index_types(env, getting = 1)
1844     
1845     def analyse_target_types(self, env):
1846         self.analyse_base_and_index_types(env, setting = 1)
1847
1848     def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
1849         # Note: This might be cleaned up by having IndexNode
1850         # parsed in a saner way and only construct the tuple if
1851         # needed.
1852
1853         # Note that this function must leave IndexNode in a cloneable state.
1854         # For buffers, self.index is packed out on the initial analysis, and
1855         # when cloning self.indices is copied.
1856         self.is_buffer_access = False
1857
1858         self.base.analyse_types(env)
1859         if self.base.type.is_error:
1860             # Do not visit child tree if base is undeclared to avoid confusing
1861             # error messages
1862             self.type = PyrexTypes.error_type
1863             return
1864         
1865         # Handle the case where base is a literal char* (and we expect a string, not an int)
1866         if isinstance(self.base, BytesNode):
1867             self.base = self.base.coerce_to_pyobject(env)
1868
1869         skip_child_analysis = False
1870         buffer_access = False
1871         if self.base.type.is_buffer:
1872             assert hasattr(self.base, "entry") # Must be a NameNode-like node
1873             if self.indices:
1874                 indices = self.indices
1875             else:
1876                 if isinstance(self.index, TupleNode):
1877                     indices = self.index.args
1878                 else:
1879                     indices = [self.index]
1880             if len(indices) == self.base.type.ndim:
1881                 buffer_access = True
1882                 skip_child_analysis = True
1883                 for x in indices:
1884                     x.analyse_types(env)
1885                     if not x.type.is_int:
1886                         buffer_access = False
1887
1888         # On cloning, indices is cloned. Otherwise, unpack index into indices
1889         assert not (buffer_access and isinstance(self.index, CloneNode))
1890
1891         if buffer_access:
1892             self.indices = indices
1893             self.index = None
1894             self.type = self.base.type.dtype
1895             self.is_buffer_access = True
1896             self.buffer_type = self.base.entry.type
1897
1898             if getting and self.type.is_pyobject:
1899                 self.is_temp = True
1900             if setting:
1901                 if not self.base.entry.type.writable:
1902                     error(self.pos, "Writing to readonly buffer")
1903                 else:
1904                     self.base.entry.buffer_aux.writable_needed = True
1905         else:
1906             if isinstance(self.index, TupleNode):
1907                 self.index.analyse_types(env, skip_children=skip_child_analysis)
1908             elif not skip_child_analysis:
1909                 self.index.analyse_types(env)
1910             self.original_index_type = self.index.type
1911             if self.base.type.is_pyobject:
1912                 if self.index.type.is_int:
1913                     if (not setting
1914                         and (self.base.type is list_type or self.base.type is tuple_type)
1915                         and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
1916                         and not env.directives['boundscheck']):
1917                         self.is_temp = 0
1918                     else:
1919                         self.is_temp = 1
1920                     self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
1921                 else:
1922                     self.index = self.index.coerce_to_pyobject(env)
1923                     self.is_temp = 1
1924                 self.type = py_object_type
1925             else:
1926                 if self.base.type.is_ptr or self.base.type.is_array:
1927                     self.type = self.base.type.base_type
1928                     if self.index.type.is_pyobject:
1929                         self.index = self.index.coerce_to(
1930                             PyrexTypes.c_py_ssize_t_type, env)
1931                     if not self.index.type.is_int:
1932                         error(self.pos,
1933                             "Invalid index type '%s'" %
1934                                 self.index.type)
1935                 elif self.base.type.is_cpp_class:
1936                     function = env.lookup_operator("[]", [self.base, self.index])
1937                     if function is None:
1938                         error(self.pos, "Indexing '%s' not supported for index type '%s'" % (self.base.type, self.index.type))
1939                         self.type = PyrexTypes.error_type
1940                         self.result_code = "<error>"
1941                         return
1942                     func_type = function.type
1943                     if func_type.is_ptr:
1944                         func_type = func_type.base_type
1945                     self.index = self.index.coerce_to(func_type.args[0].type, env)
1946                     self.type = func_type.return_type
1947                     if setting and not func_type.return_type.is_reference:
1948                         error(self.pos, "Can't set non-reference result '%s'" % self.type)
1949                 else:
1950                     error(self.pos,
1951                         "Attempting to index non-array type '%s'" %
1952                             self.base.type)
1953                     self.type = PyrexTypes.error_type
1954     gil_message = "Indexing Python object"
1955
1956     def nogil_check(self, env):
1957         if self.is_buffer_access:
1958             if env.directives['boundscheck']:
1959                 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
1960                 return
1961             elif self.type.is_pyobject:
1962                 error(self.pos, "Cannot access buffer with object dtype without gil")
1963                 return
1964         super(IndexNode, self).nogil_check(env)
1965
1966
1967     def check_const_addr(self):
1968         return self.base.check_const_addr() and self.index.check_const()
1969     
1970     def is_lvalue(self):
1971         return 1
1972
1973     def calculate_result_code(self):
1974         if self.is_buffer_access:
1975             return "(*%s)" % self.buffer_ptr_code
1976         elif self.base.type is list_type:
1977             return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
1978         elif self.base.type is tuple_type:
1979             return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
1980         else:
1981             return "(%s[%s])" % (
1982                 self.base.result(), self.index.result())
1983             
1984     def extra_index_params(self):
1985         if self.index.type.is_int:
1986             if self.original_index_type.signed:
1987                 size_adjustment = ""
1988             else:
1989                 size_adjustment = "+1"
1990             return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
1991         else:
1992             return ""
1993
1994     def generate_subexpr_evaluation_code(self, code):
1995         self.base.generate_evaluation_code(code)
1996         if not self.indices:
1997             self.index.generate_evaluation_code(code)
1998         else:
1999             for i in self.indices:
2000                 i.generate_evaluation_code(code)
2001         
2002     def generate_subexpr_disposal_code(self, code):
2003         self.base.generate_disposal_code(code)
2004         if not self.indices:
2005             self.index.generate_disposal_code(code)
2006         else:
2007             for i in self.indices:
2008                 i.generate_disposal_code(code)
2009
2010     def free_subexpr_temps(self, code):
2011         self.base.free_temps(code)
2012         if not self.indices:
2013             self.index.free_temps(code)
2014         else:
2015             for i in self.indices:
2016                 i.free_temps(code)
2017
2018     def generate_result_code(self, code):
2019         if self.is_buffer_access:
2020             if code.globalstate.directives['nonecheck']:
2021                 self.put_nonecheck(code)
2022             self.buffer_ptr_code = self.buffer_lookup_code(code)
2023             if self.type.is_pyobject:
2024                 # is_temp is True, so must pull out value and incref it.
2025                 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2026                 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2027         elif self.type.is_pyobject and self.is_temp:
2028             if self.index.type.is_int:
2029                 index_code = self.index.result()
2030                 if self.base.type is list_type:
2031                     function = "__Pyx_GetItemInt_List"
2032                 elif self.base.type is tuple_type:
2033                     function = "__Pyx_GetItemInt_Tuple"
2034                 else:
2035                     function = "__Pyx_GetItemInt"
2036                 code.globalstate.use_utility_code(getitem_int_utility_code)
2037             else:
2038                 function = "PyObject_GetItem"
2039                 index_code = self.index.py_result()
2040                 sign_code = ""
2041             code.putln(
2042                 "%s = %s(%s, %s%s); if (!%s) %s" % (
2043                     self.result(),
2044                     function,
2045                     self.base.py_result(),
2046                     index_code,
2047                     self.extra_index_params(),
2048                     self.result(),
2049                     code.error_goto(self.pos)))
2050             code.put_gotref(self.py_result())
2051             
2052     def generate_setitem_code(self, value_code, code):
2053         if self.index.type.is_int:
2054             function = "__Pyx_SetItemInt"
2055             index_code = self.index.result()
2056             code.globalstate.use_utility_code(setitem_int_utility_code)
2057         else:
2058             index_code = self.index.py_result()
2059             if self.base.type is dict_type:
2060                 function = "PyDict_SetItem"
2061             # It would seem that we could specalized lists/tuples, but that
2062             # shouldn't happen here. 
2063             # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input, 
2064             # not a PyObject*, and bad conversion here would give the wrong 
2065             # exception. Also, tuples are supposed to be immutable, and raise 
2066             # TypeErrors when trying to set their entries (PyTuple_SetItem 
2067             # is for creating new tuples from). 
2068             else:
2069                 function = "PyObject_SetItem"
2070         code.putln(
2071             "if (%s(%s, %s, %s%s) < 0) %s" % (
2072                 function,
2073                 self.base.py_result(),
2074                 index_code,
2075                 value_code,
2076                 self.extra_index_params(),
2077                 code.error_goto(self.pos)))
2078
2079     def generate_buffer_setitem_code(self, rhs, code, op=""):
2080         # Used from generate_assignment_code and InPlaceAssignmentNode
2081         if code.globalstate.directives['nonecheck']:
2082             self.put_nonecheck(code)
2083         ptrexpr = self.buffer_lookup_code(code)
2084         if self.buffer_type.dtype.is_pyobject:
2085             # Must manage refcounts. Decref what is already there
2086             # and incref what we put in.
2087             ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2088             rhs_code = rhs.result()
2089             code.putln("%s = %s;" % (ptr, ptrexpr))
2090             code.put_gotref("*%s" % ptr)
2091             code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2092                 ptr, rhs_code
2093                 ))
2094             code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2095             code.put_giveref("*%s" % ptr)
2096             code.funcstate.release_temp(ptr)
2097         else: 
2098             # Simple case
2099             code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2100
2101     def generate_assignment_code(self, rhs, code):
2102         self.generate_subexpr_evaluation_code(code)
2103         if self.is_buffer_access:
2104             self.generate_buffer_setitem_code(rhs, code)
2105         elif self.type.is_pyobject:
2106             self.generate_setitem_code(rhs.py_result(), code)
2107         else:
2108             code.putln(
2109                 "%s = %s;" % (
2110                     self.result(), rhs.result()))
2111         self.generate_subexpr_disposal_code(code)
2112         self.free_subexpr_temps(code)
2113         rhs.generate_disposal_code(code)
2114         rhs.free_temps(code)
2115     
2116     def generate_deletion_code(self, code):
2117         self.generate_subexpr_evaluation_code(code)
2118         #if self.type.is_pyobject:
2119         if self.index.type.is_int:
2120             function = "__Pyx_DelItemInt"
2121             index_code = self.index.result()
2122             code.globalstate.use_utility_code(delitem_int_utility_code)
2123         else:
2124             index_code = self.index.py_result()
2125             if self.base.type is dict_type:
2126                 function = "PyDict_DelItem"
2127             else:
2128                 function = "PyObject_DelItem"
2129         code.putln(
2130             "if (%s(%s, %s%s) < 0) %s" % (
2131                 function,
2132                 self.base.py_result(),
2133                 index_code,
2134                 self.extra_index_params(),
2135                 code.error_goto(self.pos)))
2136         self.generate_subexpr_disposal_code(code)
2137         self.free_subexpr_temps(code)
2138
2139     def buffer_lookup_code(self, code):
2140         # Assign indices to temps
2141         index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2142         for temp, index in zip(index_temps, self.indices):
2143             code.putln("%s = %s;" % (temp, index.result()))
2144         # Generate buffer access code using these temps
2145         import Buffer
2146         # The above could happen because child_attrs is wrong somewhere so that
2147         # options are not propagated.
2148         return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2149                                              index_signeds=[i.type.signed for i in self.indices],
2150                                              index_cnames=index_temps,
2151                                              directives=code.globalstate.directives,
2152                                              pos=self.pos, code=code)
2153
2154     def put_nonecheck(self, code):
2155         code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2156         code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2157         code.putln("__Pyx_RaiseNoneIndexingError();")
2158         code.putln(code.error_goto(self.pos))
2159         code.putln("}")
2160
2161 class SliceIndexNode(ExprNode):
2162     #  2-element slice indexing
2163     #
2164     #  base      ExprNode
2165     #  start     ExprNode or None
2166     #  stop      ExprNode or None
2167     
2168     subexprs = ['base', 'start', 'stop']
2169
2170     def infer_type(self, env):
2171         base_type = self.base.infer_type(env)
2172         if base_type.is_string:
2173             return bytes_type
2174         elif base_type in (bytes_type, str_type, unicode_type,
2175                            list_type, tuple_type):
2176             return base_type
2177         return py_object_type
2178
2179     def calculate_constant_result(self):
2180         self.constant_result = self.base.constant_result[
2181             self.start.constant_result : self.stop.constant_result]
2182
2183     def compile_time_value(self, denv):
2184         base = self.base.compile_time_value(denv)
2185         if self.start is None:
2186             start = 0
2187         else:
2188             start = self.start.compile_time_value(denv)
2189         if self.stop is None:
2190             stop = None
2191         else:
2192             stop = self.stop.compile_time_value(denv)
2193         try:
2194             return base[start:stop]
2195         except Exception, e:
2196             self.compile_time_value_error(e)
2197     
2198     def analyse_target_declaration(self, env):
2199         pass
2200     
2201     def analyse_target_types(self, env):
2202         self.analyse_types(env)
2203         # when assigning, we must accept any Python type
2204         if self.type.is_pyobject:
2205             self.type = py_object_type
2206
2207     def analyse_types(self, env):
2208         self.base.analyse_types(env)
2209         if self.start:
2210             self.start.analyse_types(env)
2211         if self.stop:
2212             self.stop.analyse_types(env)
2213         base_type = self.base.type
2214         if base_type.is_string:
2215             self.type = bytes_type
2216         elif base_type.is_array or base_type.is_ptr:
2217             # we need a ptr type here instead of an array type, as
2218             # array types can result in invalid type casts in the C
2219             # code
2220             self.type = PyrexTypes.CPtrType(base_type.base_type)
2221         else:
2222             self.base = self.base.coerce_to_pyobject(env)
2223             self.type = py_object_type
2224         if base_type.is_builtin_type:
2225             # slicing builtin types returns something of the same type
2226             self.type = base_type
2227         c_int = PyrexTypes.c_py_ssize_t_type
2228         if self.start:
2229             self.start = self.start.coerce_to(c_int, env)
2230         if self.stop:
2231             self.stop = self.stop.coerce_to(c_int, env)
2232         self.is_temp = 1
2233
2234     nogil_check = Node.gil_error
2235     gil_message = "Slicing Python object"
2236
2237     def generate_result_code(self, code):
2238         if not self.type.is_pyobject:
2239             error(self.pos,
2240                   "Slicing is not currently supported for '%s'." % self.type)
2241             return
2242         if self.base.type.is_string:
2243             if self.stop is None:
2244                 code.putln(
2245                     "%s = __Pyx_PyBytes_FromString(%s + %s); %s" % (
2246                         self.result(),
2247                         self.base.result(),
2248                         self.start_code(),
2249                         code.error_goto_if_null(self.result(), self.pos)))
2250             else:
2251                 code.putln(
2252                     "%s = __Pyx_PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2253                         self.result(),
2254                         self.base.result(),
2255                         self.start_code(),
2256                         self.stop_code(),
2257                         self.start_code(),
2258                         code.error_goto_if_null(self.result(), self.pos)))
2259         else:
2260             code.putln(
2261                 "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
2262                     self.result(),
2263                     self.base.py_result(),
2264                     self.start_code(),
2265                     self.stop_code(),
2266                     code.error_goto_if_null(self.result(), self.pos)))
2267         code.put_gotref(self.py_result())
2268     
2269     def generate_assignment_code(self, rhs, code):
2270         self.generate_subexpr_evaluation_code(code)
2271         if self.type.is_pyobject:
2272             code.put_error_if_neg(self.pos, 
2273                 "PySequence_SetSlice(%s, %s, %s, %s)" % (
2274                     self.base.py_result(),
2275                     self.start_code(),
2276                     self.stop_code(),
2277                     rhs.result()))
2278         else:
2279             start_offset = ''
2280             if self.start:
2281                 start_offset = self.start_code()
2282                 if start_offset == '0':
2283                     start_offset = ''
2284                 else:
2285                     start_offset += '+'
2286             if rhs.type.is_array:
2287                 array_length = rhs.type.size
2288                 self.generate_slice_guard_code(code, array_length)
2289             else:
2290                 error(self.pos,
2291                       "Slice assignments from pointers are not yet supported.")
2292                 # FIXME: fix the array size according to start/stop
2293                 array_length = self.base.type.size
2294             for i in range(array_length):
2295                 code.putln("%s[%s%s] = %s[%d];" % (
2296                         self.base.result(), start_offset, i,
2297                         rhs.result(), i))
2298         self.generate_subexpr_disposal_code(code)
2299         self.free_subexpr_temps(code)
2300         rhs.generate_disposal_code(code)
2301         rhs.free_temps(code)
2302
2303     def generate_deletion_code(self, code):
2304         if not self.base.type.is_pyobject:
2305             error(self.pos,
2306                   "Deleting slices is only supported for Python types, not '%s'." % self.type)
2307             return
2308         self.generate_subexpr_evaluation_code(code)
2309         code.put_error_if_neg(self.pos,
2310             "PySequence_DelSlice(%s, %s, %s)" % (
2311                 self.base.py_result(),
2312                 self.start_code(),
2313                 self.stop_code()))
2314         self.generate_subexpr_disposal_code(code)
2315
2316     def generate_slice_guard_code(self, code, target_size):
2317         if not self.base.type.is_array:
2318             return
2319         slice_size = self.base.type.size
2320         start = stop = None
2321         if self.stop:
2322             stop = self.stop.result()
2323             try:
2324                 stop = int(stop)
2325                 if stop < 0:
2326                     slice_size = self.base.type.size + stop
2327                 else:
2328                     slice_size = stop
2329                 stop = None
2330             except ValueError:
2331                 pass
2332         if self.start:
2333             start = self.start.result()
2334             try:
2335                 start = int(start)
2336                 if start < 0:
2337                     start = self.base.type.size + start
2338                 slice_size -= start
2339                 start = None
2340             except ValueError:
2341                 pass
2342         check = None
2343         if slice_size < 0:
2344             if target_size > 0:
2345                 error(self.pos, "Assignment to empty slice.")
2346         elif start is None and stop is None:
2347             # we know the exact slice length
2348             if target_size != slice_size:
2349                 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2350                         slice_size, target_size))
2351         elif start is not None:
2352             if stop is None:
2353                 stop = slice_size
2354             check = "(%s)-(%s)" % (stop, start)
2355         else: # stop is not None:
2356             check = stop
2357         if check:
2358             code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2359             code.putln('PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length, expected %%"PY_FORMAT_SIZE_T"d, got %%"PY_FORMAT_SIZE_T"d", (Py_ssize_t)%d, (Py_ssize_t)(%s));' % (
2360                         target_size, check))
2361             code.putln(code.error_goto(self.pos))
2362             code.putln("}")
2363     
2364     def start_code(self):
2365         if self.start:
2366             return self.start.result()
2367         else:
2368             return "0"
2369     
2370     def stop_code(self):
2371         if self.stop:
2372             return self.stop.result()
2373         elif self.base.type.is_array:
2374             return self.base.type.size
2375         else:
2376             return "PY_SSIZE_T_MAX"
2377     
2378     def calculate_result_code(self):
2379         # self.result() is not used, but this method must exist
2380         return "<unused>"
2381     
2382
2383 class SliceNode(ExprNode):
2384     #  start:stop:step in subscript list
2385     #
2386     #  start     ExprNode
2387     #  stop      ExprNode
2388     #  step      ExprNode
2389     
2390     type = py_object_type
2391     is_temp = 1
2392
2393     def calculate_constant_result(self):
2394         self.constant_result = self.base.constant_result[
2395             self.start.constant_result : \
2396                 self.stop.constant_result : \
2397                 self.step.constant_result]
2398
2399     def compile_time_value(self, denv):
2400         start = self.start.compile_time_value(denv)
2401         if self.stop is None:
2402             stop = None
2403         else:
2404             stop = self.stop.compile_time_value(denv)
2405         if self.step is None:
2406             step = None
2407         else:
2408             step = self.step.compile_time_value(denv)
2409         try:
2410             return slice(start, stop, step)
2411         except Exception, e:
2412             self.compile_time_value_error(e)
2413
2414     subexprs = ['start', 'stop', 'step']
2415     
2416     def analyse_types(self, env):
2417         self.start.analyse_types(env)
2418         self.stop.analyse_types(env)
2419         self.step.analyse_types(env)
2420         self.start = self.start.coerce_to_pyobject(env)
2421         self.stop = self.stop.coerce_to_pyobject(env)
2422         self.step = self.step.coerce_to_pyobject(env)
2423
2424     gil_message = "Constructing Python slice object"
2425
2426     def generate_result_code(self, code):
2427         code.putln(
2428             "%s = PySlice_New(%s, %s, %s); %s" % (
2429                 self.result(),
2430                 self.start.py_result(), 
2431                 self.stop.py_result(), 
2432                 self.step.py_result(),
2433                 code.error_goto_if_null(self.result(), self.pos)))
2434         code.put_gotref(self.py_result())
2435
2436
2437 class CallNode(ExprNode):
2438
2439     def analyse_as_type_constructor(self, env):
2440         type = self.function.analyse_as_type(env)
2441         if type and type.is_struct_or_union:
2442             args, kwds = self.explicit_args_kwds()
2443             items = []
2444             for arg, member in zip(args, type.scope.var_entries):
2445                 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2446             if kwds:
2447                 items += kwds.key_value_pairs
2448             self.key_value_pairs = items
2449             self.__class__ = DictNode
2450             self.analyse_types(env)
2451             self.coerce_to(type, env)
2452             return True
2453         elif type and type.is_cpp_class:
2454             for arg in self.args:
2455                 arg.analyse_types(env)
2456             constructor = type.scope.lookup("<init>")
2457             self.function = RawCNameExprNode(self.function.pos, constructor.type)
2458             self.function.entry = constructor
2459             self.function.set_cname(type.declaration_code(""))
2460             self.analyse_c_function_call(env)
2461             return True
2462     
2463     def is_lvalue(self):
2464         return self.type.is_reference
2465
2466     def nogil_check(self, env):
2467         func_type = self.function_type()
2468         if func_type.is_pyobject:
2469             self.gil_error()
2470         elif not getattr(func_type, 'nogil', False):
2471             self.gil_error()
2472
2473     gil_message = "Calling gil-requiring function"
2474
2475
2476 class SimpleCallNode(CallNode):
2477     #  Function call without keyword, * or ** args.
2478     #
2479     #  function       ExprNode
2480     #  args           [ExprNode]
2481     #  arg_tuple      ExprNode or None     used internally
2482     #  self           ExprNode or None     used internally
2483     #  coerced_self   ExprNode or None     used internally
2484     #  wrapper_call   bool                 used internally
2485     #  has_optional_args   bool            used internally
2486     
2487     subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2488     
2489     self = None
2490     coerced_self = None
2491     arg_tuple = None
2492     wrapper_call = False
2493     has_optional_args = False
2494     
2495     def compile_time_value(self, denv):
2496         function = self.function.compile_time_value(denv)
2497         args = [arg.compile_time_value(denv) for arg in self.args]
2498         try:
2499             return function(*args)
2500         except Exception, e:
2501             self.compile_time_value_error(e)
2502             
2503     def type_dependencies(self, env):
2504         # TODO: Update when Danilo's C++ code merged in to handle the
2505         # the case of function overloading.
2506         return self.function.type_dependencies(env)
2507     
2508     def infer_type(self, env):
2509         function = self.function
2510         func_type = function.infer_type(env)
2511         if isinstance(self.function, NewExprNode):
2512             return PyrexTypes.CPtrType(self.function.class_type)
2513         if func_type.is_ptr:
2514             func_type = func_type.base_type
2515         if func_type.is_cfunction:
2516             return func_type.return_type
2517         elif func_type is type_type:
2518             if function.is_name and function.entry and function.entry.type:
2519                 result_type = function.entry.type
2520                 if result_type.is_extension_type:
2521                     return result_type
2522                 elif result_type.is_builtin_type:
2523                     if function.entry.name == 'float':
2524                         return PyrexTypes.c_double_type
2525                     elif function.entry.name in Builtin.types_that_construct_their_instance:
2526                         return result_type
2527         return py_object_type
2528
2529     def analyse_as_type(self, env):
2530         attr = self.function.as_cython_attribute()
2531         if attr == 'pointer':
2532             if len(self.args) != 1:
2533                 error(self.args.pos, "only one type allowed.")
2534             else:
2535                 type = self.args[0].analyse_as_type(env)
2536                 if not type:
2537                     error(self.args[0].pos, "Unknown type")
2538                 else:
2539                     return PyrexTypes.CPtrType(type)
2540
2541     def explicit_args_kwds(self):
2542         return self.args, None
2543
2544     def analyse_types(self, env):
2545         if self.analyse_as_type_constructor(env):
2546             return
2547         function = self.function
2548         function.is_called = 1
2549         self.function.analyse_types(env)
2550         if function.is_attribute and function.entry and function.entry.is_cmethod:
2551             # Take ownership of the object from which the attribute
2552             # was obtained, because we need to pass it as 'self'.
2553             self.self = function.obj
2554             function.obj = CloneNode(self.self)
2555         func_type = self.function_type()
2556         if func_type.is_pyobject:
2557             self.arg_tuple = TupleNode(self.pos, args = self.args)
2558             self.arg_tuple.analyse_types(env)
2559             self.args = None
2560             if func_type is Builtin.type_type and function.is_name and \
2561                    function.entry and \
2562                    function.entry.is_builtin and \
2563                    function.entry.name in Builtin.types_that_construct_their_instance:
2564                 # calling a builtin type that returns a specific object type
2565                 if function.entry.name == 'float':
2566                     # the following will come true later on in a transform
2567                     self.type = PyrexTypes.c_double_type
2568                     self.result_ctype = PyrexTypes.c_double_type
2569                 else:
2570                     self.type = Builtin.builtin_types[function.entry.name]
2571                     self.result_ctype = py_object_type
2572             elif function.is_name and function.type_entry:
2573                 # We are calling an extension type constructor.  As
2574                 # long as we do not support __new__(), the result type
2575                 # is clear
2576                 self.type = function.type_entry.type
2577                 self.result_ctype = py_object_type
2578             else:
2579                 self.type = py_object_type
2580             self.is_temp = 1
2581         else:
2582             for arg in self.args:
2583                 arg.analyse_types(env)
2584             if self.self and func_type.args:
2585                 # Coerce 'self' to the type expected by the method.
2586                 expected_type = func_type.args[0].type
2587                 self.coerced_self = CloneNode(self.self).coerce_to(
2588                     expected_type, env)
2589                 # Insert coerced 'self' argument into argument list.
2590                 self.args.insert(0, self.coerced_self)
2591             self.analyse_c_function_call(env)
2592     
2593     def function_type(self):
2594         # Return the type of the function being called, coercing a function
2595         # pointer to a function if necessary.
2596         func_type = self.function.type
2597         if func_type.is_ptr:
2598             func_type = func_type.base_type
2599         return func_type
2600     
2601     def analyse_c_function_call(self, env):
2602         if self.function.type is error_type:
2603             self.type = error_type
2604             return
2605         if self.function.type.is_cpp_class:
2606             overloaded_entry = self.function.type.scope.lookup("operator()")
2607             if overloaded_entry is None:
2608                 self.type = PyrexTypes.error_type
2609                 self.result_code = "<error>"
2610                 return
2611         elif hasattr(self.function, 'entry'):
2612             overloaded_entry = self.function.entry
2613         else:
2614             overloaded_entry = None
2615         if overloaded_entry:
2616             entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2617             if not entry:
2618                 self.type = PyrexTypes.error_type
2619                 self.result_code = "<error>"
2620                 return
2621             self.function.entry = entry
2622             self.function.type = entry.type
2623             func_type = self.function_type()
2624         else:
2625             func_type = self.function_type()
2626             if not func_type.is_cfunction:
2627                 error(self.pos, "Calling non-function type '%s'" % func_type)
2628                 self.type = PyrexTypes.error_type
2629                 self.result_code = "<error>"
2630                 return
2631         # Check no. of args
2632         max_nargs = len(func_type.args)
2633         expected_nargs = max_nargs - func_type.optional_arg_count
2634         actual_nargs = len(self.args)
2635         if func_type.optional_arg_count and expected_nargs != actual_nargs:
2636             self.has_optional_args = 1
2637             self.is_temp = 1
2638         # Coerce arguments
2639         for i in range(min(max_nargs, actual_nargs)):
2640             formal_type = func_type.args[i].type
2641             self.args[i] = self.args[i].coerce_to(formal_type, env)
2642         for i in range(max_nargs, actual_nargs):
2643             if self.args[i].type.is_pyobject:
2644                 error(self.args[i].pos, 
2645                     "Python object cannot be passed as a varargs parameter")
2646         # Calc result type and code fragment
2647         if isinstance(self.function, NewExprNode):
2648             self.type = PyrexTypes.CPtrType(self.function.class_type)
2649         else:
2650             self.type = func_type.return_type
2651         if self.type.is_pyobject:
2652             self.result_ctype = py_object_type
2653             self.is_temp = 1
2654         elif func_type.exception_value is not None \
2655                  or func_type.exception_check:
2656             self.is_temp = 1
2657         # C++ exception handler
2658         if func_type.exception_check == '+':
2659             if func_type.exception_value is None:
2660                 env.use_utility_code(cpp_exception_utility_code)
2661
2662     def calculate_result_code(self):
2663         return self.c_call_code()
2664     
2665     def c_call_code(self):
2666         func_type = self.function_type()
2667         if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
2668             return "<error>"
2669         formal_args = func_type.args
2670         arg_list_code = []
2671         args = zip(formal_args, self.args)
2672         max_nargs = len(func_type.args)
2673         expected_nargs = max_nargs - func_type.optional_arg_count
2674         actual_nargs = len(self.args)
2675         for formal_arg, actual_arg in args[:expected_nargs]:
2676                 arg_code = actual_arg.result_as(formal_arg.type)
2677                 arg_list_code.append(arg_code)
2678                 
2679         if func_type.is_overridable:
2680             arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
2681                 
2682         if func_type.optional_arg_count:
2683             if expected_nargs == actual_nargs:
2684                 optional_args = 'NULL'
2685             else:
2686                 optional_args = "&%s" % self.opt_arg_struct
2687             arg_list_code.append(optional_args)
2688             
2689         for actual_arg in self.args[len(formal_args):]:
2690             arg_list_code.append(actual_arg.result())
2691         result = "%s(%s)" % (self.function.result(),
2692             ', '.join(arg_list_code))
2693         return result
2694     
2695     def generate_result_code(self, code):
2696         func_type = self.function_type()
2697         if func_type.is_pyobject:
2698             arg_code = self.arg_tuple.py_result()
2699             code.putln(
2700                 "%s = PyObject_Call(%s, %s, NULL); %s" % (
2701                     self.result(),
2702                     self.function.py_result(),
2703                     arg_code,
2704                     code.error_goto_if_null(self.result(), self.pos)))
2705             code.put_gotref(self.py_result())
2706         elif func_type.is_cfunction:
2707             if self.has_optional_args:
2708                 actual_nargs = len(self.args)
2709                 expected_nargs = len(func_type.args) - func_type.optional_arg_count
2710                 self.opt_arg_struct = code.funcstate.allocate_temp(
2711                     func_type.op_arg_struct.base_type, manage_ref=True)
2712                 code.putln("%s.%s = %s;" % (
2713                         self.opt_arg_struct,
2714                         Naming.pyrex_prefix + "n",
2715                         len(self.args) - expected_nargs))
2716                 args = zip(func_type.args, self.args)
2717                 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
2718                     code.putln("%s.%s = %s;" % (
2719                             self.opt_arg_struct,
2720                             func_type.opt_arg_cname(formal_arg.name),
2721                             actual_arg.result_as(formal_arg.type)))
2722             exc_checks = []
2723             if self.type.is_pyobject and self.is_temp:
2724                 exc_checks.append("!%s" % self.result())
2725             else:
2726                 exc_val = func_type.exception_value
2727                 exc_check = func_type.exception_check
2728                 if exc_val is not None:
2729                     exc_checks.append("%s == %s" % (self.result(), exc_val))
2730                 if exc_check:
2731                     exc_checks.append("PyErr_Occurred()")
2732             if self.is_temp or exc_checks:
2733                 rhs = self.c_call_code()
2734                 if self.result():
2735                     lhs = "%s = " % self.result()
2736                     if self.is_temp and self.type.is_pyobject:
2737                         #return_type = self.type # func_type.return_type
2738                         #print "SimpleCallNode.generate_result_code: casting", rhs, \
2739                         #    "from", return_type, "to pyobject" ###
2740                         rhs = typecast(py_object_type, self.type, rhs)
2741                 else:
2742                     lhs = ""
2743                 if func_type.exception_check == '+':
2744                     if func_type.exception_value is None:
2745                         raise_py_exception = "__Pyx_CppExn2PyErr()"
2746                     elif func_type.exception_value.type.is_pyobject:
2747                         raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
2748                             func_type.exception_value.entry.cname,
2749                             func_type.exception_value.entry.cname)
2750                     else:
2751                         raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
2752                     code.putln(
2753                     "try {%s%s;} catch(...) {%s; %s}" % (
2754                         lhs,
2755                         rhs,
2756                         raise_py_exception,
2757                         code.error_goto(self.pos)))
2758                 else:
2759                     if exc_checks:
2760                         goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
2761                     else:
2762                         goto_error = ""
2763                     code.putln("%s%s; %s" % (lhs, rhs, goto_error))
2764                 if self.type.is_pyobject and self.result():
2765                     code.put_gotref(self.py_result())
2766             if self.has_optional_args:
2767                 code.funcstate.release_temp(self.opt_arg_struct)
2768
2769
2770 class PythonCapiFunctionNode(ExprNode):
2771     subexprs = []
2772     def __init__(self, pos, py_name, cname, func_type, utility_code = None):
2773         self.pos = pos
2774         self.name = py_name
2775         self.cname = cname
2776         self.type = func_type
2777         self.utility_code = utility_code
2778
2779     def analyse_types(self, env):
2780         pass
2781
2782     def generate_result_code(self, code):
2783         if self.utility_code:
2784             code.globalstate.use_utility_code(self.utility_code)
2785
2786     def calculate_result_code(self):
2787         return self.cname
2788
2789 class PythonCapiCallNode(SimpleCallNode):
2790     # Python C-API Function call (only created in transforms)
2791
2792     def __init__(self, pos, function_name, func_type,
2793                  utility_code = None, py_name=None, **kwargs):
2794         self.type = func_type.return_type
2795         self.result_ctype = self.type
2796         self.function = PythonCapiFunctionNode(
2797             pos, py_name, function_name, func_type,
2798             utility_code = utility_code)
2799         # call this last so that we can override the constructed
2800         # attributes above with explicit keyword arguments if required
2801         SimpleCallNode.__init__(self, pos, **kwargs)
2802
2803
2804 class GeneralCallNode(CallNode):
2805     #  General Python function call, including keyword,
2806     #  * and ** arguments.
2807     #
2808     #  function         ExprNode
2809     #  positional_args  ExprNode          Tuple of positional arguments
2810     #  keyword_args     ExprNode or None  Dict of keyword arguments
2811     #  starstar_arg     ExprNode or None  Dict of extra keyword args
2812     
2813     type = py_object_type
2814     
2815     subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
2816
2817     nogil_check = Node.gil_error
2818
2819     def compile_time_value(self, denv):
2820         function = self.function.compile_time_value(denv)
2821         positional_args = self.positional_args.compile_time_value(denv)
2822         keyword_args = self.keyword_args.compile_time_value(denv)
2823         starstar_arg = self.starstar_arg.compile_time_value(denv)
2824         try:
2825             keyword_args.update(starstar_arg)
2826             return function(*positional_args, **keyword_args)
2827         except Exception, e:
2828             self.compile_time_value_error(e)
2829             
2830     def explicit_args_kwds(self):
2831         if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
2832             raise PostParseError(self.pos,
2833                 'Compile-time keyword arguments must be explicit.')
2834         return self.positional_args.args, self.keyword_args
2835
2836     def analyse_types(self, env):
2837         if self.analyse_as_type_constructor(env):
2838             return
2839         self.function.analyse_types(env)
2840         self.positional_args.analyse_types(env)
2841         if self.keyword_args:
2842             self.keyword_args.analyse_types(env)
2843         if self.starstar_arg:
2844             self.starstar_arg.analyse_types(env)
2845         if not self.function.type.is_pyobject:
2846             if self.function.type.is_error:
2847                 self.type = error_type
2848                 return
2849             if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
2850                 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
2851             else:
2852                 self.function = self.function.coerce_to_pyobject(env)
2853         self.positional_args = \
2854             self.positional_args.coerce_to_pyobject(env)
2855         if self.starstar_arg:
2856             self.starstar_arg = \
2857                 self.starstar_arg.coerce_to_pyobject(env)
2858         function = self.function
2859         if function.is_name and function.type_entry:
2860             # We are calling an extension type constructor.  As long
2861             # as we do not support __new__(), the result type is clear
2862             self.type = function.type_entry.type
2863             self.result_ctype = py_object_type
2864         else:
2865             self.type = py_object_type
2866         self.is_temp = 1
2867         
2868     def generate_result_code(self, code):
2869         if self.type.is_error: return
2870         kwargs_call_function = "PyEval_CallObjectWithKeywords"
2871         if self.keyword_args and self.starstar_arg:
2872             code.put_error_if_neg(self.pos, 
2873                 "PyDict_Update(%s, %s)" % (
2874                     self.keyword_args.py_result(), 
2875                     self.starstar_arg.py_result()))
2876             keyword_code = self.keyword_args.py_result()
2877         elif self.keyword_args:
2878             keyword_code = self.keyword_args.py_result()
2879         elif self.starstar_arg:
2880             keyword_code = self.starstar_arg.py_result()
2881             if self.starstar_arg.type is not Builtin.dict_type:
2882                 # CPython supports calling functions with non-dicts, so do we
2883                 code.globalstate.use_utility_code(kwargs_call_utility_code)
2884                 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
2885         else:
2886             keyword_code = None
2887         if not keyword_code:
2888             call_code = "PyObject_Call(%s, %s, NULL)" % (
2889                 self.function.py_result(),
2890                 self.positional_args.py_result())
2891         else:
2892             call_code = "%s(%s, %s, %s)" % (
2893                 kwargs_call_function,
2894                 self.function.py_result(),
2895                 self.positional_args.py_result(),
2896                 keyword_code)
2897         code.putln(
2898             "%s = %s; %s" % (
2899                 self.result(),
2900                 call_code,
2901                 code.error_goto_if_null(self.result(), self.pos)))
2902         code.put_gotref(self.py_result())
2903
2904
2905 class AsTupleNode(ExprNode):
2906     #  Convert argument to tuple. Used for normalising
2907     #  the * argument of a function call.
2908     #
2909     #  arg    ExprNode
2910     
2911     subexprs = ['arg']
2912
2913     def calculate_constant_result(self):
2914         self.constant_result = tuple(self.base.constant_result)
2915     
2916     def compile_time_value(self, denv):
2917         arg = self.arg.compile_time_value(denv)
2918         try:
2919             return tuple(arg)
2920         except Exception, e:
2921             self.compile_time_value_error(e)
2922
2923     def analyse_types(self, env):
2924         self.arg.analyse_types(env)
2925         self.arg = self.arg.coerce_to_pyobject(env)
2926         self.type = tuple_type
2927         self.is_temp = 1
2928
2929     nogil_check = Node.gil_error
2930     gil_message = "Constructing Python tuple"
2931
2932     def generate_result_code(self, code):
2933         code.putln(
2934             "%s = PySequence_Tuple(%s); %s" % (
2935                 self.result(),
2936                 self.arg.py_result(),
2937                 code.error_goto_if_null(self.result(), self.pos)))
2938         code.put_gotref(self.py_result())
2939     
2940
2941 class AttributeNode(ExprNode):
2942     #  obj.attribute
2943     #
2944     #  obj          ExprNode
2945     #  attribute    string
2946     #  needs_none_check boolean        Used if obj is an extension type.
2947     #                                  If set to True, it is known that the type is not None.
2948     #
2949     #  Used internally:
2950     #
2951     #  is_py_attr           boolean   Is a Python getattr operation
2952     #  member               string    C name of struct member
2953     #  is_called            boolean   Function call is being done on result
2954     #  entry                Entry     Symbol table entry of attribute
2955     
2956     is_attribute = 1
2957     subexprs = ['obj']
2958     
2959     type = PyrexTypes.error_type
2960     entry = None
2961     is_called = 0
2962     needs_none_check = True
2963
2964     def as_cython_attribute(self):
2965         if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
2966             return self.attribute
2967         cy = self.obj.as_cython_attribute()
2968         if cy:
2969             return "%s.%s" % (cy, self.attribute)
2970
2971     def coerce_to(self, dst_type, env):
2972         #  If coercing to a generic pyobject and this is a cpdef function
2973         #  we can create the corresponding attribute
2974         if dst_type is py_object_type:
2975             entry = self.entry
2976             if entry and entry.is_cfunction and entry.as_variable:
2977                 # must be a cpdef function
2978                 self.is_temp = 1
2979                 self.entry = entry.as_variable
2980                 self.analyse_as_python_attribute(env) 
2981                 return self
2982         return ExprNode.coerce_to(self, dst_type, env)
2983
2984     def calculate_constant_result(self):
2985         attr = self.attribute
2986         if attr.startswith("__") and attr.endswith("__"):
2987             return
2988         self.constant_result = getattr(self.obj.constant_result, attr)
2989
2990     def compile_time_value(self, denv):
2991         attr = self.attribute
2992         if attr.startswith("__") and attr.endswith("__"):
2993             error(self.pos,
2994                   "Invalid attribute name '%s' in compile-time expression" % attr)
2995             return None
2996         obj = self.obj.compile_time_value(denv)
2997         try:
2998             return getattr(obj, attr)
2999         except Exception, e:
3000             self.compile_time_value_error(e)
3001     
3002     def type_dependencies(self, env):
3003         return self.obj.type_dependencies(env)
3004     
3005     def infer_type(self, env):
3006         if self.analyse_as_cimported_attribute(env, 0):
3007             return self.entry.type
3008         elif self.analyse_as_unbound_cmethod(env):
3009             return self.entry.type
3010         else:
3011             self.analyse_attribute(env, obj_type = self.obj.infer_type(env))
3012             return self.type
3013
3014     def analyse_target_declaration(self, env):
3015         pass
3016     
3017     def analyse_target_types(self, env):
3018         self.analyse_types(env, target = 1)
3019     
3020     def analyse_types(self, env, target = 0):
3021         if self.analyse_as_cimported_attribute(env, target):
3022             return
3023         if not target and self.analyse_as_unbound_cmethod(env):
3024             return
3025         self.analyse_as_ordinary_attribute(env, target)
3026     
3027     def analyse_as_cimported_attribute(self, env, target):
3028         # Try to interpret this as a reference to an imported
3029         # C const, type, var or function. If successful, mutates
3030         # this node into a NameNode and returns 1, otherwise
3031         # returns 0.
3032         module_scope = self.obj.analyse_as_module(env)
3033         if module_scope:
3034             entry = module_scope.lookup_here(self.attribute)
3035             if entry and (
3036                 entry.is_cglobal or entry.is_cfunction
3037                 or entry.is_type or entry.is_const):
3038                     self.mutate_into_name_node(env, entry, target)
3039                     return 1
3040         return 0
3041     
3042     def analyse_as_unbound_cmethod(self, env):
3043         # Try to interpret this as a reference to an unbound
3044         # C method of an extension type. If successful, mutates
3045         # this node into a NameNode and returns 1, otherwise
3046         # returns 0.
3047         type = self.obj.analyse_as_extension_type(env)
3048         if type:
3049             entry = type.scope.lookup_here(self.attribute)
3050             if entry and entry.is_cmethod:
3051                 # Create a temporary entry describing the C method
3052                 # as an ordinary function.
3053                 ubcm_entry = Symtab.Entry(entry.name,
3054                     "%s->%s" % (type.vtabptr_cname, entry.cname),
3055                     entry.type)
3056                 ubcm_entry.is_cfunction = 1
3057                 ubcm_entry.func_cname = entry.func_cname
3058                 ubcm_entry.is_unbound_cmethod = 1
3059                 self.mutate_into_name_node(env, ubcm_entry, None)
3060                 return 1
3061         return 0
3062         
3063     def analyse_as_type(self, env):
3064         module_scope = self.obj.analyse_as_module(env)
3065         if module_scope:
3066             return module_scope.lookup_type(self.attribute)
3067         if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3068             base_type = self.obj.analyse_as_type(env)
3069             if base_type and hasattr(base_type, 'scope'):
3070                 return base_type.scope.lookup_type(self.attribute)
3071         return None
3072     
3073     def analyse_as_extension_type(self, env):
3074         # Try to interpret this as a reference to an extension type
3075         # in a cimported module. Returns the extension type, or None.
3076         module_scope = self.obj.analyse_as_module(env)
3077         if module_scope:
3078             entry = module_scope.lookup_here(self.attribute)
3079             if entry and entry.is_type and entry.type.is_extension_type:
3080                 return entry.type
3081         return None
3082     
3083     def analyse_as_module(self, env):
3084         # Try to interpret this as a reference to a cimported module
3085         # in another cimported module. Returns the module scope, or None.
3086         module_scope = self.obj.analyse_as_module(env)
3087         if module_scope:
3088             entry = module_scope.lookup_here(self.attribute)
3089             if entry and entry.as_module:
3090                 return entry.as_module
3091         return None
3092                 
3093     def mutate_into_name_node(self, env, entry, target):
3094         # Mutate this node into a NameNode and complete the
3095         # analyse_types phase.
3096         self.__class__ = NameNode
3097         self.name = self.attribute
3098         self.entry = entry
3099         del self.obj
3100         del self.attribute
3101         if target:
3102             NameNode.analyse_target_types(self, env)
3103         else:
3104             NameNode.analyse_rvalue_entry(self, env)
3105     
3106     def analyse_as_ordinary_attribute(self, env, target):
3107         self.obj.analyse_types(env)
3108         self.analyse_attribute(env)
3109         if self.entry and self.entry.is_cmethod and not self.is_called:
3110 #            error(self.pos, "C method can only be called")
3111             pass
3112         ## Reference to C array turns into pointer to first element.
3113         #while self.type.is_array:
3114         #    self.type = self.type.element_ptr_type()
3115         if self.is_py_attr:
3116             if not target:
3117                 self.is_temp = 1
3118                 self.result_ctype = py_object_type
3119     
3120     def analyse_attribute(self, env, obj_type = None):
3121         # Look up attribute and set self.type and self.member.
3122         self.is_py_attr = 0
3123         self.member = self.attribute
3124         if obj_type is None:
3125             if self.obj.type.is_string:
3126                 self.obj = self.obj.coerce_to_pyobject(env)
3127             obj_type = self.obj.type
3128         else:
3129             if obj_type.is_string:
3130                 obj_type = py_object_type
3131         if obj_type.is_ptr or obj_type.is_array:
3132             obj_type = obj_type.base_type
3133             self.op = "->"
3134         elif obj_type.is_extension_type:
3135             self.op = "->"
3136         else:
3137             self.op = "."
3138         if obj_type.has_attributes:
3139             entry = None
3140             if obj_type.attributes_known():
3141                 entry = obj_type.scope.lookup_here(self.attribute)
3142                 if entry and entry.is_member:
3143                     entry = None
3144             else:
3145                 error(self.pos, 
3146                     "Cannot select attribute of incomplete type '%s'" 
3147                     % obj_type)
3148                 self.type = PyrexTypes.error_type
3149                 return
3150             self.entry = entry
3151             if entry:
3152                 if obj_type.is_extension_type and entry.name == "__weakref__":
3153                     error(self.pos, "Illegal use of special attribute __weakref__")
3154                 # methods need the normal attribute lookup
3155                 # because they do not have struct entries
3156                 if entry.is_variable or entry.is_cmethod:
3157                     self.type = entry.type
3158                     self.member = entry.cname
3159                     return
3160                 else:
3161                     # If it's not a variable or C method, it must be a Python
3162                     # method of an extension type, so we treat it like a Python
3163                     # attribute.
3164                     pass
3165         # If we get here, the base object is not a struct/union/extension 
3166         # type, or it is an extension type and the attribute is either not
3167         # declared or is declared as a Python method. Treat it as a Python
3168         # attribute reference.
3169         self.analyse_as_python_attribute(env, obj_type)
3170
3171     def analyse_as_python_attribute(self, env, obj_type = None):
3172         if obj_type is None:
3173             obj_type = self.obj.type
3174         self.member = self.attribute
3175         self.type = py_object_type
3176         self.is_py_attr = 1
3177         if not obj_type.is_pyobject and not obj_type.is_error:
3178             if obj_type.can_coerce_to_pyobject(env):
3179                 self.obj = self.obj.coerce_to_pyobject(env)
3180             else:
3181                 error(self.pos,
3182                       "Object of type '%s' has no attribute '%s'" %
3183                       (obj_type, self.attribute))
3184
3185     def nogil_check(self, env):
3186         if self.is_py_attr:
3187             self.gil_error()
3188
3189     gil_message = "Accessing Python attribute"
3190
3191     def is_simple(self):
3192         if self.obj:
3193             return self.result_in_temp() or self.obj.is_simple()
3194         else:
3195             return NameNode.is_simple(self)
3196
3197     def is_lvalue(self):
3198         if self.obj:
3199             return 1
3200         else:
3201             return NameNode.is_lvalue(self)
3202     
3203     def is_ephemeral(self):
3204         if self.obj:
3205             return self.obj.is_ephemeral()
3206         else:
3207             return NameNode.is_ephemeral(self)
3208     
3209     def calculate_result_code(self):
3210         #print "AttributeNode.calculate_result_code:", self.member ###
3211         #print "...obj node =", self.obj, "code", self.obj.result() ###
3212         #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3213         obj = self.obj
3214         obj_code = obj.result_as(obj.type)
3215         #print "...obj_code =", obj_code ###
3216         if self.entry and self.entry.is_cmethod:
3217             if obj.type.is_extension_type:
3218                 return "((struct %s *)%s%s%s)->%s" % (
3219                     obj.type.vtabstruct_cname, obj_code, self.op, 
3220                     obj.type.vtabslot_cname, self.member)
3221             else:
3222                 return self.member
3223         elif obj.type.is_complex:
3224             return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3225         else:
3226             return "%s%s%s" % (obj_code, self.op, self.member)
3227     
3228     def generate_result_code(self, code):
3229         interned_attr_cname = code.intern_identifier(self.attribute)
3230         if self.is_py_attr:
3231             code.putln(
3232                 '%s = PyObject_GetAttr(%s, %s); %s' % (
3233                     self.result(),
3234                     self.obj.py_result(),
3235                     interned_attr_cname,
3236                     code.error_goto_if_null(self.result(), self.pos)))
3237             code.put_gotref(self.py_result())
3238         else:
3239             # result_code contains what is needed, but we may need to insert
3240             # a check and raise an exception
3241             if (self.obj.type.is_extension_type
3242                   and self.needs_none_check
3243                   and code.globalstate.directives['nonecheck']):
3244                 self.put_nonecheck(code)
3245     
3246     def generate_assignment_code(self, rhs, code):
3247         interned_attr_cname = code.intern_identifier(self.attribute)
3248         self.obj.generate_evaluation_code(code)
3249         if self.is_py_attr:
3250             code.put_error_if_neg(self.pos, 
3251                 'PyObject_SetAttr(%s, %s, %s)' % (
3252                     self.obj.py_result(),
3253                     interned_attr_cname,
3254                     rhs.py_result()))
3255             rhs.generate_disposal_code(code)
3256             rhs.free_temps(code)
3257         elif self.obj.type.is_complex:
3258             code.putln("__Pyx_SET_C%s(%s, %s);" % (
3259                 self.member.upper(),
3260                 self.obj.result_as(self.obj.type),
3261                 rhs.result_as(self.ctype())))
3262         else:
3263             if (self.obj.type.is_extension_type
3264                   and self.needs_none_check
3265                   and code.globalstate.directives['nonecheck']):
3266                 self.put_nonecheck(code)
3267
3268             select_code = self.result()
3269             if self.type.is_pyobject and self.use_managed_ref:
3270                 rhs.make_owned_reference(code)
3271                 code.put_giveref(rhs.py_result())
3272                 code.put_gotref(select_code)
3273                 code.put_decref(select_code, self.ctype())
3274             code.putln(
3275                 "%s = %s;" % (
3276                     select_code,
3277                     rhs.result_as(self.ctype())))
3278                     #rhs.result()))
3279             rhs.generate_post_assignment_code(code)
3280             rhs.free_temps(code)
3281         self.obj.generate_disposal_code(code)
3282         self.obj.free_temps(code)
3283     
3284     def generate_deletion_code(self, code):
3285         interned_attr_cname = code.intern_identifier(self.attribute)
3286         self.obj.generate_evaluation_code(code)
3287         if self.is_py_attr:
3288             code.put_error_if_neg(self.pos,
3289                 'PyObject_DelAttr(%s, %s)' % (
3290                     self.obj.py_result(),
3291                     interned_attr_cname))
3292         else:
3293             error(self.pos, "Cannot delete C attribute of extension type")
3294         self.obj.generate_disposal_code(code)
3295         self.obj.free_temps(code)
3296         
3297     def annotate(self, code):
3298         if self.is_py_attr:
3299             code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3300         else:
3301             code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3302
3303     def put_nonecheck(self, code):
3304         code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3305         code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3306         code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3307         code.putln(code.error_goto(self.pos))
3308         code.putln("}")
3309
3310
3311 #-------------------------------------------------------------------
3312 #
3313 #  Constructor nodes
3314 #
3315 #-------------------------------------------------------------------
3316
3317 class StarredTargetNode(ExprNode):
3318     #  A starred expression like "*a"
3319     #
3320     #  This is only allowed in sequence assignment targets such as
3321     #
3322     #      a, *b = (1,2,3,4)    =>     a = 1 ; b = [2,3,4]
3323     #
3324     #  and will be removed during type analysis (or generate an error
3325     #  if it's found at unexpected places).
3326     #
3327     #  target          ExprNode
3328
3329     subexprs = ['target']
3330     is_starred = 1
3331     type = py_object_type
3332     is_temp = 1
3333
3334     def __init__(self, pos, target):
3335         self.pos = pos
3336         self.target = target
3337
3338     def analyse_declarations(self, env):
3339         error(self.pos, "can use starred expression only as assignment target")
3340         self.target.analyse_declarations(env)
3341
3342     def analyse_types(self, env):
3343         error(self.pos, "can use starred expression only as assignment target")
3344         self.target.analyse_types(env)
3345         self.type = self.target.type
3346
3347     def analyse_target_declaration(self, env):
3348         self.target.analyse_target_declaration(env)
3349
3350     def analyse_target_types(self, env):
3351         self.target.analyse_target_types(env)
3352         self.type = self.target.type
3353
3354     def calculate_result_code(self):
3355         return ""
3356
3357     def generate_result_code(self, code):
3358         pass
3359
3360
3361 class SequenceNode(ExprNode):
3362     #  Base class for list and tuple constructor nodes.
3363     #  Contains common code for performing sequence unpacking.
3364     #
3365     #  args                    [ExprNode]
3366     #  iterator                ExprNode
3367     #  unpacked_items          [ExprNode] or None
3368     #  coerced_unpacked_items  [ExprNode] or None
3369     
3370     subexprs = ['args']
3371     
3372     is_sequence_constructor = 1
3373     unpacked_items = None
3374
3375     def compile_time_value_list(self, denv):
3376         return [arg.compile_time_value(denv) for arg in self.args]
3377
3378     def replace_starred_target_node(self):
3379         # replace a starred node in the targets by the contained expression
3380         self.starred_assignment = False
3381         args = []
3382         for arg in self.args:
3383             if arg.is_starred:
3384                 if self.starred_assignment:
3385                     error(arg.pos, "more than 1 starred expression in assignment")
3386                 self.starred_assignment = True
3387                 arg = arg.target
3388                 arg.is_starred = True
3389             args.append(arg)
3390         self.args = args
3391
3392     def analyse_target_declaration(self, env):
3393         self.replace_starred_target_node()
3394         for arg in self.args:
3395             arg.analyse_target_declaration(env)
3396
3397     def analyse_types(self, env, skip_children=False):
3398         for i in range(len(self.args)):
3399             arg = self.args[i]
3400             if not skip_children: arg.analyse_types(env)
3401             self.args[i] = arg.coerce_to_pyobject(env)
3402         self.type = py_object_type
3403         self.is_temp = 1
3404
3405     def analyse_target_types(self, env):
3406         self.iterator = PyTempNode(self.pos, env)
3407         self.unpacked_items = []
3408         self.coerced_unpacked_items = []
3409         for arg in self.args:
3410             arg.analyse_target_types(env)
3411             if arg.is_starred:
3412                 if not arg.type.assignable_from(Builtin.list_type):
3413                     error(arg.pos,
3414                           "starred target must have Python object (list) type")
3415                 if arg.type is py_object_type:
3416                     arg.type = Builtin.list_type
3417             unpacked_item = PyTempNode(self.pos, env)
3418             coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3419             self.unpacked_items.append(unpacked_item)
3420             self.coerced_unpacked_items.append(coerced_unpacked_item)
3421         self.type = py_object_type
3422
3423     def generate_result_code(self, code):
3424         self.generate_operation_code(code)
3425     
3426     def generate_assignment_code(self, rhs, code):
3427         if self.starred_assignment:
3428             self.generate_starred_assignment_code(rhs, code)
3429         else:
3430             self.generate_parallel_assignment_code(rhs, code)
3431
3432         for item in self.unpacked_items:
3433             item.release(code)
3434         rhs.free_temps(code)
3435
3436     def generate_parallel_assignment_code(self, rhs, code):
3437         # Need to work around the fact that generate_evaluation_code
3438         # allocates the temps in a rather hacky way -- the assignment
3439         # is evaluated twice, within each if-block.
3440
3441         code.globalstate.use_utility_code(unpacking_utility_code)
3442
3443         if rhs.type is tuple_type:
3444             tuple_check = "likely(%s != Py_None)"
3445         else:
3446             tuple_check = "PyTuple_CheckExact(%s)"
3447         code.putln(
3448             "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3449                 tuple_check % rhs.py_result(), 
3450                 rhs.py_result(), 
3451                 len(self.args)))
3452         code.putln("PyObject* tuple = %s;" % rhs.py_result())
3453         for item in self.unpacked_items:
3454             item.allocate(code)
3455         for i in range(len(self.args)):
3456             item = self.unpacked_items[i]
3457             code.put(
3458                 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3459                     item.result(),
3460                     i))
3461             code.put_incref(item.result(), item.ctype())
3462             value_node = self.coerced_unpacked_items[i]
3463             value_node.generate_evaluation_code(code)
3464         rhs.generate_disposal_code(code)
3465
3466         for i in range(len(self.args)):
3467             self.args[i].generate_assignment_code(
3468                 self.coerced_unpacked_items[i], code)
3469                  
3470         code.putln("} else {")
3471
3472         if rhs.type is tuple_type:
3473             code.globalstate.use_utility_code(tuple_unpacking_error_code)
3474             code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3475                         rhs.py_result(), len(self.args)))
3476             code.putln(code.error_goto(self.pos))
3477         else:
3478             self.iterator.allocate(code)
3479             code.putln(
3480                 "%s = PyObject_GetIter(%s); %s" % (
3481                     self.iterator.result(),
3482                     rhs.py_result(),
3483                     code.error_goto_if_null(self.iterator.result(), self.pos)))
3484             code.put_gotref(self.iterator.py_result())
3485             rhs.generate_disposal_code(code)
3486             for i in range(len(self.args)):
3487                 item = self.unpacked_items[i]
3488                 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3489                     self.iterator.py_result(), i)
3490                 code.putln(
3491                     "%s = %s; %s" % (
3492                         item.result(),
3493                         typecast(item.ctype(), py_object_type, unpack_code),
3494                         code.error_goto_if_null(item.result(), self.pos)))
3495                 code.put_gotref(item.py_result())
3496                 value_node = self.coerced_unpacked_items[i]
3497                 value_node.generate_evaluation_code(code)
3498             code.put_error_if_neg(self.pos, 
3499                 "__Pyx_EndUnpack(%s)" % (
3500                     self.iterator.py_result()))
3501             if debug_disposal_code:
3502                 print("UnpackNode.generate_assignment_code:")
3503                 print("...generating disposal code for %s" % self.iterator)
3504             self.iterator.generate_disposal_code(code)
3505             self.iterator.free_temps(code)
3506             self.iterator.release(code)
3507
3508             for i in range(len(self.args)):
3509                 self.args[i].generate_assignment_code(
3510                     self.coerced_unpacked_items[i], code)
3511
3512         code.putln("}")
3513
3514     def generate_starred_assignment_code(self, rhs, code):
3515         code.globalstate.use_utility_code(unpacking_utility_code)
3516
3517         for i, arg in enumerate(self.args):
3518             if arg.is_starred:
3519                 starred_target = self.unpacked_items[i]
3520                 fixed_args_left  = self.args[:i]
3521                 fixed_args_right = self.args[i+1:]
3522                 break
3523
3524         self.iterator.allocate(code)
3525         code.putln(
3526             "%s = PyObject_GetIter(%s); %s" % (
3527                 self.iterator.result(),
3528                 rhs.py_result(),
3529                 code.error_goto_if_null(self.iterator.result(), self.pos)))
3530         code.put_gotref(self.iterator.py_result())
3531         rhs.generate_disposal_code(code)
3532
3533         for item in self.unpacked_items:
3534             item.allocate(code)
3535         for i in range(len(fixed_args_left)):
3536             item = self.unpacked_items[i]
3537             unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3538                 self.iterator.py_result(), i)
3539             code.putln(
3540                 "%s = %s; %s" % (
3541                     item.result(),
3542                     typecast(item.ctype(), py_object_type, unpack_code),
3543                     code.error_goto_if_null(item.result(), self.pos)))
3544             code.put_gotref(item.py_result())
3545             value_node = self.coerced_unpacked_items[i]
3546             value_node.generate_evaluation_code(code)
3547
3548         target_list = starred_target.result()
3549         code.putln("%s = PySequence_List(%s); %s" % (
3550             target_list, self.iterator.py_result(),
3551             code.error_goto_if_null(target_list, self.pos)))
3552         code.put_gotref(target_list)
3553         if fixed_args_right:
3554             code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3555             unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3556             code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3557                 (target_list, len(unpacked_right_args))))
3558             code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3559                      len(fixed_args_left), target_list,
3560                      code.error_goto(self.pos)))
3561             code.putln('}')
3562             for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3563                                                        self.coerced_unpacked_items[::-1])):
3564                 code.putln(
3565                     "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3566                         arg.py_result(),
3567                         target_list, target_list))
3568                 # resize the list the hard way
3569                 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
3570                 code.put_gotref(arg.py_result())
3571                 coerced_arg.generate_evaluation_code(code)
3572
3573         self.iterator.generate_disposal_code(code)
3574         self.iterator.free_temps(code)
3575         self.iterator.release(code)
3576
3577         for i in range(len(self.args)):
3578             self.args[i].generate_assignment_code(
3579                 self.coerced_unpacked_items[i], code)
3580
3581     def annotate(self, code):
3582         for arg in self.args:
3583             arg.annotate(code)
3584         if self.unpacked_items:
3585             for arg in self.unpacked_items:
3586                 arg.annotate(code)
3587             for arg in self.coerced_unpacked_items:
3588                 arg.annotate(code)
3589
3590
3591 class TupleNode(SequenceNode):
3592     #  Tuple constructor.
3593     
3594     type = tuple_type
3595
3596     gil_message = "Constructing Python tuple"
3597
3598     def analyse_types(self, env, skip_children=False):
3599         if len(self.args) == 0:
3600             self.is_temp = 0
3601             self.is_literal = 1
3602         else:
3603             SequenceNode.analyse_types(self, env, skip_children)
3604             
3605     def calculate_result_code(self):
3606         if len(self.args) > 0:
3607             error(self.pos, "Positive length tuples must be constructed.")
3608         else:
3609             return Naming.empty_tuple
3610
3611     def calculate_constant_result(self):
3612         self.constant_result = tuple([
3613                 arg.constant_result for arg in self.args])
3614
3615     def compile_time_value(self, denv):
3616         values = self.compile_time_value_list(denv)
3617         try:
3618             return tuple(values)
3619         except Exception, e:
3620             self.compile_time_value_error(e)
3621     
3622     def generate_operation_code(self, code):
3623         if len(self.args) == 0:
3624             # result_code is Naming.empty_tuple
3625             return
3626         code.putln(
3627             "%s = PyTuple_New(%s); %s" % (
3628                 self.result(),
3629                 len(self.args),
3630                 code.error_goto_if_null(self.result(), self.pos)))
3631         code.put_gotref(self.py_result())
3632         for i in range(len(self.args)):
3633             arg = self.args[i]
3634             if not arg.result_in_temp():
3635                 code.put_incref(arg.result(), arg.ctype())
3636             code.putln(
3637                 "PyTuple_SET_ITEM(%s, %s, %s);" % (
3638                     self.result(),
3639                     i,
3640                     arg.py_result()))
3641             code.put_giveref(arg.py_result())
3642     
3643     def generate_subexpr_disposal_code(self, code):
3644         # We call generate_post_assignment_code here instead
3645         # of generate_disposal_code, because values were stored
3646         # in the tuple using a reference-stealing operation.
3647         for arg in self.args:
3648             arg.generate_post_assignment_code(code)
3649             # Should NOT call free_temps -- this is invoked by the default
3650             # generate_evaluation_code which will do that.
3651
3652
3653 class ListNode(SequenceNode):
3654     #  List constructor.
3655     
3656     # obj_conversion_errors    [PyrexError]   used internally
3657     # orignial_args            [ExprNode]     used internally
3658
3659     obj_conversion_errors = []
3660
3661     gil_message = "Constructing Python list"
3662     
3663     def type_dependencies(self, env):
3664         return ()
3665     
3666     def infer_type(self, env):
3667         # TOOD: Infer non-object list arrays.
3668         return list_type
3669
3670     def analyse_expressions(self, env):
3671         SequenceNode.analyse_expressions(self, env)
3672         self.coerce_to_pyobject(env)
3673
3674     def analyse_types(self, env):
3675         hold_errors()
3676         self.original_args = list(self.args)
3677         SequenceNode.analyse_types(self, env)
3678         self.type = list_type
3679         self.obj_conversion_errors = held_errors()
3680         release_errors(ignore=True)
3681         
3682     def coerce_to(self, dst_type, env):
3683         if dst_type.is_pyobject:
3684             for err in self.obj_conversion_errors:
3685                 report_error(err)
3686             self.obj_conversion_errors = []
3687             if not self.type.subtype_of(dst_type):
3688                 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3689         elif dst_type.is_ptr:
3690             base_type = dst_type.base_type
3691             self.type = PyrexTypes.CArrayType(base_type, len(self.args))
3692             for i in range(len(self.original_args)):
3693                 arg = self.args[i]
3694                 if isinstance(arg, CoerceToPyTypeNode):
3695                     arg = arg.arg
3696                 self.args[i] = arg.coerce_to(base_type, env)
3697         elif dst_type.is_struct:
3698             if len(self.args) > len(dst_type.scope.var_entries):
3699                 error(self.pos, "Too may members for '%s'" % dst_type)
3700             else:
3701                 if len(self.args) < len(dst_type.scope.var_entries):
3702                     warning(self.pos, "Too few members for '%s'" % dst_type, 1)
3703                 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
3704                     if isinstance(arg, CoerceToPyTypeNode):
3705                         arg = arg.arg
3706                     self.args[i] = arg.coerce_to(member.type, env)
3707             self.type = dst_type
3708         else:
3709             self.type = error_type
3710             error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3711         return self
3712         
3713     def release_temp(self, env):
3714         if self.type.is_array:
3715             # To be valid C++, we must allocate the memory on the stack 
3716             # manually and be sure not to reuse it for something else. 
3717             pass
3718         else:
3719             SequenceNode.release_temp(self, env)
3720
3721     def calculate_constant_result(self):
3722         self.constant_result = [
3723             arg.constant_result for arg in self.args]
3724
3725     def compile_time_value(self, denv):
3726         return self.compile_time_value_list(denv)
3727
3728     def generate_operation_code(self, code):
3729         if self.type.is_pyobject:
3730             for err in self.obj_conversion_errors:
3731                 report_error(err)
3732             code.putln("%s = PyList_New(%s); %s" %
3733                 (self.result(),
3734                 len(self.args),
3735                 code.error_goto_if_null(self.result(), self.pos)))
3736             code.put_gotref(self.py_result())
3737             for i in range(len(self.args)):
3738                 arg = self.args[i]
3739                 #if not arg.is_temp:
3740                 if not arg.result_in_temp():
3741                     code.put_incref(arg.result(), arg.ctype())
3742                 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
3743                     (self.result(),
3744                     i,
3745                     arg.py_result()))
3746                 code.put_giveref(arg.py_result())
3747         elif self.type.is_array:
3748             for i, arg in enumerate(self.args):
3749                 code.putln("%s[%s] = %s;" % (
3750                                 self.result(),
3751                                 i,
3752                                 arg.result()))
3753         elif self.type.is_struct:
3754             for arg, member in zip(self.args, self.type.scope.var_entries):
3755                 code.putln("%s.%s = %s;" % (
3756                         self.result(),
3757                         member.cname,
3758                         arg.result()))
3759         else:
3760             raise InternalError("List type never specified")
3761
3762     def generate_subexpr_disposal_code(self, code):
3763         # We call generate_post_assignment_code here instead
3764         # of generate_disposal_code, because values were stored
3765         # in the list using a reference-stealing operation.
3766         for arg in self.args:
3767             arg.generate_post_assignment_code(code)
3768             # Should NOT call free_temps -- this is invoked by the default
3769             # generate_evaluation_code which will do that.
3770
3771
3772 class ComprehensionNode(ExprNode):
3773     subexprs = ["target"]
3774     child_attrs = ["loop", "append"]
3775
3776     def infer_type(self, env):
3777         return self.target.infer_type(env)
3778
3779     def analyse_declarations(self, env):
3780         self.append.target = self # this is used in the PyList_Append of the inner loop
3781         self.loop.analyse_declarations(env)
3782
3783     def analyse_types(self, env):
3784         self.target.analyse_expressions(env)
3785         self.type = self.target.type
3786         self.loop.analyse_expressions(env)
3787
3788     def calculate_result_code(self):
3789         return self.target.result()
3790     
3791     def generate_result_code(self, code):
3792         self.generate_operation_code(code)
3793
3794     def generate_operation_code(self, code):
3795         self.loop.generate_execution_code(code)
3796
3797     def annotate(self, code):
3798         self.loop.annotate(code)
3799
3800
3801 class ComprehensionAppendNode(ExprNode):
3802     # Need to be careful to avoid infinite recursion:
3803     # target must not be in child_attrs/subexprs
3804     subexprs = ['expr']
3805
3806     type = PyrexTypes.c_int_type
3807     
3808     def analyse_types(self, env):
3809         self.expr.analyse_types(env)
3810         if not self.expr.type.is_pyobject:
3811             self.expr = self.expr.coerce_to_pyobject(env)
3812         self.is_temp = 1
3813
3814     def generate_result_code(self, code):
3815         if self.target.type is list_type:
3816             function = "PyList_Append"
3817         elif self.target.type is set_type:
3818             function = "PySet_Add"
3819         else:
3820             raise InternalError(
3821                 "Invalid type for comprehension node: %s" % self.target.type)
3822             
3823         code.putln("%s = %s(%s, (PyObject*)%s); %s" %
3824             (self.result(),
3825              function,
3826              self.target.result(),
3827              self.expr.result(),
3828              code.error_goto_if(self.result(), self.pos)))
3829
3830 class DictComprehensionAppendNode(ComprehensionAppendNode):
3831     subexprs = ['key_expr', 'value_expr']
3832
3833     def analyse_types(self, env):
3834         self.key_expr.analyse_types(env)
3835         if not self.key_expr.type.is_pyobject:
3836             self.key_expr = self.key_expr.coerce_to_pyobject(env)
3837         self.value_expr.analyse_types(env)
3838         if not self.value_expr.type.is_pyobject:
3839             self.value_expr = self.value_expr.coerce_to_pyobject(env)
3840         self.is_temp = 1
3841
3842     def generate_result_code(self, code):
3843         code.putln("%s = PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s); %s" %
3844             (self.result(),
3845              self.target.result(),
3846              self.key_expr.result(),
3847              self.value_expr.result(),
3848              code.error_goto_if(self.result(), self.pos)))
3849
3850
3851 class SetNode(ExprNode):
3852     #  Set constructor.
3853
3854     type = set_type
3855
3856     subexprs = ['args']
3857
3858     gil_message = "Constructing Python set"
3859     
3860     def analyse_types(self, env):
3861         for i in range(len(self.args)):
3862             arg = self.args[i]
3863             arg.analyse_types(env)
3864             self.args[i] = arg.coerce_to_pyobject(env)
3865         self.type = set_type
3866         self.is_temp = 1
3867
3868     def calculate_constant_result(self):
3869         self.constant_result = set([
3870                 arg.constant_result for arg in self.args])
3871
3872     def compile_time_value(self, denv):
3873         values = [arg.compile_time_value(denv) for arg in self.args]
3874         try:
3875             return set(values)
3876         except Exception, e:
3877             self.compile_time_value_error(e)
3878
3879     def generate_evaluation_code(self, code):
3880         code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
3881         self.allocate_temp_result(code)
3882         code.putln(
3883             "%s = PySet_New(0); %s" % (
3884                 self.result(),
3885                 code.error_goto_if_null(self.result(), self.pos)))
3886         code.put_gotref(self.py_result())
3887         for arg in self.args:
3888             arg.generate_evaluation_code(code)
3889             code.putln(
3890                 code.error_goto_if_neg(
3891                     "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
3892                     self.pos))
3893             arg.generate_disposal_code(code)
3894             arg.free_temps(code)
3895
3896
3897 class DictNode(ExprNode):
3898     #  Dictionary constructor.
3899     #
3900     #  key_value_pairs  [DictItemNode]
3901     #
3902     # obj_conversion_errors    [PyrexError]   used internally
3903     
3904     subexprs = ['key_value_pairs']
3905     is_temp = 1
3906     type = dict_type
3907
3908     obj_conversion_errors = []
3909
3910     def calculate_constant_result(self):
3911         self.constant_result = dict([
3912                 item.constant_result for item in self.key_value_pairs])
3913     
3914     def compile_time_value(self, denv):
3915         pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
3916             for item in self.key_value_pairs]
3917         try:
3918             return dict(pairs)
3919         except Exception, e:
3920             self.compile_time_value_error(e)
3921     
3922     def type_dependencies(self, env):
3923         return ()
3924     
3925     def infer_type(self, env):
3926         # TOOD: Infer struct constructors.
3927         return dict_type
3928
3929     def analyse_types(self, env):
3930         hold_errors()
3931         for item in self.key_value_pairs:
3932             item.analyse_types(env)
3933         self.obj_conversion_errors = held_errors()
3934         release_errors(ignore=True)
3935         
3936     def coerce_to(self, dst_type, env):
3937         if dst_type.is_pyobject:
3938             self.release_errors()
3939             if not self.type.subtype_of(dst_type):
3940                 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
3941         elif dst_type.is_struct_or_union:
3942             self.type = dst_type
3943             if not dst_type.is_struct and len(self.key_value_pairs) != 1:
3944                 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
3945             elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
3946                 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
3947             for item in self.key_value_pairs:
3948                 if isinstance(item.key, CoerceToPyTypeNode):
3949                     item.key = item.key.arg
3950                 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
3951                     error(item.key.pos, "Invalid struct field identifier")
3952                     item.key = StringNode(item.key.pos, value="<error>")
3953                 else:
3954                     key = str(item.key.value) # converts string literals to unicode in Py3
3955                     member = dst_type.scope.lookup_here(key)
3956                     if not member:
3957                         error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
3958                     else:
3959                         value = item.value
3960                         if isinstance(value, CoerceToPyTypeNode):
3961                             value = value.arg
3962                         item.value = value.coerce_to(member.type, env)
3963         else:
3964             self.type = error_type
3965             error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
3966         return self
3967     
3968     def release_errors(self):
3969         for err in self.obj_conversion_errors:
3970             report_error(err)
3971         self.obj_conversion_errors = []
3972
3973     gil_message = "Constructing Python dict"
3974
3975     def generate_evaluation_code(self, code):
3976         #  Custom method used here because key-value
3977         #  pairs are evaluated and used one at a time.
3978         code.mark_pos(self.pos)
3979         self.allocate_temp_result(code)
3980         if self.type.is_pyobject:
3981             self.release_errors()
3982             code.putln(
3983                 "%s = PyDict_New(); %s" % (
3984                     self.result(),
3985                     code.error_goto_if_null(self.result(), self.pos)))
3986             code.put_gotref(self.py_result())
3987         for item in self.key_value_pairs:
3988             item.generate_evaluation_code(code)
3989             if self.type.is_pyobject:
3990                 code.put_error_if_neg(self.pos, 
3991                     "PyDict_SetItem(%s, %s, %s)" % (
3992                         self.result(),
3993                         item.key.py_result(),
3994                         item.value.py_result()))
3995             else:
3996                 code.putln("%s.%s = %s;" % (
3997                         self.result(),
3998                         item.key.value,
3999                         item.value.result()))
4000             item.generate_disposal_code(code)
4001             item.free_temps(code)
4002             
4003     def annotate(self, code):
4004         for item in self.key_value_pairs:
4005             item.annotate(code)
4006             
4007 class DictItemNode(ExprNode):
4008     # Represents a single item in a DictNode
4009     #
4010     # key          ExprNode
4011     # value        ExprNode
4012     subexprs = ['key', 'value']
4013
4014     nogil_check = None # Parent DictNode takes care of it
4015
4016     def calculate_constant_result(self):
4017         self.constant_result = (
4018             self.key.constant_result, self.value.constant_result)
4019             
4020     def analyse_types(self, env):
4021         self.key.analyse_types(env)
4022         self.value.analyse_types(env)
4023         self.key = self.key.coerce_to_pyobject(env)
4024         self.value = self.value.coerce_to_pyobject(env)
4025         
4026     def generate_evaluation_code(self, code):
4027         self.key.generate_evaluation_code(code)
4028         self.value.generate_evaluation_code(code)
4029
4030     def generate_disposal_code(self, code):
4031         self.key.generate_disposal_code(code)
4032         self.value.generate_disposal_code(code)
4033
4034     def free_temps(self, code):
4035         self.key.free_temps(code)
4036         self.value.free_temps(code)
4037         
4038     def __iter__(self):
4039         return iter([self.key, self.value])
4040
4041
4042 class ClassNode(ExprNode):
4043     #  Helper class used in the implementation of Python
4044     #  class definitions. Constructs a class object given
4045     #  a name, tuple of bases and class dictionary.
4046     #
4047     #  name         EncodedString      Name of the class
4048     #  bases        ExprNode           Base class tuple
4049     #  dict         ExprNode           Class dict (not owned by this node)
4050     #  doc          ExprNode or None   Doc string
4051     #  module_name  string             Name of defining module
4052     
4053     subexprs = ['bases', 'doc']
4054
4055     def analyse_types(self, env):
4056         self.bases.analyse_types(env)
4057         if self.doc:
4058             self.doc.analyse_types(env)
4059             self.doc = self.doc.coerce_to_pyobject(env)
4060         self.module_name = env.global_scope().qualified_name
4061         self.type = py_object_type
4062         self.is_temp = 1
4063         env.use_utility_code(create_class_utility_code);
4064
4065     gil_message = "Constructing Python class"
4066
4067     def generate_result_code(self, code):
4068         cname = code.intern_identifier(self.name)
4069         if self.doc:
4070             code.put_error_if_neg(self.pos, 
4071                 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4072                     self.dict.py_result(),
4073                     self.doc.py_result()))
4074         code.putln(
4075             '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); %s' % (
4076                 self.result(),
4077                 self.bases.py_result(),
4078                 self.dict.py_result(),
4079                 cname,
4080                 self.module_name,
4081                 code.error_goto_if_null(self.result(), self.pos)))
4082         code.put_gotref(self.py_result())
4083
4084
4085 class UnboundMethodNode(ExprNode):
4086     #  Helper class used in the implementation of Python
4087     #  class definitions. Constructs an unbound method
4088     #  object from a class and a function.
4089     #
4090     #  function      ExprNode   Function object
4091     
4092     type = py_object_type
4093     is_temp = 1
4094     
4095     subexprs = ['function']
4096     
4097     def analyse_types(self, env):
4098         self.function.analyse_types(env)
4099
4100     gil_message = "Constructing an unbound method"
4101
4102     def generate_result_code(self, code):
4103         class_cname = code.pyclass_stack[-1].classobj.result()
4104         code.putln(
4105             "%s = PyMethod_New(%s, 0, %s); %s" % (
4106                 self.result(),
4107                 self.function.py_result(),
4108                 class_cname,
4109                 code.error_goto_if_null(self.result(), self.pos)))
4110         code.put_gotref(self.py_result())
4111
4112
4113 class PyCFunctionNode(AtomicExprNode):
4114     #  Helper class used in the implementation of Python
4115     #  class definitions. Constructs a PyCFunction object
4116     #  from a PyMethodDef struct.
4117     #
4118     #  pymethdef_cname   string   PyMethodDef structure
4119     
4120     type = py_object_type
4121     is_temp = 1
4122     
4123     def analyse_types(self, env):
4124         pass
4125     
4126     gil_message = "Constructing Python function"
4127
4128     def generate_result_code(self, code):
4129         code.putln(
4130             "%s = PyCFunction_New(&%s, 0); %s" % (
4131                 self.result(),
4132                 self.pymethdef_cname,
4133                 code.error_goto_if_null(self.result(), self.pos)))
4134         code.put_gotref(self.py_result())
4135
4136 #-------------------------------------------------------------------
4137 #
4138 #  Unary operator nodes
4139 #
4140 #-------------------------------------------------------------------
4141
4142 compile_time_unary_operators = {
4143     'not': operator.not_,
4144     '~': operator.inv,
4145     '-': operator.neg,
4146     '+': operator.pos,
4147 }
4148
4149 class UnopNode(ExprNode):
4150     #  operator     string
4151     #  operand      ExprNode
4152     #
4153     #  Processing during analyse_expressions phase:
4154     #
4155     #    analyse_c_operation
4156     #      Called when the operand is not a pyobject.
4157     #      - Check operand type and coerce if needed.
4158     #      - Determine result type and result code fragment.
4159     #      - Allocate temporary for result if needed.
4160     
4161     subexprs = ['operand']
4162     infix = True
4163
4164     def calculate_constant_result(self):
4165         func = compile_time_unary_operators[self.operator]
4166         self.constant_result = func(self.operand.constant_result)
4167     
4168     def compile_time_value(self, denv):
4169         func = compile_time_unary_operators.get(self.operator)
4170         if not func:
4171             error(self.pos,
4172                 "Unary '%s' not supported in compile-time expression"
4173                     % self.operator)
4174         operand = self.operand.compile_time_value(denv)
4175         try:
4176             return func(operand)
4177         except Exception, e:
4178             self.compile_time_value_error(e)
4179     
4180     def infer_type(self, env):
4181         return self.operand.infer_type(env)
4182
4183     def analyse_types(self, env):
4184         self.operand.analyse_types(env)
4185         if self.is_py_operation():
4186             self.coerce_operand_to_pyobject(env)
4187             self.type = py_object_type
4188             self.is_temp = 1
4189         elif self.is_cpp_operation():
4190             self.analyse_cpp_operation(env)
4191         else:
4192             self.analyse_c_operation(env)
4193     
4194     def check_const(self):
4195         return self.operand.check_const()
4196     
4197     def is_py_operation(self):
4198         return self.operand.type.is_pyobject
4199
4200     def nogil_check(self, env):
4201         if self.is_py_operation():
4202             self.gil_error()
4203
4204     def is_cpp_operation(self):
4205         type = self.operand.type
4206         return type.is_cpp_class
4207     
4208     def coerce_operand_to_pyobject(self, env):
4209         self.operand = self.operand.coerce_to_pyobject(env)
4210     
4211     def generate_result_code(self, code):
4212         if self.operand.type.is_pyobject:
4213             self.generate_py_operation_code(code)
4214     
4215     def generate_py_operation_code(self, code):
4216         function = self.py_operation_function()
4217         code.putln(
4218             "%s = %s(%s); %s" % (
4219                 self.result(), 
4220                 function, 
4221                 self.operand.py_result(),
4222                 code.error_goto_if_null(self.result(), self.pos)))
4223         code.put_gotref(self.py_result())
4224         
4225     def type_error(self):
4226         if not self.operand.type.is_error:
4227             error(self.pos, "Invalid operand type for '%s' (%s)" %
4228                 (self.operator, self.operand.type))
4229         self.type = PyrexTypes.error_type
4230
4231     def analyse_cpp_operation(self, env):
4232         type = self.operand.type
4233         if type.is_ptr:
4234             type = type.base_type
4235         function = type.scope.lookup("operator%s" % self.operator)
4236         if not function:
4237             error(self.pos, "'%s' operator not defined for %s"
4238                 % (self.operator, type))
4239             self.type_error()
4240             return
4241         func_type = function.type
4242         if func_type.is_ptr:
4243             func_type = func_type.base_type
4244         self.type = func_type.return_type
4245
4246
4247 class NotNode(ExprNode):
4248     #  'not' operator
4249     #
4250     #  operand   ExprNode
4251     
4252     type = PyrexTypes.c_bint_type
4253
4254     subexprs = ['operand']
4255     
4256     def calculate_constant_result(self):
4257         self.constant_result = not self.operand.constant_result
4258
4259     def compile_time_value(self, denv):
4260         operand = self.operand.compile_time_value(denv)
4261         try:
4262             return not operand
4263         except Exception, e:
4264             self.compile_time_value_error(e)
4265
4266     def infer_type(self, env):
4267         return PyrexTypes.c_bint_type
4268     
4269     def analyse_types(self, env):
4270         self.operand.analyse_types(env)
4271         self.operand = self.operand.coerce_to_boolean(env)
4272     
4273     def calculate_result_code(self):
4274         return "(!%s)" % self.operand.result()
4275     
4276     def generate_result_code(self, code):
4277         pass
4278
4279
4280 class UnaryPlusNode(UnopNode):
4281     #  unary '+' operator
4282     
4283     operator = '+'
4284     
4285     def analyse_c_operation(self, env):
4286         self.type = self.operand.type
4287     
4288     def py_operation_function(self):
4289         return "PyNumber_Positive"
4290     
4291     def calculate_result_code(self):
4292         if self.is_cpp_operation():
4293             return "(+%s)" % self.operand.result()
4294         else:
4295             return self.operand.result()
4296
4297
4298 class UnaryMinusNode(UnopNode):
4299     #  unary '-' operator
4300     
4301     operator = '-'
4302     
4303     def analyse_c_operation(self, env):
4304         if self.operand.type.is_numeric:
4305             self.type = self.operand.type
4306         else:
4307             self.type_error()
4308         if self.type.is_complex:
4309             self.infix = False
4310     
4311     def py_operation_function(self):
4312         return "PyNumber_Negative"
4313     
4314     def calculate_result_code(self):
4315         if self.infix:
4316             return "(-%s)" % self.operand.result()
4317         else:
4318             return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
4319
4320     def get_constant_c_result_code(self):
4321         value = self.operand.get_constant_c_result_code()
4322         if value:
4323             return "(-%s)" % (value)
4324
4325 class TildeNode(UnopNode):
4326     #  unary '~' operator
4327
4328     def analyse_c_operation(self, env):
4329         if self.operand.type.is_int:
4330             self.type = self.operand.type
4331         else:
4332             self.type_error()
4333
4334     def py_operation_function(self):
4335         return "PyNumber_Invert"
4336     
4337     def calculate_result_code(self):
4338         return "(~%s)" % self.operand.result()
4339
4340
4341 class CUnopNode(UnopNode):
4342
4343     def is_py_operation(self):
4344         return False
4345
4346 class DereferenceNode(CUnopNode):
4347     #  unary * operator
4348
4349     operator = '*'
4350     
4351     def analyse_c_operation(self, env):
4352         if self.operand.type.is_ptr:
4353             self.type = self.operand.type.base_type
4354         else:
4355             self.type_error()
4356
4357     def calculate_result_code(self):
4358         return "(*%s)" % self.operand.result()
4359
4360
4361 class DecrementIncrementNode(CUnopNode):
4362     #  unary ++/-- operator
4363     
4364     def analyse_c_operation(self, env):
4365         if self.operand.type.is_ptr or self.operand.type.is_numeric:
4366             self.type = self.operand.type
4367         else:
4368             self.type_error()
4369
4370     def calculate_result_code(self):
4371         if self.is_prefix:
4372             return "(%s%s)" % (self.operator, self.operand.result())
4373         else:
4374             return "(%s%s)" % (self.operand.result(), self.operator)
4375
4376 def inc_dec_constructor(is_prefix, operator):
4377     return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
4378
4379
4380 class AmpersandNode(ExprNode):
4381     #  The C address-of operator.
4382     #
4383     #  operand  ExprNode
4384     
4385     subexprs = ['operand']
4386     
4387     def infer_type(self, env):
4388         return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
4389
4390     def analyse_types(self, env):
4391         self.operand.analyse_types(env)
4392         argtype = self.operand.type
4393         if not (argtype.is_cfunction or self.operand.is_lvalue()):
4394             self.error("Taking address of non-lvalue")
4395             return
4396         if argtype.is_pyobject:
4397             self.error("Cannot take address of Python variable")
4398             return
4399         self.type = PyrexTypes.c_ptr_type(argtype)
4400     
4401     def check_const(self):
4402         return self.operand.check_const_addr()
4403     
4404     def error(self, mess):
4405         error(self.pos, mess)
4406         self.type = PyrexTypes.error_type
4407         self.result_code = "<error>"
4408     
4409     def calculate_result_code(self):
4410         return "(&%s)" % self.operand.result()
4411
4412     def generate_result_code(self, code):
4413         pass
4414     
4415
4416 unop_node_classes = {
4417     "+":  UnaryPlusNode,
4418     "-":  UnaryMinusNode,
4419     "~":  TildeNode,
4420 }
4421
4422 def unop_node(pos, operator, operand):
4423     # Construct unnop node of appropriate class for 
4424     # given operator.
4425     if isinstance(operand, IntNode) and operator == '-':
4426         return IntNode(pos = operand.pos, value = str(-int(operand.value, 0)))
4427     elif isinstance(operand, UnopNode) and operand.operator == operator:
4428         warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
4429     return unop_node_classes[operator](pos, 
4430         operator = operator, 
4431         operand = operand)
4432
4433
4434 class TypecastNode(ExprNode):
4435     #  C type cast
4436     #
4437     #  operand      ExprNode
4438     #  base_type    CBaseTypeNode
4439     #  declarator   CDeclaratorNode
4440     #
4441     #  If used from a transform, one can if wanted specify the attribute
4442     #  "type" directly and leave base_type and declarator to None
4443     
4444     subexprs = ['operand']
4445     base_type = declarator = type = None
4446     
4447     def type_dependencies(self, env):
4448         return ()
4449     
4450     def infer_type(self, env):
4451         if self.type is None:
4452             base_type = self.base_type.analyse(env)
4453             _, self.type = self.declarator.analyse(base_type, env)
4454         return self.type
4455     
4456     def analyse_types(self, env):
4457         if self.type is None:
4458             base_type = self.base_type.analyse(env)
4459             _, self.type = self.declarator.analyse(base_type, env)
4460         if self.type.is_cfunction:
4461             error(self.pos,
4462                 "Cannot cast to a function type")
4463             self.type = PyrexTypes.error_type
4464         self.operand.analyse_types(env)
4465         to_py = self.type.is_pyobject
4466         from_py = self.operand.type.is_pyobject
4467         if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
4468             error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
4469         if to_py and not from_py:
4470             if self.operand.type.can_coerce_to_pyobject(env):
4471                 self.result_ctype = py_object_type
4472                 self.operand = self.operand.coerce_to_pyobject(env)
4473             else:
4474                 if self.operand.type.is_ptr:
4475                     if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
4476                         error(self.pos, "Python objects cannot be cast from pointers of primitive types")
4477                 else:
4478                     # Should this be an error? 
4479                     warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
4480                 self.operand = self.operand.coerce_to_simple(env)
4481         elif from_py and not to_py:
4482             if self.type.create_from_py_utility_code(env):
4483                 self.operand = self.operand.coerce_to(self.type, env)
4484             elif self.type.is_ptr:
4485                 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
4486                     error(self.pos, "Python objects cannot be cast to pointers of primitive types")
4487             else:
4488                 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
4489         elif from_py and to_py:
4490             if self.typecheck and self.type.is_extension_type:
4491                 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
4492         elif self.type.is_complex and self.operand.type.is_complex:
4493             self.operand = self.operand.coerce_to_simple(env)
4494
4495     def nogil_check(self, env):
4496         if self.type and self.type.is_pyobject and self.is_temp:
4497             self.gil_error()
4498
4499     def check_const(self):
4500         return self.operand.check_const()
4501
4502     def calculate_constant_result(self):
4503         # we usually do not know the result of a type cast at code
4504         # generation time
4505         pass
4506     
4507     def calculate_result_code(self):
4508         if self.type.is_complex:
4509             operand_result = self.operand.result()
4510             if self.operand.type.is_complex:
4511                 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
4512                 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
4513             else:
4514                 real_part = self.type.real_type.cast_code(operand_result)
4515                 imag_part = "0"
4516             return "%s(%s, %s)" % (
4517                     self.type.from_parts,
4518                     real_part,
4519                     imag_part)    
4520         else:
4521             return self.type.cast_code(self.operand.result())
4522     
4523     def get_constant_c_result_code(self):
4524         operand_result = self.operand.get_constant_c_result_code()
4525         if operand_result:
4526             return self.type.cast_code(operand_result)
4527     
4528     def result_as(self, type):
4529         if self.type.is_pyobject and not self.is_temp:
4530             #  Optimise away some unnecessary casting
4531             return self.operand.result_as(type)
4532         else:
4533             return ExprNode.result_as(self, type)
4534
4535     def generate_result_code(self, code):
4536         if self.is_temp:
4537             code.putln(
4538                 "%s = (PyObject *)%s;" % (
4539                     self.result(),
4540                     self.operand.result()))
4541             code.put_incref(self.result(), self.ctype())
4542
4543
4544 class SizeofNode(ExprNode):
4545     #  Abstract base class for sizeof(x) expression nodes.
4546     
4547     type = PyrexTypes.c_size_t_type
4548
4549     def check_const(self):
4550         return True
4551
4552     def generate_result_code(self, code):
4553         pass
4554
4555
4556 class SizeofTypeNode(SizeofNode):
4557     #  C sizeof function applied to a type
4558     #
4559     #  base_type   CBaseTypeNode
4560     #  declarator  CDeclaratorNode
4561     
4562     subexprs = []
4563     arg_type = None
4564     
4565     def analyse_types(self, env):
4566         # we may have incorrectly interpreted a dotted name as a type rather than an attribute
4567         # this could be better handled by more uniformly treating types as runtime-available objects
4568         if 0 and self.base_type.module_path:
4569             path = self.base_type.module_path
4570             obj = env.lookup(path[0])
4571             if obj.as_module is None:
4572                 operand = NameNode(pos=self.pos, name=path[0])
4573                 for attr in path[1:]:
4574                     operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
4575                 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
4576                 self.operand = operand
4577                 self.__class__ = SizeofVarNode
4578                 self.analyse_types(env)
4579                 return
4580         if self.arg_type is None:
4581             base_type = self.base_type.analyse(env)
4582             _, arg_type = self.declarator.analyse(base_type, env)
4583             self.arg_type = arg_type
4584         self.check_type()
4585         
4586     def check_type(self):
4587         arg_type = self.arg_type
4588         if arg_type.is_pyobject and not arg_type.is_extension_type:
4589             error(self.pos, "Cannot take sizeof Python object")
4590         elif arg_type.is_void:
4591             error(self.pos, "Cannot take sizeof void")
4592         elif not arg_type.is_complete():
4593             error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
4594         
4595     def calculate_result_code(self):
4596         if self.arg_type.is_extension_type:
4597             # the size of the pointer is boring
4598             # we want the size of the actual struct
4599             arg_code = self.arg_type.declaration_code("", deref=1)
4600         else:
4601             arg_code = self.arg_type.declaration_code("")
4602         return "(sizeof(%s))" % arg_code
4603     
4604
4605 class SizeofVarNode(SizeofNode):
4606     #  C sizeof function applied to a variable
4607     #
4608     #  operand   ExprNode
4609     
4610     subexprs = ['operand']
4611     
4612     def analyse_types(self, env):
4613         # We may actually be looking at a type rather than a variable...
4614         # If we are, traditional analysis would fail...
4615         operand_as_type = self.operand.analyse_as_type(env)
4616         if operand_as_type:
4617             self.arg_type = operand_as_type
4618             self.__class__ = SizeofTypeNode
4619             self.check_type()
4620         else:
4621             self.operand.analyse_types(env)
4622     
4623     def calculate_result_code(self):
4624         return "(sizeof(%s))" % self.operand.result()
4625     
4626     def generate_result_code(self, code):
4627         pass
4628
4629 class TypeofNode(ExprNode):
4630     #  Compile-time type of an expression, as a string.
4631     #
4632     #  operand   ExprNode
4633     #  literal   StringNode # internal
4634     
4635     literal = None
4636     type = py_object_type
4637     
4638     subexprs = ['literal'] # 'operand' will be ignored after type analysis!
4639     
4640     def analyse_types(self, env):
4641         self.operand.analyse_types(env)
4642         self.literal = StringNode(
4643             self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
4644         self.literal.analyse_types(env)
4645         self.literal = self.literal.coerce_to_pyobject(env)
4646     
4647     def generate_evaluation_code(self, code):
4648         self.literal.generate_evaluation_code(code)
4649     
4650     def calculate_result_code(self):
4651         return self.literal.calculate_result_code()
4652
4653 #-------------------------------------------------------------------
4654 #
4655 #  Binary operator nodes
4656 #
4657 #-------------------------------------------------------------------
4658
4659 def _not_in(x, seq):
4660     return x not in seq
4661
4662 compile_time_binary_operators = {
4663     '<': operator.lt,
4664     '<=': operator.le,
4665     '==': operator.eq,
4666     '!=': operator.ne,
4667     '>=': operator.ge,
4668     '>': operator.gt,
4669     'is': operator.is_,
4670     'is_not': operator.is_not,
4671     '+': operator.add,
4672     '&': operator.and_,
4673     '/': operator.truediv,
4674     '//': operator.floordiv,
4675     '<<': operator.lshift,
4676     '%': operator.mod,
4677     '*': operator.mul,
4678     '|': operator.or_,
4679     '**': operator.pow,
4680     '>>': operator.rshift,
4681     '-': operator.sub,
4682     '^': operator.xor,
4683     'in': operator.contains,
4684     'not_in': _not_in,
4685 }
4686
4687 def get_compile_time_binop(node):
4688     func = compile_time_binary_operators.get(node.operator)
4689     if not func:
4690         error(node.pos,
4691             "Binary '%s' not supported in compile-time expression"
4692                 % node.operator)
4693     return func
4694
4695 class BinopNode(ExprNode):
4696     #  operator     string
4697     #  operand1     ExprNode
4698     #  operand2     ExprNode
4699     #
4700     #  Processing during analyse_expressions phase:
4701     #
4702     #    analyse_c_operation
4703     #      Called when neither operand is a pyobject.
4704     #      - Check operand types and coerce if needed.
4705     #      - Determine result type and result code fragment.
4706     #      - Allocate temporary for result if needed.
4707     
4708     subexprs = ['operand1', 'operand2']
4709
4710     def calculate_constant_result(self):
4711         func = compile_time_binary_operators[self.operator]
4712         self.constant_result = func(
4713             self.operand1.constant_result,
4714             self.operand2.constant_result)
4715
4716     def compile_time_value(self, denv):
4717         func = get_compile_time_binop(self)
4718         operand1 = self.operand1.compile_time_value(denv)
4719         operand2 = self.operand2.compile_time_value(denv)
4720         try:
4721             return func(operand1, operand2)
4722         except Exception, e:
4723             self.compile_time_value_error(e)
4724     
4725     def infer_type(self, env):
4726         return self.result_type(self.operand1.infer_type(env),
4727                                 self.operand2.infer_type(env))
4728     
4729     def analyse_types(self, env):
4730         self.operand1.analyse_types(env)
4731         self.operand2.analyse_types(env)
4732         if self.is_py_operation():
4733             self.coerce_operands_to_pyobjects(env)
4734             self.type = self.result_type(self.operand1.type,
4735                                          self.operand2.type)
4736             assert self.type.is_pyobject
4737             self.is_temp = 1
4738         elif self.is_cpp_operation():
4739             self.analyse_cpp_operation(env)
4740         else:
4741             self.analyse_c_operation(env)
4742     
4743     def is_py_operation(self):
4744         return self.is_py_operation_types(self.operand1.type, self.operand2.type)
4745     
4746     def is_py_operation_types(self, type1, type2):
4747         return type1.is_pyobject or type2.is_pyobject
4748
4749     def is_cpp_operation(self):
4750         return (self.operand1.type.is_cpp_class
4751             or self.operand2.type.is_cpp_class)
4752     
4753     def analyse_cpp_operation(self, env):
4754         type1 = self.operand1.type
4755         type2 = self.operand2.type
4756         entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
4757         if not entry:
4758             self.type_error()
4759             return
4760         func_type = entry.type
4761         if func_type.is_ptr:
4762             func_type = func_type.base_type
4763         if len(func_type.args) == 1:
4764             self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
4765         else:
4766             self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
4767             self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
4768         self.type = func_type.return_type
4769     
4770     def result_type(self, type1, type2):
4771         if self.is_py_operation_types(type1, type2):
4772             if type2.is_string:
4773                 type2 = Builtin.bytes_type
4774             if type1.is_string:
4775                 type1 = Builtin.bytes_type
4776             elif self.operator == '%' \
4777                      and type1 in (Builtin.str_type, Builtin.unicode_type):
4778                 # note that  b'%s' % b'abc'  doesn't work in Py3
4779                 return type1
4780             if type1.is_builtin_type:
4781                 if type1 is type2:
4782                     if self.operator in '**%+|&^':
4783                         # FIXME: at least these operators should be safe - others?
4784                         return type1
4785                 elif self.operator == '*':
4786                     if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
4787                         return type1
4788                     # multiplication of containers/numbers with an
4789                     # integer value always (?) returns the same type
4790                     if type2.is_int:
4791                         return type1
4792             elif type2.is_builtin_type and type1.is_int and self.operator == '*':
4793                 # multiplication of containers/numbers with an
4794                 # integer value always (?) returns the same type
4795                 return type2
4796             return py_object_type
4797         else:
4798             return self.compute_c_result_type(type1, type2)
4799
4800     def nogil_check(self, env):
4801         if self.is_py_operation():
4802             self.gil_error()
4803         
4804     def coerce_operands_to_pyobjects(self, env):
4805         self.operand1 = self.operand1.coerce_to_pyobject(env)
4806         self.operand2 = self.operand2.coerce_to_pyobject(env)
4807     
4808     def check_const(self):
4809         return self.operand1.check_const() and self.operand2.check_const()
4810     
4811     def generate_result_code(self, code):
4812         #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
4813         if self.operand1.type.is_pyobject:
4814             function = self.py_operation_function()
4815             if function == "PyNumber_Power":
4816                 extra_args = ", Py_None"
4817             else:
4818                 extra_args = ""
4819             code.putln(
4820                 "%s = %s(%s, %s%s); %s" % (
4821                     self.result(), 
4822                     function, 
4823                     self.operand1.py_result(),
4824                     self.operand2.py_result(),
4825                     extra_args,
4826                     code.error_goto_if_null(self.result(), self.pos)))
4827             code.put_gotref(self.py_result())
4828     
4829     def type_error(self):
4830         if not (self.operand1.type.is_error
4831                 or self.operand2.type.is_error):
4832             error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
4833                 (self.operator, self.operand1.type, 
4834                     self.operand2.type))
4835         self.type = PyrexTypes.error_type
4836
4837
4838 class NumBinopNode(BinopNode):
4839     #  Binary operation taking numeric arguments.
4840     
4841     infix = True
4842     
4843     def analyse_c_operation(self, env):
4844         type1 = self.operand1.type
4845         type2 = self.operand2.type
4846         self.type = self.compute_c_result_type(type1, type2)
4847         if not self.type:
4848             self.type_error()
4849             return
4850         if self.type.is_complex:
4851             self.infix = False
4852         if not self.infix:
4853             self.operand1 = self.operand1.coerce_to(self.type, env)
4854             self.operand2 = self.operand2.coerce_to(self.type, env)
4855     
4856     def compute_c_result_type(self, type1, type2):
4857         if self.c_types_okay(type1, type2):
4858             return PyrexTypes.widest_numeric_type(type1, type2)
4859         else:
4860             return None
4861
4862     def get_constant_c_result_code(self):
4863         value1 = self.operand1.get_constant_c_result_code()
4864         value2 = self.operand2.get_constant_c_result_code()
4865         if value1 and value2:
4866             return "(%s %s %s)" % (value1, self.operator, value2)
4867         else:
4868             return None
4869     
4870     def c_types_okay(self, type1, type2):
4871         #print "NumBinopNode.c_types_okay:", type1, type2 ###
4872         return (type1.is_numeric  or type1.is_enum) \
4873             and (type2.is_numeric  or type2.is_enum)
4874
4875     def calculate_result_code(self):
4876         if self.infix:
4877             return "(%s %s %s)" % (
4878                 self.operand1.result(), 
4879                 self.operator, 
4880                 self.operand2.result())
4881         else:
4882             func = self.type.binary_op(self.operator)
4883             if func is None:
4884                 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
4885             return "%s(%s, %s)" % (
4886                 func,
4887                 self.operand1.result(),
4888                 self.operand2.result())
4889     
4890     def py_operation_function(self):
4891         return self.py_functions[self.operator]
4892
4893     py_functions = {
4894         "|":        "PyNumber_Or",
4895         "^":        "PyNumber_Xor",
4896         "&":        "PyNumber_And",
4897         "<<":       "PyNumber_Lshift",
4898         ">>":       "PyNumber_Rshift",
4899         "+":        "PyNumber_Add",
4900         "-":        "PyNumber_Subtract",
4901         "*":        "PyNumber_Multiply",
4902         "/":        "__Pyx_PyNumber_Divide",
4903         "//":       "PyNumber_FloorDivide",
4904         "%":        "PyNumber_Remainder",
4905         "**":       "PyNumber_Power"
4906     }
4907
4908
4909 class IntBinopNode(NumBinopNode):
4910     #  Binary operation taking integer arguments.
4911     
4912     def c_types_okay(self, type1, type2):
4913         #print "IntBinopNode.c_types_okay:", type1, type2 ###
4914         return (type1.is_int or type1.is_enum) \
4915             and (type2.is_int or type2.is_enum)
4916
4917     
4918 class AddNode(NumBinopNode):
4919     #  '+' operator.
4920     
4921     def is_py_operation_types(self, type1, type2):
4922         if type1.is_string and type2.is_string:
4923             return 1
4924         else:
4925             return NumBinopNode.is_py_operation_types(self, type1, type2)
4926
4927     def compute_c_result_type(self, type1, type2):
4928         #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
4929         if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
4930             return type1
4931         elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
4932             return type2
4933         else:
4934             return NumBinopNode.compute_c_result_type(
4935                 self, type1, type2)
4936
4937
4938 class SubNode(NumBinopNode):
4939     #  '-' operator.
4940     
4941     def compute_c_result_type(self, type1, type2):
4942         if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
4943             return type1
4944         elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
4945             return PyrexTypes.c_int_type
4946         else:
4947             return NumBinopNode.compute_c_result_type(
4948                 self, type1, type2)
4949
4950
4951 class MulNode(NumBinopNode):
4952     #  '*' operator.
4953     
4954     def is_py_operation_types(self, type1, type2):
4955         if (type1.is_string and type2.is_int) \
4956             or (type2.is_string and type1.is_int):
4957                 return 1
4958         else:
4959             return NumBinopNode.is_py_operation_types(self, type1, type2)
4960
4961
4962 class DivNode(NumBinopNode):
4963     #  '/' or '//' operator.
4964     
4965     cdivision = None
4966     truedivision = None   # == "unknown" if operator == '/'
4967     ctruedivision = False
4968     cdivision_warnings = False
4969     zerodivision_check = None
4970
4971     def find_compile_time_binary_operator(self, op1, op2):
4972         func = compile_time_binary_operators[self.operator]
4973         if self.operator == '/' and self.truedivision is None:
4974             # => true div for floats, floor div for integers
4975             if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
4976                 func = compile_time_binary_operators['//']
4977         return func
4978
4979     def calculate_constant_result(self):
4980         op1 = self.operand1.constant_result
4981         op2 = self.operand2.constant_result
4982         func = self.find_compile_time_binary_operator(op1, op2)
4983         self.constant_result = func(
4984             self.operand1.constant_result,
4985             self.operand2.constant_result)
4986
4987     def compile_time_value(self, denv):
4988         operand1 = self.operand1.compile_time_value(denv)
4989         operand2 = self.operand2.compile_time_value(denv)
4990         try:
4991             func = self.find_compile_time_binary_operator(
4992                 self, operand1, operand2)
4993             return func(operand1, operand2)
4994         except Exception, e:
4995             self.compile_time_value_error(e)
4996
4997     def analyse_types(self, env):
4998         if self.cdivision or env.directives['cdivision']:
4999             self.ctruedivision = False
5000         else:
5001             self.ctruedivision = self.truedivision
5002         NumBinopNode.analyse_types(self, env)
5003         if self.is_cpp_operation():
5004             self.cdivision = True
5005         if not self.type.is_pyobject:
5006             self.zerodivision_check = (
5007                 self.cdivision is None and not env.directives['cdivision']
5008                 and (self.operand2.constant_result is not_a_constant or
5009                      self.operand2.constant_result == 0))
5010             if self.zerodivision_check or env.directives['cdivision_warnings']:
5011                 # Need to check ahead of time to warn or raise zero division error
5012                 self.operand1 = self.operand1.coerce_to_simple(env)
5013                 self.operand2 = self.operand2.coerce_to_simple(env)
5014                 if env.nogil:
5015                     error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
5016
5017     def compute_c_result_type(self, type1, type2):
5018         if self.operator == '/' and self.ctruedivision:
5019             if not type1.is_float and not type2.is_float:
5020                 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
5021                 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
5022                 return widest_type
5023         return NumBinopNode.compute_c_result_type(self, type1, type2)
5024
5025     def zero_division_message(self):
5026         if self.type.is_int:
5027             return "integer division or modulo by zero"
5028         else:
5029             return "float division"
5030
5031     def generate_evaluation_code(self, code):
5032         if not self.type.is_pyobject and not self.type.is_complex:
5033             if self.cdivision is None:
5034                 self.cdivision = (code.globalstate.directives['cdivision'] 
5035                                     or not self.type.signed
5036                                     or self.type.is_float)
5037             if not self.cdivision:
5038                 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
5039         NumBinopNode.generate_evaluation_code(self, code)
5040         self.generate_div_warning_code(code)
5041     
5042     def generate_div_warning_code(self, code):
5043         if not self.type.is_pyobject:
5044             if self.zerodivision_check:
5045                 if not self.infix:
5046                     zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
5047                 else:
5048                     zero_test = "%s == 0" % self.operand2.result()
5049                 code.putln("if (unlikely(%s)) {" % zero_test)
5050                 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
5051                 code.putln(code.error_goto(self.pos))
5052                 code.putln("}")
5053                 if self.type.is_int and self.type.signed and self.operator != '%':
5054                     code.globalstate.use_utility_code(division_overflow_test_code)
5055                     code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
5056                                     self.type.declaration_code(''), 
5057                                     self.operand2.result(),
5058                                     self.operand1.result()))
5059                     code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
5060                     code.putln(code.error_goto(self.pos))
5061                     code.putln("}")
5062             if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
5063                 code.globalstate.use_utility_code(cdivision_warning_utility_code)
5064                 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
5065                                 self.operand1.result(),
5066                                 self.operand2.result()))
5067                 code.putln(code.set_error_info(self.pos));
5068                 code.put("if (__Pyx_cdivision_warning()) ")
5069                 code.put_goto(code.error_label)
5070                 code.putln("}")
5071     
5072     def calculate_result_code(self):
5073         if self.type.is_complex:
5074             return NumBinopNode.calculate_result_code(self)
5075         elif self.type.is_float and self.operator == '//':
5076             return "floor(%s / %s)" % (
5077                 self.operand1.result(),
5078                 self.operand2.result())
5079         elif self.truedivision or self.cdivision:
5080             op1 = self.operand1.result()
5081             op2 = self.operand2.result()
5082             if self.truedivision:
5083                 if self.type != self.operand1.type:
5084                     op1 = self.type.cast_code(op1)
5085                 if self.type != self.operand2.type:
5086                     op2 = self.type.cast_code(op2)
5087             return "(%s / %s)" % (op1, op2)
5088         else:
5089             return "__Pyx_div_%s(%s, %s)" % (
5090                     self.type.specalization_name(),
5091                     self.operand1.result(), 
5092                     self.operand2.result())
5093
5094
5095 class ModNode(DivNode):
5096     #  '%' operator.
5097
5098     def is_py_operation_types(self, type1, type2):
5099         return (type1.is_string
5100             or type2.is_string
5101             or NumBinopNode.is_py_operation_types(self, type1, type2))
5102
5103     def zero_division_message(self):
5104         if self.type.is_int:
5105             return "integer division or modulo by zero"
5106         else:
5107             return "float divmod()"
5108     
5109     def generate_evaluation_code(self, code):
5110         if not self.type.is_pyobject:
5111             if self.cdivision is None:
5112                 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
5113             if not self.cdivision:
5114                 if self.type.is_int:
5115                     code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
5116                 else:
5117                     code.globalstate.use_utility_code(
5118                         mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
5119         NumBinopNode.generate_evaluation_code(self, code)
5120         self.generate_div_warning_code(code)
5121     
5122     def calculate_result_code(self):
5123         if self.cdivision:
5124             if self.type.is_float:
5125                 return "fmod%s(%s, %s)" % (
5126                     self.type.math_h_modifier,
5127                     self.operand1.result(), 
5128                     self.operand2.result())
5129             else:
5130                 return "(%s %% %s)" % (
5131                     self.operand1.result(), 
5132                     self.operand2.result())
5133         else:
5134             return "__Pyx_mod_%s(%s, %s)" % (
5135                     self.type.specalization_name(),
5136                     self.operand1.result(), 
5137                     self.operand2.result())
5138
5139 class PowNode(NumBinopNode):
5140     #  '**' operator.
5141     
5142     def analyse_c_operation(self, env):
5143         NumBinopNode.analyse_c_operation(self, env)
5144         if self.type.is_complex:
5145             error(self.pos, "complex powers not yet supported")
5146             self.pow_func = "<error>"
5147         elif self.type.is_float:
5148             self.pow_func = "pow"
5149         else:
5150             self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
5151             env.use_utility_code(
5152                     int_pow_utility_code.specialize(func_name=self.pow_func, 
5153                                                 type=self.type.declaration_code('')))
5154
5155     def calculate_result_code(self):
5156         return "%s(%s, %s)" % (
5157             self.pow_func, 
5158             self.operand1.result(), 
5159             self.operand2.result())
5160
5161
5162 # Note: This class is temporary "shut down" into an ineffective mode temp
5163 # allocation mode.
5164 #
5165 # More sophisticated temp reuse was going on before,
5166 # one could have a look at adding this again after /all/ classes
5167 # are converted to the new temp scheme. (The temp juggling cannot work
5168 # otherwise).
5169 class BoolBinopNode(ExprNode):
5170     #  Short-circuiting boolean operation.
5171     #
5172     #  operator     string
5173     #  operand1     ExprNode
5174     #  operand2     ExprNode
5175     
5176     subexprs = ['operand1', 'operand2']
5177     
5178     def infer_type(self, env):
5179         type1 = self.operand1.infer_type(env)
5180         type2 = self.operand2.infer_type(env)
5181         return PyrexTypes.spanning_type(type1, type2)
5182
5183     def calculate_constant_result(self):
5184         if self.operator == 'and':
5185             self.constant_result = \
5186                 self.operand1.constant_result and \
5187                 self.operand2.constant_result
5188         else:
5189             self.constant_result = \
5190                 self.operand1.constant_result or \
5191                 self.operand2.constant_result
5192     
5193     def compile_time_value(self, denv):
5194         if self.operator == 'and':
5195             return self.operand1.compile_time_value(denv) \
5196                 and self.operand2.compile_time_value(denv)
5197         else:
5198             return self.operand1.compile_time_value(denv) \
5199                 or self.operand2.compile_time_value(denv)
5200     
5201     def coerce_to_boolean(self, env):
5202         self.operand1 = self.operand1.coerce_to_boolean(env)
5203         self.operand2 = self.operand2.coerce_to_boolean(env)
5204         self.type = PyrexTypes.c_bint_type
5205         return self
5206
5207     def analyse_types(self, env):
5208         self.operand1.analyse_types(env)
5209         self.operand2.analyse_types(env)
5210         self.type = PyrexTypes.spanning_type(self.operand1.type, self.operand2.type)
5211         self.operand1 = self.operand1.coerce_to(self.type, env)
5212         self.operand2 = self.operand2.coerce_to(self.type, env)
5213         
5214         # For what we're about to do, it's vital that
5215         # both operands be temp nodes.
5216         self.operand1 = self.operand1.coerce_to_simple(env)
5217         self.operand2 = self.operand2.coerce_to_simple(env)
5218         self.is_temp = 1
5219
5220     gil_message = "Truth-testing Python object"
5221
5222     def check_const(self):
5223         return self.operand1.check_const() and self.operand2.check_const()
5224     
5225     def generate_evaluation_code(self, code):
5226         code.mark_pos(self.pos)
5227         self.operand1.generate_evaluation_code(code)
5228         test_result, uses_temp = self.generate_operand1_test(code)
5229         if self.operator == 'and':
5230             sense = ""
5231         else:
5232             sense = "!"
5233         code.putln(
5234             "if (%s%s) {" % (
5235                 sense,
5236                 test_result))
5237         if uses_temp:
5238             code.funcstate.release_temp(test_result)
5239         self.operand1.generate_disposal_code(code)
5240         self.operand2.generate_evaluation_code(code)
5241         self.allocate_temp_result(code)
5242         self.operand2.make_owned_reference(code)
5243         code.putln("%s = %s;" % (self.result(), self.operand2.result()))
5244         self.operand2.generate_post_assignment_code(code)
5245         self.operand2.free_temps(code)
5246         code.putln("} else {")
5247         self.operand1.make_owned_reference(code)
5248         code.putln("%s = %s;" % (self.result(), self.operand1.result()))
5249         self.operand1.generate_post_assignment_code(code)
5250         self.operand1.free_temps(code)
5251         code.putln("}")
5252     
5253     def generate_operand1_test(self, code):
5254         #  Generate code to test the truth of the first operand.
5255         if self.type.is_pyobject:
5256             test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
5257                                                        manage_ref=False)
5258             code.putln(
5259                 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
5260                     test_result,
5261                     self.operand1.py_result(),
5262                     code.error_goto_if_neg(test_result, self.pos)))
5263         else:
5264             test_result = self.operand1.result()
5265         return (test_result, self.type.is_pyobject)
5266
5267
5268 class CondExprNode(ExprNode):
5269     #  Short-circuiting conditional expression.
5270     #
5271     #  test        ExprNode
5272     #  true_val    ExprNode
5273     #  false_val   ExprNode
5274     
5275     true_val = None
5276     false_val = None
5277     
5278     subexprs = ['test', 'true_val', 'false_val']
5279     
5280     def type_dependencies(self, env):
5281         return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
5282     
5283     def infer_type(self, env):
5284         return self.compute_result_type(self.true_val.infer_type(env),
5285                                         self.false_val.infer_type(env))
5286
5287     def calculate_constant_result(self):
5288         if self.test.constant_result:
5289             self.constant_result = self.true_val.constant_result
5290         else:
5291             self.constant_result = self.false_val.constant_result
5292
5293     def analyse_types(self, env):
5294         self.test.analyse_types(env)
5295         self.test = self.test.coerce_to_boolean(env)
5296         self.true_val.analyse_types(env)
5297         self.false_val.analyse_types(env)
5298         self.type = self.compute_result_type(self.true_val.type, self.false_val.type)
5299         if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
5300             self.true_val = self.true_val.coerce_to(self.type, env)
5301             self.false_val = self.false_val.coerce_to(self.type, env)
5302         self.is_temp = 1
5303         if self.type == PyrexTypes.error_type:
5304             self.type_error()
5305         
5306     def compute_result_type(self, type1, type2):
5307         if type1 == type2:
5308             return type1
5309         elif type1.is_numeric and type2.is_numeric:
5310             return PyrexTypes.widest_numeric_type(type1, type2)
5311         elif type1.is_extension_type and type1.subtype_of_resolved_type(type2):
5312             return type2
5313         elif type2.is_extension_type and type2.subtype_of_resolved_type(type1):
5314             return type1
5315         elif type1.is_pyobject or type2.is_pyobject:
5316             return py_object_type
5317         elif type1.assignable_from(type2):
5318             return type1
5319         elif type2.assignable_from(type1):
5320             return type2
5321         else:
5322             return PyrexTypes.error_type
5323         
5324     def type_error(self):
5325         if not (self.true_val.type.is_error or self.false_val.type.is_error):
5326             error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
5327                 (self.true_val.type, self.false_val.type))
5328         self.type = PyrexTypes.error_type
5329     
5330     def check_const(self):
5331         return (self.test.check_const() 
5332             and self.true_val.check_const()
5333             and self.false_val.check_const())
5334     
5335     def generate_evaluation_code(self, code):
5336         # Because subexprs may not be evaluated we can use a more optimal
5337         # subexpr allocation strategy than the default, so override evaluation_code.
5338         
5339         code.mark_pos(self.pos)
5340         self.allocate_temp_result(code)
5341         self.test.generate_evaluation_code(code)
5342         code.putln("if (%s) {" % self.test.result() )
5343         self.eval_and_get(code, self.true_val)
5344         code.putln("} else {")
5345         self.eval_and_get(code, self.false_val)
5346         code.putln("}")
5347         self.test.generate_disposal_code(code)
5348         self.test.free_temps(code)
5349
5350     def eval_and_get(self, code, expr):
5351         expr.generate_evaluation_code(code)
5352         expr.make_owned_reference(code)
5353         code.putln("%s = %s;" % (self.result(), expr.result()))
5354         expr.generate_post_assignment_code(code)
5355         expr.free_temps(code)
5356
5357 richcmp_constants = {
5358     "<" : "Py_LT",
5359     "<=": "Py_LE",
5360     "==": "Py_EQ",
5361     "!=": "Py_NE",
5362     "<>": "Py_NE",
5363     ">" : "Py_GT",
5364     ">=": "Py_GE",
5365 }
5366
5367 class CmpNode(object):
5368     #  Mixin class containing code common to PrimaryCmpNodes
5369     #  and CascadedCmpNodes.
5370     
5371     def infer_types(self, env):
5372         # TODO: Actually implement this (after merging with -unstable).
5373         return py_object_type
5374
5375     def calculate_cascaded_constant_result(self, operand1_result):
5376         func = compile_time_binary_operators[self.operator]
5377         operand2_result = self.operand2.constant_result
5378         result = func(operand1_result, operand2_result)
5379         if result and self.cascade:
5380             result = result and \
5381                 self.cascade.cascaded_compile_time_value(operand2_result)
5382         self.constant_result = result
5383     
5384     def cascaded_compile_time_value(self, operand1, denv):
5385         func = get_compile_time_binop(self)
5386         operand2 = self.operand2.compile_time_value(denv)
5387         try:
5388             result = func(operand1, operand2)
5389         except Exception, e:
5390             self.compile_time_value_error(e)
5391             result = None
5392         if result:
5393             cascade = self.cascade
5394             if cascade:
5395                 # FIXME: I bet this must call cascaded_compile_time_value()
5396                 result = result and cascade.compile_time_value(operand2, denv)
5397         return result
5398
5399     def is_cpp_comparison(self):
5400         return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
5401
5402     def find_common_int_type(self, env, op, operand1, operand2):
5403         # type1 != type2 and at least one of the types is not a C int
5404         type1 = operand1.type
5405         type2 = operand2.type
5406         type1_can_be_int = False
5407         type2_can_be_int = False
5408
5409         if isinstance(operand1, (StringNode, BytesNode)) \
5410                and operand1.can_coerce_to_char_literal():
5411             type1_can_be_int = True
5412         if isinstance(operand2, (StringNode, BytesNode)) \
5413                  and operand2.can_coerce_to_char_literal():
5414             type2_can_be_int = True
5415
5416         if type1.is_int:
5417             if type2_can_be_int:
5418                 return type1
5419         elif type2.is_int:
5420             if type1_can_be_int:
5421                 return type2
5422         elif type1_can_be_int:
5423             if type2_can_be_int:
5424                 return PyrexTypes.c_uchar_type
5425
5426         return None
5427
5428     def find_common_type(self, env, op, operand1, common_type=None):
5429         operand2 = self.operand2
5430         type1 = operand1.type
5431         type2 = operand2.type
5432
5433         new_common_type = None
5434
5435         # catch general errors
5436         if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
5437                type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
5438             error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
5439             new_common_type = error_type
5440
5441         # try to use numeric comparisons where possible
5442         elif type1.is_complex or type2.is_complex:
5443             if op not in ('==', '!='):
5444                 error(self.pos, "complex types are unordered")
5445                 new_common_type = error_type
5446             if type1.is_pyobject:
5447                 new_common_type = type1
5448             elif type2.is_pyobject:
5449                 new_common_type = type2
5450             else:
5451                 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
5452         elif type1.is_numeric and type2.is_numeric:
5453             new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
5454         elif common_type is None or not common_type.is_pyobject:
5455             new_common_type = self.find_common_int_type(env, op, operand1, operand2)
5456
5457         if new_common_type is None:
5458             # fall back to generic type compatibility tests
5459             if type1 == type2:
5460                 new_common_type = type1
5461             elif type1.is_pyobject or type2.is_pyobject:
5462                 if type2.is_numeric or type2.is_string:
5463                     if operand2.check_for_coercion_error(type1):
5464                         new_common_type = error_type
5465                     else:
5466                         new_common_type = py_object_type
5467                 elif type1.is_numeric or type1.is_string:
5468                     if operand1.check_for_coercion_error(type2):
5469                         new_common_type = error_type
5470                     else:
5471                         new_common_type = py_object_type
5472                 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
5473                     new_common_type = py_object_type
5474                 else:
5475                     # one Python type and one non-Python type, not assignable
5476                     self.invalid_types_error(operand1, op, operand2)
5477                     new_common_type = error_type
5478             elif type1.assignable_from(type2):
5479                 new_common_type = type1
5480             elif type2.assignable_from(type1):
5481                 new_common_type = type2
5482             else:
5483                 # C types that we couldn't handle up to here are an error
5484                 self.invalid_types_error(operand1, op, operand2)
5485                 new_common_type = error_type
5486
5487         # recursively merge types
5488         if common_type is None or new_common_type.is_error:
5489             common_type = new_common_type
5490         else:
5491             # we could do a lot better by splitting the comparison
5492             # into a non-Python part and a Python part, but this is
5493             # safer for now
5494             common_type = PyrexTypes.spanning_type(common_type, new_common_type)
5495
5496         if self.cascade:
5497             common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
5498
5499         return common_type
5500
5501     def invalid_types_error(self, operand1, op, operand2):
5502         error(self.pos, "Invalid types for '%s' (%s, %s)" %
5503               (op, operand1.type, operand2.type))
5504
5505     def is_python_comparison(self):
5506         return (self.has_python_operands()
5507                 or (self.cascade and self.cascade.is_python_comparison())
5508                 or self.operator in ('in', 'not_in'))
5509
5510     def coerce_operands_to(self, dst_type, env):
5511         operand2 = self.operand2
5512         if operand2.type != dst_type:
5513             self.operand2 = operand2.coerce_to(dst_type, env)
5514         if self.cascade:
5515             self.cascade.coerce_operands_to(dst_type, env)
5516
5517     def is_python_result(self):
5518         return ((self.has_python_operands() and
5519                  self.operator not in ('is', 'is_not', 'in', 'not_in'))
5520             or (self.cascade and self.cascade.is_python_result()))
5521
5522     def generate_operation_code(self, code, result_code, 
5523             operand1, op , operand2):
5524         if self.type is PyrexTypes.py_object_type:
5525             coerce_result = "__Pyx_PyBool_FromLong"
5526         else:
5527             coerce_result = ""
5528         if 'not' in op: 
5529             negation = "!"
5530         else: 
5531             negation = ""
5532         if op == 'in' or op == 'not_in':
5533             code.globalstate.use_utility_code(contians_utility_code)
5534             if self.type is PyrexTypes.py_object_type:
5535                 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
5536             if op == 'not_in':
5537                 negation = "__Pyx_NegateNonNeg"
5538             if operand2.type is dict_type:
5539                 code.globalstate.use_utility_code(
5540                     raise_none_iter_error_utility_code)
5541                 code.putln("if (unlikely(%s == Py_None)) {" % operand2.py_result())
5542                 code.putln("__Pyx_RaiseNoneNotIterableError(); %s" %
5543                            code.error_goto(self.pos))
5544                 code.putln("} else {")
5545                 method = "PyDict_Contains"
5546             else:
5547                 method = "PySequence_Contains"
5548             if self.type is PyrexTypes.py_object_type:
5549                 error_clause = code.error_goto_if_null
5550                 got_ref = "__Pyx_XGOTREF(%s); " % result_code
5551             else:
5552                 error_clause = code.error_goto_if_neg
5553                 got_ref = ""
5554             code.putln(
5555                 "%s = %s(%s(%s(%s, %s))); %s%s" % (
5556                     result_code,
5557                     coerce_result,
5558                     negation,
5559                     method,
5560                     operand2.py_result(), 
5561                     operand1.py_result(), 
5562                     got_ref,
5563                     error_clause(result_code, self.pos)))
5564             if operand2.type is dict_type:
5565                 code.putln("}")
5566                     
5567         elif (operand1.type.is_pyobject
5568             and op not in ('is', 'is_not')):
5569                 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
5570                         result_code, 
5571                         operand1.py_result(), 
5572                         operand2.py_result(), 
5573                         richcmp_constants[op],
5574                         code.error_goto_if_null(result_code, self.pos)))
5575                 code.put_gotref(result_code)
5576         elif operand1.type.is_complex:
5577             if op == "!=": 
5578                 negation = "!"
5579             else: 
5580                 negation = ""
5581             code.putln("%s = %s(%s%s(%s, %s));" % (
5582                 result_code, 
5583                 coerce_result,
5584                 negation,
5585                 operand1.type.unary_op('eq'), 
5586                 operand1.result(), 
5587                 operand2.result()))
5588         else:
5589             type1 = operand1.type
5590             type2 = operand2.type
5591             if (type1.is_extension_type or type2.is_extension_type) \
5592                     and not type1.same_as(type2):
5593                 common_type = py_object_type
5594             elif type1.is_numeric:
5595                 common_type = PyrexTypes.widest_numeric_type(type1, type2)
5596             else:
5597                 common_type = type1
5598             code1 = operand1.result_as(common_type)
5599             code2 = operand2.result_as(common_type)
5600             code.putln("%s = %s(%s %s %s);" % (
5601                 result_code, 
5602                 coerce_result, 
5603                 code1, 
5604                 self.c_operator(op), 
5605                 code2))
5606
5607     def c_operator(self, op):
5608         if op == 'is':
5609             return "=="
5610         elif op == 'is_not':
5611             return "!="
5612         else:
5613             return op
5614     
5615 contians_utility_code = UtilityCode(
5616 proto="""
5617 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
5618 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
5619     return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
5620 }
5621 """)
5622
5623
5624 class PrimaryCmpNode(ExprNode, CmpNode):
5625     #  Non-cascaded comparison or first comparison of
5626     #  a cascaded sequence.
5627     #
5628     #  operator      string
5629     #  operand1      ExprNode
5630     #  operand2      ExprNode
5631     #  cascade       CascadedCmpNode
5632     
5633     #  We don't use the subexprs mechanism, because
5634     #  things here are too complicated for it to handle.
5635     #  Instead, we override all the framework methods
5636     #  which use it.
5637     
5638     child_attrs = ['operand1', 'operand2', 'cascade']
5639     
5640     cascade = None
5641
5642     def infer_type(self, env):
5643         # TODO: Actually implement this (after merging with -unstable).
5644         return py_object_type
5645
5646     def type_dependencies(self, env):
5647         return ()
5648
5649     def calculate_constant_result(self):
5650         self.constant_result = self.calculate_cascaded_constant_result(
5651             self.operand1.constant_result)
5652     
5653     def compile_time_value(self, denv):
5654         operand1 = self.operand1.compile_time_value(denv)
5655         return self.cascaded_compile_time_value(operand1, denv)
5656
5657     def analyse_types(self, env):
5658         self.operand1.analyse_types(env)
5659         self.operand2.analyse_types(env)
5660         if self.is_cpp_comparison():
5661             self.analyse_cpp_comparison(env)
5662             if self.cascade:
5663                 error(self.pos, "Cascading comparison not yet supported for cpp types.")
5664             return
5665         if self.cascade:
5666             self.cascade.analyse_types(env)
5667
5668         if self.operator in ('in', 'not_in'):
5669             common_type = py_object_type
5670             self.is_pycmp = True
5671         else:
5672             common_type = self.find_common_type(env, self.operator, self.operand1)
5673             self.is_pycmp = common_type.is_pyobject
5674
5675         if not common_type.is_error:
5676             if self.operand1.type != common_type:
5677                 self.operand1 = self.operand1.coerce_to(common_type, env)
5678             self.coerce_operands_to(common_type, env)
5679
5680         if self.cascade:
5681             self.operand2 = self.operand2.coerce_to_simple(env)
5682             self.cascade.coerce_cascaded_operands_to_temp(env)
5683         if self.is_python_result():
5684             self.type = PyrexTypes.py_object_type
5685         else:
5686             self.type = PyrexTypes.c_bint_type
5687         cdr = self.cascade
5688         while cdr:
5689             cdr.type = self.type
5690             cdr = cdr.cascade
5691         if self.is_pycmp or self.cascade:
5692             self.is_temp = 1
5693     
5694     def analyse_cpp_comparison(self, env):
5695         type1 = self.operand1.type
5696         type2 = self.operand2.type
5697         entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5698         if entry is None:
5699             error(self.pos, "Invalid types for '%s' (%s, %s)" %
5700                 (self.operator, type1, type2))
5701             self.type = PyrexTypes.error_type
5702             self.result_code = "<error>"
5703             return
5704         func_type = entry.type
5705         if func_type.is_ptr:
5706             func_type = func_type.base_type
5707         if len(func_type.args) == 1:
5708             self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5709         else:
5710             self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5711             self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5712         self.type = func_type.return_type
5713     
5714     def has_python_operands(self):
5715         return (self.operand1.type.is_pyobject
5716             or self.operand2.type.is_pyobject)
5717     
5718     def check_const(self):
5719         if self.cascade:
5720             self.not_const()
5721             return False
5722         else:
5723             return self.operand1.check_const() and self.operand2.check_const()
5724
5725     def calculate_result_code(self):
5726         if self.operand1.type.is_complex:
5727             if self.operator == "!=":
5728                 negation = "!"
5729             else:
5730                 negation = ""
5731             return "(%s%s(%s, %s))" % (
5732                 negation,
5733                 self.operand1.type.binary_op('=='), 
5734                 self.operand1.result(), 
5735                 self.operand2.result())
5736         else:
5737             return "(%s %s %s)" % (
5738                 self.operand1.result(),
5739                 self.c_operator(self.operator),
5740                 self.operand2.result())
5741
5742     def generate_evaluation_code(self, code):
5743         self.operand1.generate_evaluation_code(code)
5744         self.operand2.generate_evaluation_code(code)
5745         if self.is_temp:
5746             self.allocate_temp_result(code)
5747             self.generate_operation_code(code, self.result(), 
5748                 self.operand1, self.operator, self.operand2)
5749             if self.cascade:
5750                 self.cascade.generate_evaluation_code(code,
5751                     self.result(), self.operand2)
5752             self.operand1.generate_disposal_code(code)
5753             self.operand1.free_temps(code)
5754             self.operand2.generate_disposal_code(code)
5755             self.operand2.free_temps(code)
5756
5757     def generate_subexpr_disposal_code(self, code):
5758         #  If this is called, it is a non-cascaded cmp,
5759         #  so only need to dispose of the two main operands.
5760         self.operand1.generate_disposal_code(code)
5761         self.operand2.generate_disposal_code(code)
5762         
5763     def free_subexpr_temps(self, code):
5764         #  If this is called, it is a non-cascaded cmp,
5765         #  so only need to dispose of the two main operands.
5766         self.operand1.free_temps(code)
5767         self.operand2.free_temps(code)
5768         
5769     def annotate(self, code):
5770         self.operand1.annotate(code)
5771         self.operand2.annotate(code)
5772         if self.cascade:
5773             self.cascade.annotate(code)
5774
5775
5776 class CascadedCmpNode(Node, CmpNode):
5777     #  A CascadedCmpNode is not a complete expression node. It 
5778     #  hangs off the side of another comparison node, shares 
5779     #  its left operand with that node, and shares its result 
5780     #  with the PrimaryCmpNode at the head of the chain.
5781     #
5782     #  operator      string
5783     #  operand2      ExprNode
5784     #  cascade       CascadedCmpNode
5785
5786     child_attrs = ['operand2', 'cascade']
5787
5788     cascade = None
5789     constant_result = constant_value_not_set # FIXME: where to calculate this?
5790
5791     def infer_type(self, env):
5792         # TODO: Actually implement this (after merging with -unstable).
5793         return py_object_type
5794
5795     def type_dependencies(self, env):
5796         return ()
5797
5798     def analyse_types(self, env):
5799         self.operand2.analyse_types(env)
5800         if self.cascade:
5801             self.cascade.analyse_types(env)
5802
5803     def has_python_operands(self):
5804         return self.operand2.type.is_pyobject
5805         
5806     def coerce_operands_to_pyobjects(self, env):
5807         self.operand2 = self.operand2.coerce_to_pyobject(env)
5808         if self.cascade:
5809             self.cascade.coerce_operands_to_pyobjects(env)
5810
5811     def coerce_cascaded_operands_to_temp(self, env):
5812         if self.cascade:
5813             #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
5814             self.operand2 = self.operand2.coerce_to_simple(env)
5815             self.cascade.coerce_cascaded_operands_to_temp(env)
5816     
5817     def generate_evaluation_code(self, code, result, operand1):
5818         if self.type.is_pyobject:
5819             code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
5820             code.put_decref(result, self.type)
5821         else:
5822             code.putln("if (%s) {" % result)
5823         self.operand2.generate_evaluation_code(code)
5824         self.generate_operation_code(code, result, 
5825             operand1, self.operator, self.operand2)
5826         if self.cascade:
5827             self.cascade.generate_evaluation_code(
5828                 code, result, self.operand2)
5829         # Cascaded cmp result is always temp
5830         self.operand2.generate_disposal_code(code)
5831         self.operand2.free_temps(code)
5832         code.putln("}")
5833
5834     def annotate(self, code):
5835         self.operand2.annotate(code)
5836         if self.cascade:
5837             self.cascade.annotate(code)
5838
5839
5840 binop_node_classes = {
5841     "or":       BoolBinopNode,
5842     "and":      BoolBinopNode,
5843     "|":        IntBinopNode,
5844     "^":        IntBinopNode,
5845     "&":        IntBinopNode,
5846     "<<":       IntBinopNode,
5847     ">>":       IntBinopNode,
5848     "+":        AddNode,
5849     "-":        SubNode,
5850     "*":        MulNode,
5851     "/":        DivNode,
5852     "//":       DivNode,
5853     "%":        ModNode,
5854     "**":       PowNode
5855 }
5856
5857 def binop_node(pos, operator, operand1, operand2):
5858     # Construct binop node of appropriate class for 
5859     # given operator.
5860     return binop_node_classes[operator](pos, 
5861         operator = operator, 
5862         operand1 = operand1, 
5863         operand2 = operand2)
5864
5865 #-------------------------------------------------------------------
5866 #
5867 #  Coercion nodes
5868 #
5869 #  Coercion nodes are special in that they are created during
5870 #  the analyse_types phase of parse tree processing.
5871 #  Their __init__ methods consequently incorporate some aspects
5872 #  of that phase.
5873 #
5874 #-------------------------------------------------------------------
5875
5876 class CoercionNode(ExprNode):
5877     #  Abstract base class for coercion nodes.
5878     #
5879     #  arg       ExprNode       node being coerced
5880     
5881     subexprs = ['arg']
5882     constant_result = not_a_constant
5883     
5884     def __init__(self, arg):
5885         self.pos = arg.pos
5886         self.arg = arg
5887         if debug_coercion:
5888             print("%s Coercing %s" % (self, self.arg))
5889
5890     def calculate_constant_result(self):
5891         # constant folding can break type coercion, so this is disabled
5892         pass
5893             
5894     def annotate(self, code):
5895         self.arg.annotate(code)
5896         if self.arg.type != self.type:
5897             file, line, col = self.pos
5898             code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
5899
5900
5901 class CastNode(CoercionNode):
5902     #  Wrap a node in a C type cast.
5903     
5904     def __init__(self, arg, new_type):
5905         CoercionNode.__init__(self, arg)
5906         self.type = new_type
5907     
5908     def calculate_result_code(self):
5909         return self.arg.result_as(self.type)
5910
5911     def generate_result_code(self, code):
5912         self.arg.generate_result_code(code)
5913
5914
5915 class PyTypeTestNode(CoercionNode):
5916     #  This node is used to check that a generic Python
5917     #  object is an instance of a particular extension type.
5918     #  This node borrows the result of its argument node.
5919
5920     def __init__(self, arg, dst_type, env, notnone=False):
5921         #  The arg is know to be a Python object, and
5922         #  the dst_type is known to be an extension type.
5923         assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
5924         CoercionNode.__init__(self, arg)
5925         self.type = dst_type
5926         self.result_ctype = arg.ctype()
5927         self.notnone = notnone
5928
5929     nogil_check = Node.gil_error
5930     gil_message = "Python type test"
5931     
5932     def analyse_types(self, env):
5933         pass
5934     
5935     def result_in_temp(self):
5936         return self.arg.result_in_temp()
5937     
5938     def is_ephemeral(self):
5939         return self.arg.is_ephemeral()
5940
5941     def calculate_constant_result(self):
5942         # FIXME
5943         pass
5944
5945     def calculate_result_code(self):
5946         return self.arg.result()
5947     
5948     def generate_result_code(self, code):
5949         if self.type.typeobj_is_available():
5950             if not self.type.is_builtin_type:
5951                 code.globalstate.use_utility_code(type_test_utility_code)
5952             code.putln(
5953                 "if (!(%s)) %s" % (
5954                     self.type.type_test_code(self.arg.py_result(), self.notnone),
5955                     code.error_goto(self.pos)))
5956         else:
5957             error(self.pos, "Cannot test type of extern C class "
5958                 "without type object name specification")
5959                 
5960     def generate_post_assignment_code(self, code):
5961         self.arg.generate_post_assignment_code(code)
5962
5963     def free_temps(self, code):
5964         self.arg.free_temps(code)
5965
5966
5967 class NoneCheckNode(CoercionNode):
5968     # This node is used to check that a Python object is not None and
5969     # raises an appropriate exception (as specified by the creating
5970     # transform).
5971
5972     def __init__(self, arg, exception_type_cname, exception_message):
5973         CoercionNode.__init__(self, arg)
5974         self.type = arg.type
5975         self.result_ctype = arg.ctype()
5976         self.exception_type_cname = exception_type_cname
5977         self.exception_message = exception_message
5978
5979     def analyse_types(self, env):
5980         pass
5981
5982     def result_in_temp(self):
5983         return self.arg.result_in_temp()
5984
5985     def calculate_result_code(self):
5986         return self.arg.result()
5987     
5988     def generate_result_code(self, code):
5989         code.putln(
5990             "if (unlikely(%s == Py_None)) {" % self.arg.result())
5991         code.putln('PyErr_SetString(%s, "%s"); %s ' % (
5992             self.exception_type_cname,
5993             StringEncoding.escape_byte_string(
5994                 self.exception_message.encode('UTF-8')),
5995             code.error_goto(self.pos)))
5996         code.putln("}")
5997
5998     def generate_post_assignment_code(self, code):
5999         self.arg.generate_post_assignment_code(code)
6000
6001     def free_temps(self, code):
6002         self.arg.free_temps(code)
6003
6004
6005 class CoerceToPyTypeNode(CoercionNode):
6006     #  This node is used to convert a C data type
6007     #  to a Python object.
6008     
6009     type = py_object_type
6010     is_temp = 1
6011
6012     def __init__(self, arg, env, type=py_object_type):
6013         CoercionNode.__init__(self, arg)
6014         if not arg.type.create_to_py_utility_code(env):
6015             error(arg.pos,
6016                 "Cannot convert '%s' to Python object" % arg.type)
6017         if type is not py_object_type:
6018             self.type = py_object_type
6019         elif arg.type.is_string:
6020             self.type = Builtin.bytes_type
6021
6022     gil_message = "Converting to Python object"
6023
6024     def coerce_to_boolean(self, env):
6025         return self.arg.coerce_to_boolean(env).coerce_to_temp(env)
6026     
6027     def coerce_to_integer(self, env):
6028         # If not already some C integer type, coerce to longint.
6029         if self.arg.type.is_int:
6030             return self.arg
6031         else:
6032             return self.arg.coerce_to(PyrexTypes.c_long_type, env)
6033
6034     def analyse_types(self, env):
6035         # The arg is always already analysed
6036         pass
6037
6038     def generate_result_code(self, code):
6039         function = self.arg.type.to_py_function
6040         code.putln('%s = %s(%s); %s' % (
6041             self.result(), 
6042             function, 
6043             self.arg.result(), 
6044             code.error_goto_if_null(self.result(), self.pos)))
6045         code.put_gotref(self.py_result())
6046
6047
6048 class CoerceFromPyTypeNode(CoercionNode):
6049     #  This node is used to convert a Python object
6050     #  to a C data type.
6051
6052     def __init__(self, result_type, arg, env):
6053         CoercionNode.__init__(self, arg)
6054         self.type = result_type
6055         self.is_temp = 1
6056         if not result_type.create_from_py_utility_code(env):
6057             error(arg.pos,
6058                 "Cannot convert Python object to '%s'" % result_type)
6059         if self.type.is_string and self.arg.is_ephemeral():
6060             error(arg.pos,
6061                 "Obtaining char * from temporary Python value")
6062     
6063     def analyse_types(self, env):
6064         # The arg is always already analysed
6065         pass
6066
6067     def generate_result_code(self, code):
6068         function = self.type.from_py_function
6069         operand = self.arg.py_result()
6070         rhs = "%s(%s)" % (function, operand)
6071         if self.type.is_enum:
6072             rhs = typecast(self.type, c_long_type, rhs)
6073         code.putln('%s = %s; %s' % (
6074             self.result(), 
6075             rhs,
6076             code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
6077         if self.type.is_pyobject:
6078             code.put_gotref(self.py_result())
6079
6080
6081 class CoerceToBooleanNode(CoercionNode):
6082     #  This node is used when a result needs to be used
6083     #  in a boolean context.
6084     
6085     type = PyrexTypes.c_bint_type
6086     
6087     def __init__(self, arg, env):
6088         CoercionNode.__init__(self, arg)
6089         if arg.type.is_pyobject:
6090             self.is_temp = 1
6091
6092     def nogil_check(self, env):
6093         if self.arg.type.is_pyobject:
6094             self.gil_error()
6095
6096     gil_message = "Truth-testing Python object"
6097     
6098     def check_const(self):
6099         if self.is_temp:
6100             self.not_const()
6101             return False
6102         return self.arg.check_const()
6103     
6104     def calculate_result_code(self):
6105         return "(%s != 0)" % self.arg.result()
6106
6107     def generate_result_code(self, code):
6108         if self.arg.type.is_pyobject:
6109             code.putln(
6110                 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6111                     self.result(), 
6112                     self.arg.py_result(), 
6113                     code.error_goto_if_neg(self.result(), self.pos)))
6114
6115 class CoerceToComplexNode(CoercionNode):
6116
6117     def __init__(self, arg, dst_type, env):
6118         if arg.type.is_complex:
6119             arg = arg.coerce_to_simple(env)
6120         self.type = dst_type
6121         CoercionNode.__init__(self, arg)
6122         dst_type.create_declaration_utility_code(env)
6123
6124     def calculate_result_code(self):
6125         if self.arg.type.is_complex:
6126             real_part = "__Pyx_CREAL(%s)" % self.arg.result()
6127             imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
6128         else:
6129             real_part = self.arg.result()
6130             imag_part = "0"
6131         return "%s(%s, %s)" % (
6132                 self.type.from_parts,
6133                 real_part,
6134                 imag_part)
6135     
6136     def generate_result_code(self, code):
6137         pass
6138
6139 class CoerceToTempNode(CoercionNode):
6140     #  This node is used to force the result of another node
6141     #  to be stored in a temporary. It is only used if the
6142     #  argument node's result is not already in a temporary.
6143
6144     def __init__(self, arg, env):
6145         CoercionNode.__init__(self, arg)
6146         self.type = self.arg.type
6147         self.is_temp = 1
6148         if self.type.is_pyobject:
6149             self.result_ctype = py_object_type
6150
6151     gil_message = "Creating temporary Python reference"
6152
6153     def analyse_types(self, env):
6154         # The arg is always already analysed
6155         pass
6156         
6157     def coerce_to_boolean(self, env):
6158         self.arg = self.arg.coerce_to_boolean(env)
6159         self.type = self.arg.type
6160         self.result_ctype = self.type
6161         return self
6162
6163     def generate_result_code(self, code):
6164         #self.arg.generate_evaluation_code(code) # Already done
6165         # by generic generate_subexpr_evaluation_code!
6166         code.putln("%s = %s;" % (
6167             self.result(), self.arg.result_as(self.ctype())))
6168         if self.type.is_pyobject and self.use_managed_ref:
6169             code.put_incref(self.result(), self.ctype())
6170
6171
6172 class CloneNode(CoercionNode):
6173     #  This node is employed when the result of another node needs
6174     #  to be used multiple times. The argument node's result must
6175     #  be in a temporary. This node "borrows" the result from the
6176     #  argument node, and does not generate any evaluation or
6177     #  disposal code for it. The original owner of the argument 
6178     #  node is responsible for doing those things.
6179     
6180     subexprs = [] # Arg is not considered a subexpr
6181     nogil_check = None
6182     
6183     def __init__(self, arg):
6184         CoercionNode.__init__(self, arg)
6185         if hasattr(arg, 'type'):
6186             self.type = arg.type
6187             self.result_ctype = arg.result_ctype
6188         if hasattr(arg, 'entry'):
6189             self.entry = arg.entry
6190             
6191     def result(self):
6192         return self.arg.result()
6193     
6194     def type_dependencies(self, env):
6195         return self.arg.type_dependencies(env)
6196     
6197     def infer_type(self, env):
6198         return self.arg.infer_type(env)
6199
6200     def analyse_types(self, env):
6201         self.type = self.arg.type
6202         self.result_ctype = self.arg.result_ctype
6203         self.is_temp = 1
6204         if hasattr(self.arg, 'entry'):
6205             self.entry = self.arg.entry
6206     
6207     def generate_evaluation_code(self, code):
6208         pass
6209
6210     def generate_result_code(self, code):
6211         pass
6212         
6213     def generate_disposal_code(self, code):
6214         pass
6215                 
6216     def free_temps(self, code):
6217         pass
6218
6219
6220 class ModuleRefNode(ExprNode):
6221     # Simple returns the module object
6222     
6223     type = py_object_type
6224     is_temp = False
6225     subexprs = []
6226     
6227     def analyse_types(self, env):
6228         pass
6229
6230     def calculate_result_code(self):
6231         return Naming.module_cname
6232
6233     def generate_result_code(self, code):
6234         pass
6235
6236 class DocstringRefNode(ExprNode):
6237     # Extracts the docstring of the body element
6238     
6239     subexprs = ['body']
6240     type = py_object_type
6241     is_temp = True
6242     
6243     def __init__(self, pos, body):
6244         ExprNode.__init__(self, pos)
6245         assert body.type.is_pyobject
6246         self.body = body
6247
6248     def analyse_types(self, env):
6249         pass
6250
6251     def generate_result_code(self, code):
6252         code.putln('%s = __Pyx_GetAttrString(%s, "__doc__");' %
6253                    (self.result(), self.body.result()))
6254         code.put_gotref(self.result())
6255
6256
6257
6258 #------------------------------------------------------------------------------------
6259 #
6260 #  Runtime support code
6261 #
6262 #------------------------------------------------------------------------------------
6263
6264 get_name_interned_utility_code = UtilityCode(
6265 proto = """
6266 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
6267 """,
6268 impl = """
6269 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
6270     PyObject *result;
6271     result = PyObject_GetAttr(dict, name);
6272     if (!result)
6273         PyErr_SetObject(PyExc_NameError, name);
6274     return result;
6275 }
6276 """)
6277
6278 #------------------------------------------------------------------------------------
6279
6280 import_utility_code = UtilityCode(
6281 proto = """
6282 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
6283 """,
6284 impl = """
6285 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
6286     PyObject *__import__ = 0;
6287     PyObject *empty_list = 0;
6288     PyObject *module = 0;
6289     PyObject *global_dict = 0;
6290     PyObject *empty_dict = 0;
6291     PyObject *list;
6292     __import__ = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
6293     if (!__import__)
6294         goto bad;
6295     if (from_list)
6296         list = from_list;
6297     else {
6298         empty_list = PyList_New(0);
6299         if (!empty_list)
6300             goto bad;
6301         list = empty_list;
6302     }
6303     global_dict = PyModule_GetDict(%(GLOBALS)s);
6304     if (!global_dict)
6305         goto bad;
6306     empty_dict = PyDict_New();
6307     if (!empty_dict)
6308         goto bad;
6309     module = PyObject_CallFunctionObjArgs(__import__,
6310         name, global_dict, empty_dict, list, NULL);
6311 bad:
6312     Py_XDECREF(empty_list);
6313     Py_XDECREF(__import__);
6314     Py_XDECREF(empty_dict);
6315     return module;
6316 }
6317 """ % {
6318     "BUILTINS": Naming.builtins_cname,
6319     "GLOBALS":  Naming.module_cname,
6320 })
6321
6322 #------------------------------------------------------------------------------------
6323
6324 get_exception_utility_code = UtilityCode(
6325 proto = """
6326 static PyObject *__Pyx_GetExcValue(void); /*proto*/
6327 """,
6328 impl = """
6329 static PyObject *__Pyx_GetExcValue(void) {
6330     PyObject *type = 0, *value = 0, *tb = 0;
6331     PyObject *tmp_type, *tmp_value, *tmp_tb;
6332     PyObject *result = 0;
6333     PyThreadState *tstate = PyThreadState_Get();
6334     PyErr_Fetch(&type, &value, &tb);
6335     PyErr_NormalizeException(&type, &value, &tb);
6336     if (PyErr_Occurred())
6337         goto bad;
6338     if (!value) {
6339         value = Py_None;
6340         Py_INCREF(value);
6341     }
6342     tmp_type = tstate->exc_type;
6343     tmp_value = tstate->exc_value;
6344     tmp_tb = tstate->exc_traceback;
6345     tstate->exc_type = type;
6346     tstate->exc_value = value;
6347     tstate->exc_traceback = tb;
6348     /* Make sure tstate is in a consistent state when we XDECREF
6349     these objects (XDECREF may run arbitrary code). */
6350     Py_XDECREF(tmp_type);
6351     Py_XDECREF(tmp_value);
6352     Py_XDECREF(tmp_tb);
6353     result = value;
6354     Py_XINCREF(result);
6355     type = 0;
6356     value = 0;
6357     tb = 0;
6358 bad:
6359     Py_XDECREF(type);
6360     Py_XDECREF(value);
6361     Py_XDECREF(tb);
6362     return result;
6363 }
6364 """)
6365
6366 #------------------------------------------------------------------------------------
6367
6368 type_test_utility_code = UtilityCode(
6369 proto = """
6370 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
6371 """,
6372 impl = """
6373 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
6374     if (unlikely(!type)) {
6375         PyErr_Format(PyExc_SystemError, "Missing type object");
6376         return 0;
6377     }
6378     if (likely(PyObject_TypeCheck(obj, type)))
6379         return 1;
6380     PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
6381                  Py_TYPE(obj)->tp_name, type->tp_name);
6382     return 0;
6383 }
6384 """)
6385
6386 #------------------------------------------------------------------------------------
6387
6388 create_class_utility_code = UtilityCode(
6389 proto = """
6390 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, const char *modname); /*proto*/
6391 """,
6392 impl = """
6393 static PyObject *__Pyx_CreateClass(
6394     PyObject *bases, PyObject *dict, PyObject *name, const char *modname)
6395 {
6396     PyObject *py_modname;
6397     PyObject *result = 0;
6398
6399     #if PY_MAJOR_VERSION < 3
6400     py_modname = PyString_FromString(modname);
6401     #else
6402     py_modname = PyUnicode_FromString(modname);
6403     #endif
6404     if (!py_modname)
6405         goto bad;
6406     if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
6407         goto bad;
6408     #if PY_MAJOR_VERSION < 3
6409     result = PyClass_New(bases, dict, name);
6410     #else
6411     result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
6412     #endif
6413 bad:
6414     Py_XDECREF(py_modname);
6415     return result;
6416 }
6417 """)
6418
6419 #------------------------------------------------------------------------------------
6420
6421 cpp_exception_utility_code = UtilityCode(
6422 proto = """
6423 #ifndef __Pyx_CppExn2PyErr
6424 static void __Pyx_CppExn2PyErr() {
6425   try {
6426     if (PyErr_Occurred())
6427       ; // let the latest Python exn pass through and ignore the current one
6428     else
6429       throw;
6430   } catch (const std::out_of_range& exn) {
6431     // catch out_of_range explicitly so the proper Python exn may be raised
6432     PyErr_SetString(PyExc_IndexError, exn.what());
6433   } catch (const std::exception& exn) {
6434     PyErr_SetString(PyExc_RuntimeError, exn.what());
6435   }
6436   catch (...)
6437   {
6438     PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
6439   }
6440 }
6441 #endif
6442 """,
6443 impl = ""
6444 )
6445
6446 #------------------------------------------------------------------------------------
6447
6448 # If the is_unsigned flag is set, we need to do some extra work to make 
6449 # sure the index doesn't become negative. 
6450
6451 getitem_int_utility_code = UtilityCode(
6452 proto = """
6453
6454 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
6455     PyObject *r;
6456     if (!j) return NULL;
6457     r = PyObject_GetItem(o, j);
6458     Py_DECREF(j);
6459     return r;
6460 }
6461
6462 """ + ''.join([
6463 """
6464 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6465                                                     __Pyx_GetItemInt_%(type)s_Fast(o, i, size <= sizeof(long)) : \\
6466                                                     __Pyx_GetItemInt_Generic(o, to_py_func(i)))
6467
6468 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
6469     if (likely(o != Py_None)) {
6470         if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
6471             PyObject *r = Py%(type)s_GET_ITEM(o, i);
6472             Py_INCREF(r);
6473             return r;
6474         }
6475         else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
6476             PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
6477             Py_INCREF(r);
6478             return r;
6479         }
6480     }
6481     return __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
6482 }
6483 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
6484 ]) + """
6485
6486 #define __Pyx_GetItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6487                                                     __Pyx_GetItemInt_Fast(o, i, size <= sizeof(long)) : \\
6488                                                     __Pyx_GetItemInt_Generic(o, to_py_func(i)))
6489
6490 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
6491     PyObject *r;
6492     if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
6493         r = PyList_GET_ITEM(o, i);
6494         Py_INCREF(r);
6495     }
6496     else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
6497         r = PyTuple_GET_ITEM(o, i);
6498         Py_INCREF(r);
6499     }
6500     else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
6501         r = PySequence_GetItem(o, i);
6502     }
6503     else {
6504         r = __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
6505     }
6506     return r;
6507 }
6508 """,
6509 impl = """
6510 """)
6511
6512
6513
6514 #------------------------------------------------------------------------------------
6515
6516 setitem_int_utility_code = UtilityCode(
6517 proto = """
6518 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6519                                                     __Pyx_SetItemInt_Fast(o, i, v, size <= sizeof(long)) : \\
6520                                                     __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
6521
6522 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
6523     int r;
6524     if (!j) return -1;
6525     r = PyObject_SetItem(o, j, v);
6526     Py_DECREF(j);
6527     return r;
6528 }
6529
6530 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int fits_long) {
6531     if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
6532         Py_INCREF(v);
6533         Py_DECREF(PyList_GET_ITEM(o, i));
6534         PyList_SET_ITEM(o, i, v);
6535         return 1;
6536     }
6537     else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
6538         return PySequence_SetItem(o, i, v);
6539     else {
6540         PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
6541         return __Pyx_SetItemInt_Generic(o, j, v);
6542     }
6543 }
6544 """,
6545 impl = """
6546 """)
6547
6548 #------------------------------------------------------------------------------------
6549
6550 delitem_int_utility_code = UtilityCode(
6551 proto = """
6552 #define __Pyx_DelItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6553                                                     __Pyx_DelItemInt_Fast(o, i, size <= sizeof(long)) : \\
6554                                                     __Pyx_DelItem_Generic(o, to_py_func(i)))
6555
6556 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
6557     int r;
6558     if (!j) return -1;
6559     r = PyObject_DelItem(o, j);
6560     Py_DECREF(j);
6561     return r;
6562 }
6563
6564 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
6565     if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
6566         return PySequence_DelItem(o, i);
6567     else {
6568         PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
6569         return __Pyx_DelItem_Generic(o, j);
6570     }
6571 }
6572 """,
6573 impl = """
6574 """)
6575
6576 #------------------------------------------------------------------------------------
6577
6578 raise_noneattr_error_utility_code = UtilityCode(
6579 proto = """
6580 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
6581 """,
6582 impl = '''
6583 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
6584     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
6585 }
6586 ''')
6587
6588 raise_noneindex_error_utility_code = UtilityCode(
6589 proto = """
6590 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
6591 """,
6592 impl = '''
6593 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
6594     PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
6595 }
6596 ''')
6597
6598 raise_none_iter_error_utility_code = UtilityCode(
6599 proto = """
6600 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
6601 """,
6602 impl = '''
6603 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
6604     PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
6605 }
6606 ''')
6607
6608 raise_too_many_values_to_unpack = UtilityCode(
6609 proto = """
6610 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(void);
6611 """,
6612 impl = '''
6613 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(void) {
6614     PyErr_SetString(PyExc_ValueError, "too many values to unpack");
6615 }
6616 ''')
6617
6618 raise_need_more_values_to_unpack = UtilityCode(
6619 proto = """
6620 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
6621 """,
6622 impl = '''
6623 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
6624     PyErr_Format(PyExc_ValueError,
6625         #if PY_VERSION_HEX < 0x02050000
6626                  "need more than %d value%s to unpack", (int)index,
6627         #else
6628                  "need more than %zd value%s to unpack", index,
6629         #endif
6630                  (index == 1) ? "" : "s");
6631 }
6632 ''')
6633
6634 #------------------------------------------------------------------------------------
6635
6636 tuple_unpacking_error_code = UtilityCode(
6637 proto = """
6638 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
6639 """, 
6640 impl = """
6641 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
6642     if (t == Py_None) {
6643       __Pyx_RaiseNoneNotIterableError();
6644     } else if (PyTuple_GET_SIZE(t) < index) {
6645       __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
6646     } else {
6647       __Pyx_RaiseTooManyValuesError();
6648     }
6649 }
6650 """, 
6651 requires = [raise_none_iter_error_utility_code,
6652             raise_need_more_values_to_unpack,
6653             raise_too_many_values_to_unpack]
6654 )
6655
6656 unpacking_utility_code = UtilityCode(
6657 proto = """
6658 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
6659 static int __Pyx_EndUnpack(PyObject *); /*proto*/
6660 """,
6661 impl = """
6662 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
6663     PyObject *item;
6664     if (!(item = PyIter_Next(iter))) {
6665         if (!PyErr_Occurred()) {
6666             __Pyx_RaiseNeedMoreValuesError(index);
6667         }
6668     }
6669     return item;
6670 }
6671
6672 static int __Pyx_EndUnpack(PyObject *iter) {
6673     PyObject *item;
6674     if ((item = PyIter_Next(iter))) {
6675         Py_DECREF(item);
6676         __Pyx_RaiseTooManyValuesError();
6677         return -1;
6678     }
6679     else if (!PyErr_Occurred())
6680         return 0;
6681     else
6682         return -1;
6683 }
6684 """,
6685 requires = [raise_need_more_values_to_unpack,
6686             raise_too_many_values_to_unpack]
6687 )
6688
6689 #------------------------------------------------------------------------------------
6690
6691 # CPython supports calling functions with non-dict kwargs by
6692 # converting them to a dict first
6693
6694 kwargs_call_utility_code = UtilityCode(
6695 proto = """
6696 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
6697 """,
6698 impl = """
6699 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
6700     PyObject* result;
6701     if (likely(PyDict_Check(kwargs))) {
6702         return PyEval_CallObjectWithKeywords(callable, args, kwargs);
6703     } else {
6704         PyObject* real_dict;
6705         real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
6706         if (unlikely(!real_dict))
6707             return NULL;
6708         result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
6709         Py_DECREF(real_dict);
6710         return result; /* may be NULL */
6711     }
6712 }
6713 """, 
6714 )
6715
6716
6717 #------------------------------------------------------------------------------------
6718
6719 int_pow_utility_code = UtilityCode(
6720 proto="""
6721 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
6722 """,
6723 impl="""
6724 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
6725     %(type)s t = b;
6726     switch (e) {
6727         case 3:
6728             t *= b;
6729         case 2:
6730             t *= b;
6731         case 1:
6732             return t;
6733         case 0:
6734             return 1;
6735     }
6736     if (unlikely(e<0)) return 0;
6737     t = 1;
6738     while (likely(e)) {
6739         t *= (b * (e&1)) | ((~e)&1);    /* 1 or b */
6740         b *= b;
6741         e >>= 1;
6742     }
6743     return t;
6744 }
6745 """)
6746
6747 # ------------------------------ Division ------------------------------------
6748
6749 div_int_utility_code = UtilityCode(
6750 proto="""
6751 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
6752 """,
6753 impl="""
6754 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
6755     %(type)s q = a / b;
6756     %(type)s r = a - q*b;
6757     q -= ((r != 0) & ((r ^ b) < 0));
6758     return q;
6759 }
6760 """)
6761
6762 mod_int_utility_code = UtilityCode(
6763 proto="""
6764 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
6765 """,
6766 impl="""
6767 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
6768     %(type)s r = a %% b;
6769     r += ((r != 0) & ((r ^ b) < 0)) * b;
6770     return r;
6771 }
6772 """)
6773
6774 mod_float_utility_code = UtilityCode(
6775 proto="""
6776 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
6777 """,
6778 impl="""
6779 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
6780     %(type)s r = fmod%(math_h_modifier)s(a, b);
6781     r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
6782     return r;
6783 }
6784 """)
6785
6786 cdivision_warning_utility_code = UtilityCode(
6787 proto="""
6788 static int __Pyx_cdivision_warning(void); /* proto */
6789 """,
6790 impl="""
6791 static int __Pyx_cdivision_warning(void) {
6792     return PyErr_WarnExplicit(PyExc_RuntimeWarning, 
6793                               "division with oppositely signed operands, C and Python semantics differ",
6794                               %(FILENAME)s, 
6795                               %(LINENO)s,
6796                               __Pyx_MODULE_NAME,
6797                               NULL);
6798 }
6799 """ % {
6800     'FILENAME': Naming.filename_cname,
6801     'LINENO':  Naming.lineno_cname,
6802 })
6803
6804 # from intobject.c
6805 division_overflow_test_code = UtilityCode(
6806 proto="""
6807 #define UNARY_NEG_WOULD_OVERFLOW(x)     \
6808         (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
6809 """)