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