optimisation: do not build and test metaclass kwargs if we know the metaclass at...
[cython.git] / Cython / Compiler / Nodes.py
1
2 #
3 #   Pyrex - Parse tree nodes
4 #
5
6 import sys, os, time, copy
7
8 try:
9     set
10 except NameError:
11     # Python 2.3
12     from sets import Set as set
13
14 import Code
15 import Builtin
16 from Errors import error, warning, InternalError
17 import Naming
18 import PyrexTypes
19 import TypeSlots
20 from PyrexTypes import py_object_type, error_type, CFuncType
21 from Symtab import ModuleScope, LocalScope, ClosureScope, \
22     StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
23 from Cython.Utils import open_new_file, replace_suffix
24 from Code import UtilityCode
25 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
26 import Options
27 import ControlFlow
28 import DebugFlags
29
30 absolute_path_length = 0
31
32 def relative_position(pos):
33     """
34     We embed the relative filename in the generated C file, since we
35     don't want to have to regnerate and compile all the source code
36     whenever the Python install directory moves (which could happen,
37     e.g,. when distributing binaries.)
38     
39     INPUT:
40         a position tuple -- (absolute filename, line number column position)
41
42     OUTPUT:
43         relative filename
44         line number
45
46     AUTHOR: William Stein
47     """
48     global absolute_path_length
49     if absolute_path_length==0:
50         absolute_path_length = len(os.path.abspath(os.getcwd())) 
51     return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
52
53 def embed_position(pos, docstring):
54     if not Options.embed_pos_in_docstring:
55         return docstring
56     pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
57     if docstring is None:
58         # unicode string
59         return EncodedString(pos_line)
60
61     # make sure we can encode the filename in the docstring encoding
62     # otherwise make the docstring a unicode string
63     encoding = docstring.encoding
64     if encoding is not None:
65         try:
66             encoded_bytes = pos_line.encode(encoding)
67         except UnicodeEncodeError:
68             encoding = None
69
70     if not docstring:
71         # reuse the string encoding of the original docstring
72         doc = EncodedString(pos_line)
73     else:
74         doc = EncodedString(pos_line + u'\n' + docstring)
75     doc.encoding = encoding
76     return doc
77
78
79 from Code import CCodeWriter
80 from types import FunctionType
81
82 def write_func_call(func):
83     def f(*args, **kwds):
84         if len(args) > 1 and isinstance(args[1], CCodeWriter):
85             # here we annotate the code with this function call
86             # but only if new code is generated
87             node, code = args[:2]
88             marker = '                    /* %s -> %s.%s %s */' % (
89                     ' ' * code.call_level,
90                     node.__class__.__name__, 
91                     func.__name__, 
92                     node.pos[1:])
93             pristine = code.buffer.stream.tell()
94             code.putln(marker)
95             start = code.buffer.stream.tell()
96             code.call_level += 4
97             res = func(*args, **kwds)
98             code.call_level -= 4
99             if start == code.buffer.stream.tell():
100                 code.buffer.stream.seek(pristine)
101             else:
102                 marker = marker.replace('->', '<-')
103                 code.putln(marker)
104             return res
105         else:
106             return func(*args, **kwds)
107     return f
108
109 class VerboseCodeWriter(type):
110     # Set this as a metaclass to trace function calls in code.
111     # This slows down code generation and makes much larger files. 
112     def __new__(cls, name, bases, attrs):
113         attrs = dict(attrs)
114         for mname, m in attrs.items():
115             if isinstance(m, FunctionType):
116                 attrs[mname] = write_func_call(m)
117         return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
118
119
120 class Node(object):
121     #  pos         (string, int, int)   Source file position
122     #  is_name     boolean              Is a NameNode
123     #  is_literal  boolean              Is a ConstNode
124
125     if DebugFlags.debug_trace_code_generation:
126         __metaclass__ = VerboseCodeWriter
127     
128     is_name = 0
129     is_literal = 0
130     temps = None
131
132     # All descandants should set child_attrs to a list of the attributes
133     # containing nodes considered "children" in the tree. Each such attribute
134     # can either contain a single node or a list of nodes. See Visitor.py.
135     child_attrs = None
136     
137     def __init__(self, pos, **kw):
138         self.pos = pos
139         self.__dict__.update(kw)
140     
141     gil_message = "Operation"
142
143     nogil_check = None
144
145     def gil_error(self, env=None):
146         error(self.pos, "%s not allowed without gil" % self.gil_message)
147     
148     cpp_message = "Operation"
149     
150     def cpp_check(self, env):
151         if not env.is_cpp():
152             self.cpp_error()
153
154     def cpp_error(self):
155         error(self.pos, "%s only allowed in c++" % self.cpp_message)
156
157     def clone_node(self):
158         """Clone the node. This is defined as a shallow copy, except for member lists
159            amongst the child attributes (from get_child_accessors) which are also
160            copied. Lists containing child nodes are thus seen as a way for the node
161            to hold multiple children directly; the list is not treated as a seperate
162            level in the tree."""
163         result = copy.copy(self)
164         for attrname in result.child_attrs:
165             value = getattr(result, attrname)
166             if isinstance(value, list):
167                 setattr(result, attrname, [x for x in value])
168         return result
169     
170     
171     #
172     #  There are 4 phases of parse tree processing, applied in order to
173     #  all the statements in a given scope-block:
174     #
175     #  (0) analyse_control_flow
176     #        Create the control flow tree into which state can be asserted and
177     #        queried.
178     #
179     #  (1) analyse_declarations
180     #        Make symbol table entries for all declarations at the current
181     #        level, both explicit (def, cdef, etc.) and implicit (assignment
182     #        to an otherwise undeclared name).
183     #
184     #  (2) analyse_expressions
185     #         Determine the result types of expressions and fill in the
186     #         'type' attribute of each ExprNode. Insert coercion nodes into the
187     #         tree where needed to convert to and from Python objects. 
188     #         Allocate temporary locals for intermediate results. Fill
189     #         in the 'result_code' attribute of each ExprNode with a C code
190     #         fragment.
191     #
192     #  (3) generate_code
193     #         Emit C code for all declarations, statements and expressions.
194     #         Recursively applies the 3 processing phases to the bodies of
195     #         functions.
196     #
197     
198     def analyse_control_flow(self, env):
199         pass
200     
201     def analyse_declarations(self, env):
202         pass
203     
204     def analyse_expressions(self, env):
205         raise InternalError("analyse_expressions not implemented for %s" % \
206             self.__class__.__name__)
207     
208     def generate_code(self, code):
209         raise InternalError("generate_code not implemented for %s" % \
210             self.__class__.__name__)
211             
212     def annotate(self, code):
213         # mro does the wrong thing
214         if isinstance(self, BlockNode):
215             self.body.annotate(code)
216             
217     def end_pos(self):
218         try:
219             return self._end_pos
220         except AttributeError:
221             pos = self.pos
222             if not self.child_attrs:
223                 self._end_pos = pos
224                 return pos
225             for attr in self.child_attrs:
226                 child = getattr(self, attr)
227                 # Sometimes lists, sometimes nodes
228                 if child is None:
229                     pass
230                 elif isinstance(child, list):
231                     for c in child:
232                         pos = max(pos, c.end_pos())
233                 else:
234                     pos = max(pos, child.end_pos())
235             self._end_pos = pos
236             return pos
237
238     def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
239         if cutoff == 0:
240             return "<...nesting level cutoff...>"
241         if encountered is None:
242             encountered = set()
243         if id(self) in encountered:
244             return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
245         encountered.add(id(self))
246         
247         def dump_child(x, level):
248             if isinstance(x, Node):
249                 return x.dump(level, filter_out, cutoff-1, encountered)
250             elif isinstance(x, list):
251                 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
252             else:
253                 return repr(x)
254             
255         
256         attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
257         if len(attrs) == 0:
258             return "<%s (%d)>" % (self.__class__.__name__, id(self))
259         else:
260             indent = "  " * level
261             res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
262             for key, value in attrs:
263                 res += "%s  %s: %s\n" % (indent, key, dump_child(value, level + 1))
264             res += "%s>" % indent
265             return res
266
267 class CompilerDirectivesNode(Node):
268     """
269     Sets compiler directives for the children nodes
270     """
271     #  directives     {string:value}  A dictionary holding the right value for
272     #                                 *all* possible directives.
273     #  body           Node
274     child_attrs = ["body"]
275
276     def analyse_control_flow(self, env):
277         old = env.directives
278         env.directives = self.directives
279         self.body.analyse_control_flow(env)
280         env.directives = old
281
282     def analyse_declarations(self, env):
283         old = env.directives
284         env.directives = self.directives
285         self.body.analyse_declarations(env)
286         env.directives = old
287     
288     def analyse_expressions(self, env):
289         old = env.directives
290         env.directives = self.directives
291         self.body.analyse_expressions(env)
292         env.directives = old
293
294     def generate_function_definitions(self, env, code):
295         env_old = env.directives
296         code_old = code.globalstate.directives
297         code.globalstate.directives = self.directives
298         self.body.generate_function_definitions(env, code)
299         env.directives = env_old
300         code.globalstate.directives = code_old
301             
302     def generate_execution_code(self, code):
303         old = code.globalstate.directives
304         code.globalstate.directives = self.directives
305         self.body.generate_execution_code(code)
306         code.globalstate.directives = old
307             
308     def annotate(self, code):
309         old = code.globalstate.directives
310         code.globalstate.directives = self.directives
311         self.body.annotate(code)
312         code.globalstate.directives = old
313         
314 class BlockNode(object):
315     #  Mixin class for nodes representing a declaration block.
316
317     def generate_cached_builtins_decls(self, env, code):
318         entries = env.global_scope().undeclared_cached_builtins
319         for entry in entries:
320             code.globalstate.add_cached_builtin_decl(entry)
321         del entries[:]
322         
323
324 class StatListNode(Node):
325     # stats     a list of StatNode
326     
327     child_attrs = ["stats"]
328
329     def create_analysed(pos, env, *args, **kw):
330         node = StatListNode(pos, *args, **kw)
331         return node # No node-specific analysis necesarry
332     create_analysed = staticmethod(create_analysed)
333     
334     def analyse_control_flow(self, env):
335         for stat in self.stats:
336             stat.analyse_control_flow(env)
337
338     def analyse_declarations(self, env):
339         #print "StatListNode.analyse_declarations" ###
340         for stat in self.stats:
341             stat.analyse_declarations(env)
342     
343     def analyse_expressions(self, env):
344         #print "StatListNode.analyse_expressions" ###
345         for stat in self.stats:
346             stat.analyse_expressions(env)
347     
348     def generate_function_definitions(self, env, code):
349         #print "StatListNode.generate_function_definitions" ###
350         for stat in self.stats:
351             stat.generate_function_definitions(env, code)
352             
353     def generate_execution_code(self, code):
354         #print "StatListNode.generate_execution_code" ###
355         for stat in self.stats:
356             code.mark_pos(stat.pos)
357             stat.generate_execution_code(code)
358             
359     def annotate(self, code):
360         for stat in self.stats:
361             stat.annotate(code)
362     
363
364 class StatNode(Node):
365     #
366     #  Code generation for statements is split into the following subphases:
367     #
368     #  (1) generate_function_definitions
369     #        Emit C code for the definitions of any structs,
370     #        unions, enums and functions defined in the current
371     #        scope-block.
372     #
373     #  (2) generate_execution_code
374     #        Emit C code for executable statements.
375     #
376     
377     def generate_function_definitions(self, env, code):
378         pass
379     
380     def generate_execution_code(self, code):
381         raise InternalError("generate_execution_code not implemented for %s" % \
382             self.__class__.__name__)
383
384
385 class CDefExternNode(StatNode):
386     #  include_file   string or None
387     #  body           StatNode
388     
389     child_attrs = ["body"]
390     
391     def analyse_declarations(self, env):
392         if self.include_file:
393             env.add_include_file(self.include_file)
394         old_cinclude_flag = env.in_cinclude
395         env.in_cinclude = 1
396         self.body.analyse_declarations(env)
397         env.in_cinclude = old_cinclude_flag
398     
399     def analyse_expressions(self, env):
400         pass
401     
402     def generate_execution_code(self, code):
403         pass
404
405     def annotate(self, code):
406         self.body.annotate(code)
407         
408
409 class CDeclaratorNode(Node):
410     # Part of a C declaration.
411     #
412     # Processing during analyse_declarations phase:
413     #
414     #   analyse
415     #      Returns (name, type) pair where name is the
416     #      CNameDeclaratorNode of the name being declared 
417     #      and type is the type it is being declared as.
418     #
419     #  calling_convention  string   Calling convention of CFuncDeclaratorNode
420     #                               for which this is a base 
421
422     child_attrs = []
423
424     calling_convention = ""
425
426
427 class CNameDeclaratorNode(CDeclaratorNode):
428     #  name    string             The Pyrex name being declared
429     #  cname   string or None     C name, if specified
430     #  default ExprNode or None   the value assigned on declaration
431     
432     child_attrs = ['default']
433     
434     default = None
435     
436     def analyse(self, base_type, env, nonempty = 0):
437         if nonempty and self.name == '':
438             # May have mistaken the name for the type. 
439             if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
440                 error(self.pos, "Missing argument name")
441             elif base_type.is_void:
442                 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
443             else:
444                 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
445                 base_type = py_object_type
446         self.type = base_type
447         return self, base_type
448         
449 class CPtrDeclaratorNode(CDeclaratorNode):
450     # base     CDeclaratorNode
451     
452     child_attrs = ["base"]
453
454     def analyse(self, base_type, env, nonempty = 0):
455         if base_type.is_pyobject:
456             error(self.pos,
457                 "Pointer base type cannot be a Python object")
458         ptr_type = PyrexTypes.c_ptr_type(base_type)
459         return self.base.analyse(ptr_type, env, nonempty = nonempty)
460
461 class CReferenceDeclaratorNode(CDeclaratorNode):
462     # base     CDeclaratorNode
463
464     child_attrs = ["base"]
465
466     def analyse(self, base_type, env, nonempty = 0):
467         if base_type.is_pyobject:
468             error(self.pos,
469                   "Reference base type cannot be a Python object")
470         ref_type = PyrexTypes.c_ref_type(base_type)
471         return self.base.analyse(ref_type, env, nonempty = nonempty)
472
473 class CArrayDeclaratorNode(CDeclaratorNode):
474     # base        CDeclaratorNode
475     # dimension   ExprNode
476
477     child_attrs = ["base", "dimension"]
478     
479     def analyse(self, base_type, env, nonempty = 0):
480         if base_type.is_cpp_class:
481             from ExprNodes import TupleNode
482             if isinstance(self.dimension, TupleNode):
483                 args = self.dimension.args
484             else:
485                 args = self.dimension,
486             values = [v.analyse_as_type(env) for v in args]
487             if None in values:
488                 ix = values.index(None)
489                 error(args[ix].pos, "Template parameter not a type.")
490                 return error_type
491             base_type = base_type.specialize_here(self.pos, values)
492             return self.base.analyse(base_type, env, nonempty = nonempty)
493         if self.dimension:
494             self.dimension.analyse_const_expression(env)
495             if not self.dimension.type.is_int:
496                 error(self.dimension.pos, "Array dimension not integer")
497             size = self.dimension.get_constant_c_result_code()
498             if size is not None:
499                 try:
500                     size = int(size)
501                 except ValueError:
502                     # runtime constant?
503                     pass
504         else:
505             size = None
506         if not base_type.is_complete():
507             error(self.pos,
508                 "Array element type '%s' is incomplete" % base_type)
509         if base_type.is_pyobject:
510             error(self.pos,
511                 "Array element cannot be a Python object")
512         if base_type.is_cfunction:
513             error(self.pos,
514                 "Array element cannot be a function")
515         array_type = PyrexTypes.c_array_type(base_type, size)
516         return self.base.analyse(array_type, env, nonempty = nonempty)
517
518
519 class CFuncDeclaratorNode(CDeclaratorNode):
520     # base             CDeclaratorNode
521     # args             [CArgDeclNode]
522     # has_varargs      boolean
523     # exception_value  ConstNode
524     # exception_check  boolean    True if PyErr_Occurred check needed
525     # nogil            boolean    Can be called without gil
526     # with_gil         boolean    Acquire gil around function body
527     
528     child_attrs = ["base", "args", "exception_value"]
529
530     overridable = 0
531     optional_arg_count = 0
532
533     def analyse(self, return_type, env, nonempty = 0):
534         if nonempty:
535             nonempty -= 1
536         func_type_args = []
537         for i, arg_node in enumerate(self.args):
538             name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
539                                                      is_self_arg = (i == 0 and env.is_c_class_scope))
540             name = name_declarator.name
541             if name_declarator.cname:
542                 error(self.pos, 
543                     "Function argument cannot have C name specification")
544             # Turn *[] argument into **
545             if type.is_array:
546                 type = PyrexTypes.c_ptr_type(type.base_type)
547             # Catch attempted C-style func(void) decl
548             if type.is_void:
549                 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
550             func_type_args.append(
551                 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
552             if arg_node.default:
553                 self.optional_arg_count += 1
554             elif self.optional_arg_count:
555                 error(self.pos, "Non-default argument follows default argument")
556         
557         if self.optional_arg_count:
558             scope = StructOrUnionScope()
559             arg_count_member = '%sn' % Naming.pyrex_prefix
560             scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
561             for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
562                 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
563             struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
564             self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
565                                         kind = 'struct',
566                                         scope = scope,
567                                         typedef_flag = 0,
568                                         pos = self.pos,
569                                         cname = struct_cname)
570             self.op_args_struct.defined_in_pxd = 1
571             self.op_args_struct.used = 1
572         
573         exc_val = None
574         exc_check = 0
575         if self.exception_check == '+':
576             env.add_include_file('stdexcept')
577         if return_type.is_pyobject \
578             and (self.exception_value or self.exception_check) \
579             and self.exception_check != '+':
580                 error(self.pos,
581                     "Exception clause not allowed for function returning Python object")
582         else:
583             if self.exception_value:
584                 self.exception_value.analyse_const_expression(env)
585                 if self.exception_check == '+':
586                     self.exception_value.analyse_types(env)
587                     exc_val_type = self.exception_value.type
588                     if not exc_val_type.is_error and \
589                           not exc_val_type.is_pyobject and \
590                           not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
591                         error(self.exception_value.pos,
592                             "Exception value must be a Python exception or cdef function with no arguments.")
593                     exc_val = self.exception_value
594                 else:
595                     self.exception_value = self.exception_value.coerce_to(return_type, env)
596                     if self.exception_value.analyse_const_expression(env):
597                         exc_val = self.exception_value.get_constant_c_result_code()
598                         if exc_val is None:
599                             raise InternalError("get_constant_c_result_code not implemented for %s" %
600                                 self.exception_value.__class__.__name__)
601                         if not return_type.assignable_from(self.exception_value.type):
602                             error(self.exception_value.pos,
603                                   "Exception value incompatible with function return type")
604             exc_check = self.exception_check
605         if return_type.is_array:
606             error(self.pos,
607                 "Function cannot return an array")
608         if return_type.is_cfunction:
609             error(self.pos,
610                 "Function cannot return a function")
611         func_type = PyrexTypes.CFuncType(
612             return_type, func_type_args, self.has_varargs, 
613             optional_arg_count = self.optional_arg_count,
614             exception_value = exc_val, exception_check = exc_check,
615             calling_convention = self.base.calling_convention,
616             nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
617         if self.optional_arg_count:
618             func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
619         callspec = env.directives['callspec']
620         if callspec:
621             current = func_type.calling_convention
622             if current and current != callspec:
623                 error(self.pos, "cannot have both '%s' and '%s' "
624                       "calling conventions" % (current, callspec))
625             func_type.calling_convention = callspec
626         return self.base.analyse(func_type, env)
627
628
629 class CArgDeclNode(Node):
630     # Item in a function declaration argument list.
631     #
632     # base_type      CBaseTypeNode
633     # declarator     CDeclaratorNode
634     # not_none       boolean            Tagged with 'not None'
635     # or_none        boolean            Tagged with 'or None'
636     # accept_none    boolean            Resolved boolean for not_none/or_none
637     # default        ExprNode or None
638     # default_value  PyObjectConst      constant for default value
639     # annotation     ExprNode or None   Py3 function arg annotation
640     # is_self_arg    boolean            Is the "self" arg of an extension type method
641     # is_type_arg    boolean            Is the "class" arg of an extension type classmethod
642     # is_kw_only     boolean            Is a keyword-only argument
643
644     child_attrs = ["base_type", "declarator", "default"]
645
646     is_self_arg = 0
647     is_type_arg = 0
648     is_generic = 1
649     type = None
650     name_declarator = None
651     default_value = None
652     annotation = None
653
654     def analyse(self, env, nonempty = 0, is_self_arg = False):
655         if is_self_arg:
656             self.base_type.is_self_arg = self.is_self_arg = True
657         if self.type is None:
658             # The parser may missinterpret names as types...
659             # We fix that here.
660             if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
661                 if nonempty:
662                     self.declarator.name = self.base_type.name
663                     self.base_type.name = None
664                     self.base_type.is_basic_c_type = False
665                 could_be_name = True
666             else:
667                 could_be_name = False
668             base_type = self.base_type.analyse(env, could_be_name = could_be_name)
669             if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
670                 self.declarator.name = self.base_type.arg_name
671             # The parser is unable to resolve the ambiguity of [] as part of the 
672             # type (e.g. in buffers) or empty declarator (as with arrays). 
673             # This is only arises for empty multi-dimensional arrays.
674             if (base_type.is_array 
675                     and isinstance(self.base_type, TemplatedTypeNode) 
676                     and isinstance(self.declarator, CArrayDeclaratorNode)):
677                 declarator = self.declarator
678                 while isinstance(declarator.base, CArrayDeclaratorNode):
679                     declarator = declarator.base
680                 declarator.base = self.base_type.array_declarator
681                 base_type = base_type.base_type
682             return self.declarator.analyse(base_type, env, nonempty = nonempty)
683         else:
684             return self.name_declarator, self.type
685
686     def calculate_default_value_code(self, code):
687         if self.default_value is None:
688             if self.default:
689                 if self.default.is_literal:
690                     # will not output any code, just assign the result_code
691                     self.default.generate_evaluation_code(code)
692                     return self.type.cast_code(self.default.result())
693                 self.default_value = code.get_argument_default_const(self.type)
694         return self.default_value
695
696     def annotate(self, code):
697         if self.default:
698             self.default.annotate(code)
699
700
701 class CBaseTypeNode(Node):
702     # Abstract base class for C base type nodes.
703     #
704     # Processing during analyse_declarations phase:
705     #
706     #   analyse
707     #     Returns the type.
708     
709     pass
710     
711     def analyse_as_type(self, env):
712         return self.analyse(env)
713     
714 class CAnalysedBaseTypeNode(Node):
715     # type            type
716     
717     child_attrs = []
718     
719     def analyse(self, env, could_be_name = False):
720         return self.type
721
722 class CSimpleBaseTypeNode(CBaseTypeNode):
723     # name             string
724     # module_path      [string]     Qualifying name components
725     # is_basic_c_type  boolean
726     # signed           boolean
727     # longness         integer
728     # complex          boolean
729     # is_self_arg      boolean      Is self argument of C method
730     # ##is_type_arg      boolean      Is type argument of class method
731
732     child_attrs = []
733     arg_name = None   # in case the argument name was interpreted as a type
734     
735     def analyse(self, env, could_be_name = False):
736         # Return type descriptor.
737         #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
738         type = None
739         if self.is_basic_c_type:
740             type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
741             if not type:
742                 error(self.pos, "Unrecognised type modifier combination")
743         elif self.name == "object" and not self.module_path:
744             type = py_object_type
745         elif self.name is None:
746             if self.is_self_arg and env.is_c_class_scope:
747                 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
748                 type = env.parent_type
749             ## elif self.is_type_arg and env.is_c_class_scope:
750             ##     type = Builtin.type_type
751             else:
752                 type = py_object_type
753         else:
754             if self.module_path:
755                 scope = env.find_imported_module(self.module_path, self.pos)
756             else:
757                 scope = env
758             if scope:
759                 if scope.is_c_class_scope:
760                     scope = scope.global_scope()
761                 entry = scope.lookup(self.name)
762                 if entry and entry.is_type:
763                     type = entry.type
764                 elif could_be_name:
765                     if self.is_self_arg and env.is_c_class_scope:
766                         type = env.parent_type
767                     ## elif self.is_type_arg and env.is_c_class_scope:
768                     ##     type = Builtin.type_type
769                     else:
770                         type = py_object_type
771                     self.arg_name = self.name
772                 else:
773                     if self.templates:
774                         if not self.name in self.templates:
775                             error(self.pos, "'%s' is not a type identifier" % self.name)
776                         type = PyrexTypes.TemplatePlaceholderType(self.name)
777                     else:
778                         error(self.pos, "'%s' is not a type identifier" % self.name)
779         if self.complex:
780             if not type.is_numeric or type.is_complex:
781                 error(self.pos, "can only complexify c numeric types")
782             type = PyrexTypes.CComplexType(type)
783             type.create_declaration_utility_code(env)
784         if type:
785             return type
786         else:
787             return PyrexTypes.error_type
788
789 class CNestedBaseTypeNode(CBaseTypeNode):
790     # For C++ classes that live inside other C++ classes. 
791
792     # name             string
793     # base_type        CBaseTypeNode
794
795     child_attrs = ['base_type']
796
797     def analyse(self, env, could_be_name = None):
798         base_type = self.base_type.analyse(env)
799         if base_type is PyrexTypes.error_type:
800             return PyrexTypes.error_type
801         if not base_type.is_cpp_class:
802             error(self.pos, "'%s' is not a valid type scope" % base_type)
803             return PyrexTypes.error_type
804         type_entry = base_type.scope.lookup_here(self.name)
805         if not type_entry or not type_entry.is_type:
806             error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
807             return PyrexTypes.error_type
808         return type_entry.type
809
810 class TemplatedTypeNode(CBaseTypeNode):
811     #  After parsing:
812     #  positional_args  [ExprNode]        List of positional arguments
813     #  keyword_args     DictNode          Keyword arguments
814     #  base_type_node   CBaseTypeNode
815
816     #  After analysis:
817     #  type             PyrexTypes.BufferType or PyrexTypes.CppClassType  ...containing the right options
818
819
820     child_attrs = ["base_type_node", "positional_args",
821                    "keyword_args", "dtype_node"]
822
823     dtype_node = None
824
825     name = None
826     
827     def analyse(self, env, could_be_name = False, base_type = None):
828         if base_type is None:
829             base_type = self.base_type_node.analyse(env)
830         if base_type.is_error: return base_type
831         
832         if base_type.is_cpp_class:
833             # Templated class
834             if self.keyword_args and self.keyword_args.key_value_pairs:
835                 error(self.pos, "c++ templates cannot take keyword arguments");
836                 self.type = PyrexTypes.error_type
837             else:
838                 template_types = []
839                 for template_node in self.positional_args:
840                     type = template_node.analyse_as_type(env)
841                     if type is None:
842                         error(template_node.pos, "unknown type in template argument")
843                         return error_type
844                     template_types.append(type)
845                 self.type = base_type.specialize_here(self.pos, template_types)
846         
847         elif base_type.is_pyobject:
848             # Buffer
849             import Buffer
850
851             options = Buffer.analyse_buffer_options(
852                 self.pos,
853                 env,
854                 self.positional_args,
855                 self.keyword_args,
856                 base_type.buffer_defaults)
857
858             if sys.version_info[0] < 3:
859                 # Py 2.x enforces byte strings as keyword arguments ...
860                 options = dict([ (name.encode('ASCII'), value)
861                                  for name, value in options.iteritems() ])
862
863             self.type = PyrexTypes.BufferType(base_type, **options)
864         
865         else:
866             # Array
867             empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
868             if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
869                 error(self.pos, "invalid array declaration")
870                 self.type = PyrexTypes.error_type
871             else:
872                 # It would be nice to merge this class with CArrayDeclaratorNode, 
873                 # but arrays are part of the declaration, not the type...
874                 if not self.positional_args:
875                     dimension = None
876                 else:
877                     dimension = self.positional_args[0]
878                 self.array_declarator = CArrayDeclaratorNode(self.pos, 
879                     base = empty_declarator, 
880                     dimension = dimension)
881                 self.type = self.array_declarator.analyse(base_type, env)[1]
882         
883         return self.type
884
885 class CComplexBaseTypeNode(CBaseTypeNode):
886     # base_type   CBaseTypeNode
887     # declarator  CDeclaratorNode
888     
889     child_attrs = ["base_type", "declarator"]
890
891     def analyse(self, env, could_be_name = False):
892         base = self.base_type.analyse(env, could_be_name)
893         _, type = self.declarator.analyse(base, env)
894         return type
895
896
897 class CVarDefNode(StatNode):
898     #  C variable definition or forward/extern function declaration.
899     #
900     #  visibility    'private' or 'public' or 'extern'
901     #  base_type     CBaseTypeNode
902     #  declarators   [CDeclaratorNode]
903     #  in_pxd        boolean
904     #  api           boolean
905
906     #  decorators    [cython.locals(...)] or None 
907     #  directive_locals { string : NameNode } locals defined by cython.locals(...)
908
909     child_attrs = ["base_type", "declarators"]
910     
911     decorators = None
912     directive_locals = {}
913     
914     def analyse_declarations(self, env, dest_scope = None):
915         if not dest_scope:
916             dest_scope = env
917         self.dest_scope = dest_scope
918         base_type = self.base_type.analyse(env)
919
920         # If the field is an external typedef, we cannot be sure about the type,
921         # so do conversion ourself rather than rely on the CPython mechanism (through
922         # a property; made in AnalyseDeclarationsTransform).
923         if (dest_scope.is_c_class_scope
924             and self.visibility in ('public', 'readonly')):
925             need_property = True
926         else:
927             need_property = False
928         visibility = self.visibility
929             
930         for declarator in self.declarators:
931             name_declarator, type = declarator.analyse(base_type, env)
932             if not type.is_complete():
933                 if not (self.visibility == 'extern' and type.is_array):
934                     error(declarator.pos,
935                         "Variable type '%s' is incomplete" % type)
936             if self.visibility == 'extern' and type.is_pyobject:
937                 error(declarator.pos,
938                     "Python object cannot be declared extern")
939             name = name_declarator.name
940             cname = name_declarator.cname
941             if name == '':
942                 error(declarator.pos, "Missing name in declaration.")
943                 return
944             if type.is_cfunction:
945                 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
946                     cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
947                     api = self.api)
948                 if entry is not None:
949                     entry.directive_locals = self.directive_locals
950             else:
951                 if self.directive_locals:
952                     s.error("Decorators can only be followed by functions")
953                 if self.in_pxd and self.visibility != 'extern':
954                     error(self.pos, 
955                         "Only 'extern' C variable declaration allowed in .pxd file")
956                 entry = dest_scope.declare_var(name, type, declarator.pos,
957                             cname = cname, visibility = visibility, is_cdef = 1)
958                 entry.needs_property = need_property
959     
960
961 class CStructOrUnionDefNode(StatNode):
962     #  name          string
963     #  cname         string or None
964     #  kind          "struct" or "union"
965     #  typedef_flag  boolean
966     #  visibility    "public" or "private"
967     #  in_pxd        boolean
968     #  attributes    [CVarDefNode] or None
969     #  entry         Entry
970     #  packed        boolean
971     
972     child_attrs = ["attributes"]
973
974     def analyse_declarations(self, env):
975         scope = None
976         if self.visibility == 'extern' and self.packed:
977             error(self.pos, "Cannot declare extern struct as 'packed'")
978         if self.attributes is not None:
979             scope = StructOrUnionScope(self.name)
980         self.entry = env.declare_struct_or_union(
981             self.name, self.kind, scope, self.typedef_flag, self.pos,
982             self.cname, visibility = self.visibility, packed = self.packed)
983         if self.attributes is not None:
984             if self.in_pxd and not env.in_cinclude:
985                 self.entry.defined_in_pxd = 1
986             for attr in self.attributes:
987                 attr.analyse_declarations(env, scope)
988             if self.visibility != 'extern':
989                 need_typedef_indirection = False
990                 for attr in scope.var_entries:
991                     type = attr.type
992                     while type.is_array:
993                         type = type.base_type
994                     if type == self.entry.type:
995                         error(attr.pos, "Struct cannot contain itself as a member.")
996                     if self.typedef_flag:
997                         while type.is_ptr:
998                             type = type.base_type
999                         if type == self.entry.type:
1000                             need_typedef_indirection = True
1001                 if need_typedef_indirection:
1002                     # C can't handle typedef structs that refer to themselves. 
1003                     struct_entry = self.entry
1004                     self.entry = env.declare_typedef(
1005                         self.name, struct_entry.type, self.pos,
1006                         cname = self.cname, visibility='ignore')
1007                     struct_entry.type.typedef_flag = False
1008                     # FIXME: this might be considered a hack ;-)
1009                     struct_entry.cname = struct_entry.type.cname = \
1010                                          '_' + self.entry.type.typedef_cname
1011     
1012     def analyse_expressions(self, env):
1013         pass
1014     
1015     def generate_execution_code(self, code):
1016         pass
1017
1018
1019 class CppClassNode(CStructOrUnionDefNode):
1020
1021     #  name          string
1022     #  cname         string or None
1023     #  visibility    "extern"
1024     #  in_pxd        boolean
1025     #  attributes    [CVarDefNode] or None
1026     #  entry         Entry
1027     #  base_classes  [string]
1028     #  templates     [string] or None
1029
1030     def analyse_declarations(self, env):
1031         scope = None
1032         if self.attributes is not None:
1033             scope = CppClassScope(self.name, env)
1034         base_class_types = []
1035         for base_class_name in self.base_classes:
1036             base_class_entry = env.lookup(base_class_name)
1037             if base_class_entry is None:
1038                 error(self.pos, "'%s' not found" % base_class_name)
1039             elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1040                 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1041             else:
1042                 base_class_types.append(base_class_entry.type)
1043         if self.templates is None:
1044             template_types = None
1045         else:
1046             template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1047         self.entry = env.declare_cpp_class(
1048             self.name, scope, self.pos,
1049             self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1050         self.entry.is_cpp_class = 1
1051         if self.attributes is not None:
1052             if self.in_pxd and not env.in_cinclude:
1053                 self.entry.defined_in_pxd = 1
1054             for attr in self.attributes:
1055                 attr.analyse_declarations(scope)
1056
1057 class CEnumDefNode(StatNode):
1058     #  name           string or None
1059     #  cname          string or None
1060     #  items          [CEnumDefItemNode]
1061     #  typedef_flag   boolean
1062     #  visibility     "public" or "private"
1063     #  in_pxd         boolean
1064     #  entry          Entry
1065     
1066     child_attrs = ["items"]
1067     
1068     def analyse_declarations(self, env):
1069         self.entry = env.declare_enum(self.name, self.pos,
1070             cname = self.cname, typedef_flag = self.typedef_flag,
1071             visibility = self.visibility)
1072         if self.items is not None:
1073             if self.in_pxd and not env.in_cinclude:
1074                 self.entry.defined_in_pxd = 1
1075             for item in self.items:
1076                 item.analyse_declarations(env, self.entry)
1077
1078     def analyse_expressions(self, env):
1079         pass
1080
1081     def generate_execution_code(self, code):
1082         if self.visibility == 'public':
1083             temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1084             for item in self.entry.enum_values:
1085                 code.putln("%s = PyInt_FromLong(%s); %s" % (
1086                         temp,
1087                         item.cname,
1088                         code.error_goto_if_null(temp, item.pos)))
1089                 code.put_gotref(temp)
1090                 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1091                         Naming.module_cname, 
1092                         item.name, 
1093                         temp,
1094                         code.error_goto(item.pos)))
1095                 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1096             code.funcstate.release_temp(temp)
1097
1098
1099 class CEnumDefItemNode(StatNode):
1100     #  name     string
1101     #  cname    string or None
1102     #  value    ExprNode or None
1103     
1104     child_attrs = ["value"]
1105
1106     def analyse_declarations(self, env, enum_entry):
1107         if self.value:
1108             self.value.analyse_const_expression(env)
1109             if not self.value.type.is_int:
1110                 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1111                 self.value.analyse_const_expression(env)
1112         entry = env.declare_const(self.name, enum_entry.type, 
1113             self.value, self.pos, cname = self.cname,
1114             visibility = enum_entry.visibility)
1115         enum_entry.enum_values.append(entry)
1116
1117
1118 class CTypeDefNode(StatNode):
1119     #  base_type    CBaseTypeNode
1120     #  declarator   CDeclaratorNode
1121     #  visibility   "public" or "private"
1122     #  in_pxd       boolean
1123
1124     child_attrs = ["base_type", "declarator"]
1125     
1126     def analyse_declarations(self, env):
1127         base = self.base_type.analyse(env)
1128         name_declarator, type = self.declarator.analyse(base, env)
1129         name = name_declarator.name
1130         cname = name_declarator.cname
1131         entry = env.declare_typedef(name, type, self.pos,
1132             cname = cname, visibility = self.visibility)
1133         if self.in_pxd and not env.in_cinclude:
1134             entry.defined_in_pxd = 1
1135     
1136     def analyse_expressions(self, env):
1137         pass
1138     def generate_execution_code(self, code):
1139         pass
1140
1141
1142 class FuncDefNode(StatNode, BlockNode):
1143     #  Base class for function definition nodes.
1144     #
1145     #  return_type     PyrexType
1146     #  #filename        string        C name of filename string const
1147     #  entry           Symtab.Entry
1148     #  needs_closure   boolean        Whether or not this function has inner functions/classes/yield
1149     #  directive_locals { string : NameNode } locals defined by cython.locals(...)
1150     
1151     py_func = None
1152     assmt = None
1153     needs_closure = False
1154     modifiers = []
1155     
1156     def analyse_default_values(self, env):
1157         genv = env.global_scope()
1158         default_seen = 0
1159         for arg in self.args:
1160             if arg.default:
1161                 default_seen = 1
1162                 if arg.is_generic:
1163                     arg.default.analyse_types(env)
1164                     arg.default = arg.default.coerce_to(arg.type, genv)
1165                 else:
1166                     error(arg.pos,
1167                         "This argument cannot have a default value")
1168                     arg.default = None
1169             elif arg.kw_only:
1170                 default_seen = 1
1171             elif default_seen:
1172                 error(arg.pos, "Non-default argument following default argument")
1173
1174     def need_gil_acquisition(self, lenv):
1175         return 0
1176         
1177     def create_local_scope(self, env):
1178         genv = env
1179         while genv.is_py_class_scope or genv.is_c_class_scope:
1180             genv = env.outer_scope
1181         if self.needs_closure:
1182             lenv = ClosureScope(name=self.entry.name,
1183                                 outer_scope = genv,
1184                                 scope_name=self.entry.cname)
1185         else:
1186             lenv = LocalScope(name=self.entry.name,
1187                               outer_scope=genv,
1188                               parent_scope=env)
1189         lenv.return_type = self.return_type
1190         type = self.entry.type
1191         if type.is_cfunction:
1192             lenv.nogil = type.nogil and not type.with_gil
1193         self.local_scope = lenv
1194         lenv.directives = env.directives
1195         return lenv
1196                 
1197     def generate_function_definitions(self, env, code):
1198         import Buffer
1199
1200         lenv = self.local_scope
1201         if lenv.is_closure_scope:
1202             outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1203                                             Naming.outer_scope_cname)
1204         else:
1205             outer_scope_cname = Naming.outer_scope_cname
1206         lenv.mangle_closure_cnames(outer_scope_cname)
1207         # Generate closure function definitions
1208         self.body.generate_function_definitions(lenv, code)
1209         # generate lambda function definitions
1210         for node in lenv.lambda_defs:
1211             node.generate_function_definitions(lenv, code)
1212
1213         is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1214                              self.entry.scope.is_c_class_scope)
1215         is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1216                                  self.entry.scope.is_c_class_scope)
1217         is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1218         if is_buffer_slot:
1219             if 'cython_unused' not in self.modifiers:
1220                 self.modifiers = self.modifiers + ['cython_unused']
1221
1222         preprocessor_guard = None
1223         if self.entry.is_special and not is_buffer_slot:
1224             slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1225             if slot:
1226                 preprocessor_guard = slot.preprocessor_guard_code()
1227                 if (self.entry.name == '__long__' and
1228                     not self.entry.scope.lookup_here('__int__')):
1229                     preprocessor_guard = None
1230         
1231         profile = code.globalstate.directives['profile']
1232         if profile:
1233             if lenv.nogil:
1234                 error(self.pos, "Cannot profile nogil function.")
1235             code.globalstate.use_utility_code(profile_utility_code)
1236
1237         # Generate C code for header and body of function
1238         code.enter_cfunc_scope()
1239         code.return_from_error_cleanup_label = code.new_label()
1240             
1241         # ----- Top-level constants used by this function
1242         code.mark_pos(self.pos)
1243         self.generate_cached_builtins_decls(lenv, code)
1244         # ----- Function header
1245         code.putln("")
1246
1247         if preprocessor_guard:
1248             code.putln(preprocessor_guard)
1249
1250         with_pymethdef = self.needs_assignment_synthesis(env, code)
1251         if self.py_func:
1252             self.py_func.generate_function_header(code, 
1253                 with_pymethdef = with_pymethdef,
1254                 proto_only=True)
1255         self.generate_function_header(code,
1256             with_pymethdef = with_pymethdef)
1257         # ----- Local variable declarations
1258         if lenv.is_closure_scope:
1259             code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1260             code.putln(";")
1261         elif env.is_closure_scope:
1262             code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
1263             code.putln(";")
1264         self.generate_argument_declarations(lenv, code)
1265         for entry in lenv.var_entries:
1266             if not entry.in_closure:
1267                 code.put_var_declaration(entry)
1268         init = ""
1269         if not self.return_type.is_void:
1270             if self.return_type.is_pyobject:
1271                 init = " = NULL"
1272             code.putln(
1273                 "%s%s;" % 
1274                     (self.return_type.declaration_code(Naming.retval_cname),
1275                      init))
1276         tempvardecl_code = code.insertion_point()
1277         self.generate_keyword_list(code)
1278         if profile:
1279             code.put_trace_declarations()
1280         # ----- Extern library function declarations
1281         lenv.generate_library_function_declarations(code)
1282         # ----- GIL acquisition
1283         acquire_gil = self.acquire_gil
1284         if acquire_gil:
1285             env.use_utility_code(force_init_threads_utility_code)
1286             code.putln("#ifdef WITH_THREAD")
1287             code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1288             code.putln("#endif")
1289         # ----- set up refnanny
1290         if not lenv.nogil:
1291             code.put_setup_refcount_context(self.entry.name)
1292         # ----- Automatic lead-ins for certain special functions
1293         if is_getbuffer_slot:
1294             self.getbuffer_init(code)
1295         # ----- Create closure scope object
1296         if self.needs_closure:
1297             code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1298                 Naming.cur_scope_cname,
1299                 lenv.scope_class.type.declaration_code(''),
1300                 lenv.scope_class.type.typeptr_cname, 
1301                 lenv.scope_class.type.typeptr_cname,
1302                 Naming.empty_tuple))
1303             code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1304             if is_getbuffer_slot:
1305                 self.getbuffer_error_cleanup(code)
1306             if not lenv.nogil:
1307                 code.put_finish_refcount_context()
1308             # FIXME: what if the error return value is a Python value?
1309             code.putln("return %s;" % self.error_value())
1310             code.putln("}")
1311             code.put_gotref(Naming.cur_scope_cname)
1312             # Note that it is unsafe to decref the scope at this point.
1313         if env.is_closure_scope:
1314             code.putln("%s = (%s)%s;" % (
1315                             outer_scope_cname,
1316                             env.scope_class.type.declaration_code(''),
1317                             Naming.self_cname))
1318             if self.needs_closure:
1319                 # inner closures own a reference to their outer parent
1320                 code.put_incref(outer_scope_cname, env.scope_class.type)
1321                 code.put_giveref(outer_scope_cname)
1322         # ----- Trace function call
1323         if profile:
1324             # this looks a bit late, but if we don't get here due to a
1325             # fatal error before hand, it's not really worth tracing
1326             code.put_trace_call(self.entry.name, self.pos)
1327         # ----- Fetch arguments
1328         self.generate_argument_parsing_code(env, code)
1329         # If an argument is assigned to in the body, we must 
1330         # incref it to properly keep track of refcounts.
1331         for entry in lenv.arg_entries:
1332             if entry.type.is_pyobject:
1333                 if entry.assignments and not entry.in_closure:
1334                     code.put_var_incref(entry)
1335         # ----- Initialise local variables 
1336         for entry in lenv.var_entries:
1337             if entry.type.is_pyobject and entry.init_to_none and entry.used:
1338                 code.put_init_var_to_py_none(entry)
1339         # ----- Initialise local buffer auxiliary variables
1340         for entry in lenv.var_entries + lenv.arg_entries:
1341             if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1342                 code.putln("%s.buf = NULL;" %
1343                            entry.buffer_aux.buffer_info_var.cname)
1344         # ----- Check and convert arguments
1345         self.generate_argument_type_tests(code)
1346         # ----- Acquire buffer arguments
1347         for entry in lenv.arg_entries:
1348             if entry.type.is_buffer:
1349                 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1350
1351         # -------------------------
1352         # ----- Function body -----
1353         # -------------------------
1354         self.body.generate_execution_code(code)
1355
1356         # ----- Default return value
1357         code.putln("")
1358         if self.return_type.is_pyobject:
1359             #if self.return_type.is_extension_type:
1360             #    lhs = "(PyObject *)%s" % Naming.retval_cname
1361             #else:
1362             lhs = Naming.retval_cname
1363             code.put_init_to_py_none(lhs, self.return_type)
1364         else:
1365             val = self.return_type.default_value
1366             if val:
1367                 code.putln("%s = %s;" % (Naming.retval_cname, val))
1368         # ----- Error cleanup
1369         if code.error_label in code.labels_used:
1370             code.put_goto(code.return_label)
1371             code.put_label(code.error_label)
1372             for cname, type in code.funcstate.all_managed_temps():
1373                 code.put_xdecref(cname, type)
1374
1375             # Clean up buffers -- this calls a Python function
1376             # so need to save and restore error state
1377             buffers_present = len(lenv.buffer_entries) > 0
1378             if buffers_present:
1379                 code.globalstate.use_utility_code(restore_exception_utility_code)
1380                 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1381                 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1382                 for entry in lenv.buffer_entries:                    
1383                     Buffer.put_release_buffer_code(code, entry)
1384                     #code.putln("%s = 0;" % entry.cname)
1385                 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1386
1387             err_val = self.error_value()
1388             exc_check = self.caller_will_check_exceptions()
1389             if err_val is not None or exc_check:
1390                 # TODO: Fix exception tracing (though currently unused by cProfile). 
1391                 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1392                 # code.put_trace_exception()
1393                 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1394             else:
1395                 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1396                             % self.entry.qualified_name, 0)
1397                 code.putln(
1398                     '__Pyx_WriteUnraisable("%s");' % 
1399                         self.entry.qualified_name)
1400                 env.use_utility_code(unraisable_exception_utility_code)
1401                 env.use_utility_code(restore_exception_utility_code)
1402             default_retval = self.return_type.default_value
1403             if err_val is None and default_retval:
1404                 err_val = default_retval
1405             if err_val is not None:
1406                 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1407
1408             if is_getbuffer_slot:
1409                 self.getbuffer_error_cleanup(code)
1410
1411             # If we are using the non-error cleanup section we should
1412             # jump past it if we have an error. The if-test below determine
1413             # whether this section is used.
1414             if buffers_present or is_getbuffer_slot:
1415                 code.put_goto(code.return_from_error_cleanup_label)
1416
1417
1418         # ----- Non-error return cleanup
1419         code.put_label(code.return_label)
1420         for entry in lenv.buffer_entries:
1421             if entry.used:
1422                 Buffer.put_release_buffer_code(code, entry)
1423         if is_getbuffer_slot:
1424             self.getbuffer_normal_cleanup(code)
1425         # ----- Return cleanup for both error and no-error return
1426         code.put_label(code.return_from_error_cleanup_label)
1427         if not Options.init_local_none:
1428             for entry in lenv.var_entries:
1429                 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1430                     entry.xdecref_cleanup = 1
1431         
1432         for entry in lenv.var_entries:
1433             if entry.type.is_pyobject:
1434                 if entry.used and not entry.in_closure:
1435                     code.put_var_decref(entry)
1436                 elif entry.in_closure and self.needs_closure:
1437                     code.put_giveref(entry.cname)
1438         # Decref any increfed args
1439         for entry in lenv.arg_entries:
1440             if entry.type.is_pyobject:
1441                 if entry.in_closure:
1442                     code.put_var_giveref(entry)
1443                 elif entry.assignments:
1444                     code.put_var_decref(entry)
1445         if self.needs_closure:
1446             code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1447                 
1448         # ----- Return
1449         # This code is duplicated in ModuleNode.generate_module_init_func
1450         if not lenv.nogil:
1451             default_retval = self.return_type.default_value
1452             err_val = self.error_value()
1453             if err_val is None and default_retval:
1454                 err_val = default_retval
1455             if self.return_type.is_pyobject:
1456                 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1457
1458         if self.entry.is_special and self.entry.name == "__hash__":
1459             # Returning -1 for __hash__ is supposed to signal an error
1460             # We do as Python instances and coerce -1 into -2. 
1461             code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1462                     Naming.retval_cname, Naming.retval_cname))
1463
1464         if profile:
1465             if self.return_type.is_pyobject:
1466                 code.put_trace_return(Naming.retval_cname)
1467             else:
1468                 code.put_trace_return("Py_None")
1469         if not lenv.nogil:
1470             code.put_finish_refcount_context()
1471         
1472         if acquire_gil:
1473             code.putln("#ifdef WITH_THREAD")
1474             code.putln("PyGILState_Release(_save);")
1475             code.putln("#endif")
1476
1477         if not self.return_type.is_void:
1478             code.putln("return %s;" % Naming.retval_cname)
1479             
1480         code.putln("}")
1481
1482         if preprocessor_guard:
1483             code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1484
1485         # ----- Go back and insert temp variable declarations
1486         tempvardecl_code.put_temp_declarations(code.funcstate)
1487         # ----- Python version
1488         code.exit_cfunc_scope()
1489         if self.py_func:
1490             self.py_func.generate_function_definitions(env, code)
1491         self.generate_wrapper_functions(code)
1492
1493     def declare_argument(self, env, arg):
1494         if arg.type.is_void:
1495             error(arg.pos, "Invalid use of 'void'")
1496         elif not arg.type.is_complete() and not arg.type.is_array:
1497             error(arg.pos,
1498                 "Argument type '%s' is incomplete" % arg.type)
1499         return env.declare_arg(arg.name, arg.type, arg.pos)
1500     
1501     def generate_arg_type_test(self, arg, code):
1502         # Generate type test for one argument.
1503         if arg.type.typeobj_is_available():
1504             code.globalstate.use_utility_code(arg_type_test_utility_code)
1505             typeptr_cname = arg.type.typeptr_cname
1506             arg_code = "((PyObject *)%s)" % arg.entry.cname
1507             code.putln(
1508                 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1509                     arg_code, 
1510                     typeptr_cname,
1511                     arg.accept_none,
1512                     arg.name,
1513                     arg.type.is_builtin_type,
1514                     code.error_goto(arg.pos)))
1515         else:
1516             error(arg.pos, "Cannot test type of extern C class "
1517                 "without type object name specification")
1518
1519     def generate_arg_none_check(self, arg, code):
1520         # Generate None check for one argument.
1521         code.globalstate.use_utility_code(arg_type_test_utility_code)
1522         code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1523         code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1524             arg.name,
1525             code.error_goto(arg.pos)))
1526         code.putln('}')
1527         
1528     def generate_wrapper_functions(self, code):
1529         pass
1530
1531     def generate_execution_code(self, code):
1532         # Evaluate and store argument default values
1533         for arg in self.args:
1534             default = arg.default
1535             if default:
1536                 if not default.is_literal:
1537                     default.generate_evaluation_code(code)
1538                     default.make_owned_reference(code)
1539                     result = default.result_as(arg.type)
1540                     code.putln(
1541                         "%s = %s;" % (
1542                             arg.calculate_default_value_code(code),
1543                             result))
1544                     if arg.type.is_pyobject:
1545                         code.put_giveref(default.result())
1546                     default.generate_post_assignment_code(code)
1547                     default.free_temps(code)
1548         # For Python class methods, create and store function object
1549         if self.assmt:
1550             self.assmt.generate_execution_code(code)
1551
1552     #
1553     # Special code for the __getbuffer__ function
1554     #
1555     def getbuffer_init(self, code):
1556         info = self.local_scope.arg_entries[1].cname
1557         # Python 3.0 betas have a bug in memoryview which makes it call
1558         # getbuffer with a NULL parameter. For now we work around this;
1559         # the following line should be removed when this bug is fixed.
1560         code.putln("if (%s == NULL) return 0;" % info) 
1561         code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1562         code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1563
1564     def getbuffer_error_cleanup(self, code):
1565         info = self.local_scope.arg_entries[1].cname
1566         code.put_gotref("%s->obj" % info)
1567         code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1568                    (info, info))
1569
1570     def getbuffer_normal_cleanup(self, code):
1571         info = self.local_scope.arg_entries[1].cname
1572         code.putln("if (%s->obj == Py_None) {" % info)
1573         code.put_gotref("Py_None")
1574         code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1575         code.putln("}")
1576
1577 class CFuncDefNode(FuncDefNode):
1578     #  C function definition.
1579     #
1580     #  modifiers     ['inline']
1581     #  visibility    'private' or 'public' or 'extern'
1582     #  base_type     CBaseTypeNode
1583     #  declarator    CDeclaratorNode
1584     #  body          StatListNode
1585     #  api           boolean
1586     #  decorators    [DecoratorNode]        list of decorators
1587     #
1588     #  with_gil      boolean    Acquire GIL around body
1589     #  type          CFuncType
1590     #  py_func       wrapper for calling from Python
1591     #  overridable   whether or not this is a cpdef function
1592     #  inline_in_pxd whether this is an inline function in a pxd file
1593     
1594     child_attrs = ["base_type", "declarator", "body", "py_func"]
1595
1596     inline_in_pxd = False
1597     decorators = None
1598     directive_locals = {}
1599
1600     def unqualified_name(self):
1601         return self.entry.name
1602         
1603     def analyse_declarations(self, env):
1604         self.directive_locals.update(env.directives['locals'])
1605         base_type = self.base_type.analyse(env)
1606         # The 2 here is because we need both function and argument names.
1607         name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1608         if not type.is_cfunction:
1609             error(self.pos, 
1610                 "Suite attached to non-function declaration")
1611         # Remember the actual type according to the function header
1612         # written here, because the type in the symbol table entry
1613         # may be different if we're overriding a C method inherited
1614         # from the base type of an extension type.
1615         self.type = type
1616         type.is_overridable = self.overridable
1617         declarator = self.declarator
1618         while not hasattr(declarator, 'args'):
1619             declarator = declarator.base
1620         self.args = declarator.args
1621         for formal_arg, type_arg in zip(self.args, type.args):
1622             formal_arg.type = type_arg.type
1623             formal_arg.name = type_arg.name
1624             formal_arg.cname = type_arg.cname
1625         name = name_declarator.name
1626         cname = name_declarator.cname
1627         self.entry = env.declare_cfunction(
1628             name, type, self.pos, 
1629             cname = cname, visibility = self.visibility,
1630             defining = self.body is not None,
1631             api = self.api, modifiers = self.modifiers)
1632         self.entry.inline_func_in_pxd = self.inline_in_pxd
1633         self.return_type = type.return_type
1634         
1635         if self.overridable and not env.is_module_scope:
1636             if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1637                 # An error will be produced in the cdef function
1638                 self.overridable = False
1639             
1640         if self.overridable:
1641             import ExprNodes
1642             py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1643             self.py_func = DefNode(pos = self.pos, 
1644                                    name = self.entry.name,
1645                                    args = self.args,
1646                                    star_arg = None,
1647                                    starstar_arg = None,
1648                                    doc = self.doc,
1649                                    body = py_func_body,
1650                                    is_wrapper = 1)
1651             self.py_func.is_module_scope = env.is_module_scope
1652             self.py_func.analyse_declarations(env)
1653             self.entry.as_variable = self.py_func.entry
1654             # Reset scope entry the above cfunction
1655             env.entries[name] = self.entry
1656             if not env.is_module_scope or Options.lookup_module_cpdef:
1657                 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1658                 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1659         self.create_local_scope(env)
1660     
1661     def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1662         import ExprNodes
1663         args = self.type.args
1664         if omit_optional_args:
1665             args = args[:len(args) - self.type.optional_arg_count]
1666         arg_names = [arg.name for arg in args]
1667         if is_module_scope:
1668             cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1669         else:
1670             self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1671             cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1672         skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1673         c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1-is_module_scope:]], wrapper_call=skip_dispatch)
1674         return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1675     
1676     def declare_arguments(self, env):
1677         for arg in self.type.args:
1678             if not arg.name:
1679                 error(arg.pos, "Missing argument name")
1680             self.declare_argument(env, arg)
1681
1682     def need_gil_acquisition(self, lenv):
1683         return self.type.with_gil
1684
1685     def nogil_check(self, env):
1686         type = self.type
1687         with_gil = type.with_gil
1688         if type.nogil and not with_gil:
1689             if type.return_type.is_pyobject:
1690                 error(self.pos,
1691                       "Function with Python return type cannot be declared nogil")
1692             for entry in self.local_scope.var_entries:
1693                 if entry.type.is_pyobject:
1694                     error(self.pos, "Function declared nogil has Python locals or temporaries")
1695
1696     def analyse_expressions(self, env):
1697         self.local_scope.directives = env.directives
1698         if self.py_func is not None:
1699             # this will also analyse the default values
1700             self.py_func.analyse_expressions(env)
1701         else:
1702             self.analyse_default_values(env)
1703         self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1704
1705     def needs_assignment_synthesis(self, env, code=None):
1706         return False
1707
1708     def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1709         arg_decls = []
1710         type = self.type
1711         visibility = self.entry.visibility
1712         for arg in type.args[:len(type.args)-type.optional_arg_count]:
1713             arg_decls.append(arg.declaration_code())
1714         if with_dispatch and self.overridable:
1715             arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1716         if type.optional_arg_count and with_opt_args:
1717             arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1718         if type.has_varargs:
1719             arg_decls.append("...")
1720         if not arg_decls:
1721             arg_decls = ["void"]
1722         if cname is None:
1723             cname = self.entry.func_cname
1724         entity = type.function_header_code(cname, ', '.join(arg_decls))
1725         if visibility == 'public':
1726             dll_linkage = "DL_EXPORT"
1727         else:
1728             dll_linkage = None
1729         header = self.return_type.declaration_code(entity,
1730             dll_linkage = dll_linkage)
1731         if visibility == 'extern':
1732             storage_class = "%s " % Naming.extern_c_macro
1733         elif visibility == 'public':
1734             storage_class = ""
1735         else:
1736             storage_class = "static "
1737         if 'inline' in self.modifiers:
1738             self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1739         code.putln("%s%s %s {" % (
1740             storage_class,
1741             ' '.join(self.modifiers).upper(), # macro forms 
1742             header))
1743
1744     def generate_argument_declarations(self, env, code):
1745         for arg in self.args:
1746             if arg.default:
1747                 result = arg.calculate_default_value_code(code)
1748                 code.putln('%s = %s;' % (
1749                     arg.type.declaration_code(arg.cname), result))
1750
1751     def generate_keyword_list(self, code):
1752         pass
1753         
1754     def generate_argument_parsing_code(self, env, code):
1755         i = 0
1756         if self.type.optional_arg_count:
1757             code.putln('if (%s) {' % Naming.optional_args_cname)
1758             for arg in self.args:
1759                 if arg.default:
1760                     code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1761                     declarator = arg.declarator
1762                     while not hasattr(declarator, 'name'):
1763                         declarator = declarator.base
1764                     code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1765                     i += 1
1766             for _ in range(self.type.optional_arg_count):
1767                 code.putln('}')
1768             code.putln('}')
1769     
1770     def generate_argument_conversion_code(self, code):
1771         pass
1772     
1773     def generate_argument_type_tests(self, code):
1774         # Generate type tests for args whose type in a parent
1775         # class is a supertype of the declared type.
1776         for arg in self.type.args:
1777             if arg.needs_type_test:
1778                 self.generate_arg_type_test(arg, code)
1779             elif arg.type.is_pyobject and not arg.accept_none:
1780                 self.generate_arg_none_check(arg, code)
1781
1782     def error_value(self):
1783         if self.return_type.is_pyobject:
1784             return "0"
1785         else:
1786             #return None
1787             return self.entry.type.exception_value
1788             
1789     def caller_will_check_exceptions(self):
1790         return self.entry.type.exception_check
1791         
1792     def generate_wrapper_functions(self, code):
1793         # If the C signature of a function has changed, we need to generate
1794         # wrappers to put in the slots here. 
1795         k = 0
1796         entry = self.entry
1797         func_type = entry.type
1798         while entry.prev_entry is not None:
1799             k += 1
1800             entry = entry.prev_entry
1801             entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1802             code.putln()
1803             self.generate_function_header(code, 
1804                                           0,
1805                                           with_dispatch = entry.type.is_overridable, 
1806                                           with_opt_args = entry.type.optional_arg_count, 
1807                                           cname = entry.func_cname)
1808             if not self.return_type.is_void:
1809                 code.put('return ')
1810             args = self.type.args
1811             arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1812             if entry.type.is_overridable:
1813                 arglist.append(Naming.skip_dispatch_cname)
1814             elif func_type.is_overridable:
1815                 arglist.append('0')
1816             if entry.type.optional_arg_count:
1817                 arglist.append(Naming.optional_args_cname)
1818             elif func_type.optional_arg_count:
1819                 arglist.append('NULL')
1820             code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1821             code.putln('}')
1822         
1823
1824 class PyArgDeclNode(Node):
1825     # Argument which must be a Python object (used
1826     # for * and ** arguments).
1827     #
1828     # name        string
1829     # entry       Symtab.Entry
1830     # annotation  ExprNode or None   Py3 argument annotation
1831     child_attrs = []
1832
1833     def generate_function_definitions(self, env, code):
1834         self.entry.generate_function_definitions(env, code)
1835
1836 class DecoratorNode(Node):
1837     # A decorator
1838     #
1839     # decorator    NameNode or CallNode or AttributeNode
1840     child_attrs = ['decorator']
1841
1842
1843 class DefNode(FuncDefNode):
1844     # A Python function definition.
1845     #
1846     # name          string                 the Python name of the function
1847     # lambda_name   string                 the internal name of a lambda 'function'
1848     # decorators    [DecoratorNode]        list of decorators
1849     # args          [CArgDeclNode]         formal arguments
1850     # star_arg      PyArgDeclNode or None  * argument
1851     # starstar_arg  PyArgDeclNode or None  ** argument
1852     # doc           EncodedString or None
1853     # body          StatListNode
1854     # return_type_annotation
1855     #               ExprNode or None       the Py3 return type annotation
1856     #
1857     #  The following subnode is constructed internally
1858     #  when the def statement is inside a Python class definition.
1859     #
1860     #  assmt   AssignmentNode   Function construction/assignment
1861     
1862     child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1863
1864     lambda_name = None
1865     assmt = None
1866     num_kwonly_args = 0
1867     num_required_kw_args = 0
1868     reqd_kw_flags_cname = "0"
1869     is_wrapper = 0
1870     decorators = None
1871     return_type_annotation = None
1872     entry = None
1873     acquire_gil = 0
1874     self_in_stararg = 0
1875
1876     def __init__(self, pos, **kwds):
1877         FuncDefNode.__init__(self, pos, **kwds)
1878         k = rk = r = 0
1879         for arg in self.args:
1880             if arg.kw_only:
1881                 k += 1
1882                 if not arg.default:
1883                     rk += 1
1884             if not arg.default:
1885                 r += 1
1886         self.num_kwonly_args = k
1887         self.num_required_kw_args = rk
1888         self.num_required_args = r
1889         
1890     def as_cfunction(self, cfunc=None, scope=None):
1891         if self.star_arg:
1892             error(self.star_arg.pos, "cdef function cannot have star argument")
1893         if self.starstar_arg:
1894             error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1895         if cfunc is None:
1896             cfunc_args = []
1897             for formal_arg in self.args:
1898                 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1899                 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1900                                                           cname = None,
1901                                                           type = py_object_type,
1902                                                           pos = formal_arg.pos))
1903             cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1904                                               args = cfunc_args,
1905                                               has_varargs = False,
1906                                               exception_value = None,
1907                                               exception_check = False,
1908                                               nogil = False,
1909                                               with_gil = False,
1910                                               is_overridable = True)
1911             cfunc = CVarDefNode(self.pos, type=cfunc_type)
1912         else:
1913             if scope is None:
1914                 scope = cfunc.scope
1915             cfunc_type = cfunc.type
1916             if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1917                 error(self.pos, "wrong number of arguments")
1918                 error(cfunc.pos, "previous declaration here")
1919             for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1920                 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1921                                                            is_self_arg = (i == 0 and scope.is_c_class_scope))
1922                 if type is None or type is PyrexTypes.py_object_type:
1923                     formal_arg.type = type_arg.type
1924                     formal_arg.name_declarator = name_declarator
1925         import ExprNodes
1926         if cfunc_type.exception_value is None:
1927             exception_value = None
1928         else:
1929             exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1930         declarator = CFuncDeclaratorNode(self.pos, 
1931                                          base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1932                                          args = self.args,
1933                                          has_varargs = False,
1934                                          exception_check = cfunc_type.exception_check,
1935                                          exception_value = exception_value,
1936                                          with_gil = cfunc_type.with_gil,
1937                                          nogil = cfunc_type.nogil)
1938         return CFuncDefNode(self.pos, 
1939                             modifiers = [],
1940                             base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1941                             declarator = declarator,
1942                             body = self.body,
1943                             doc = self.doc,
1944                             overridable = cfunc_type.is_overridable,
1945                             type = cfunc_type,
1946                             with_gil = cfunc_type.with_gil,
1947                             nogil = cfunc_type.nogil,
1948                             visibility = 'private',
1949                             api = False,
1950                             directive_locals = getattr(cfunc, 'directive_locals', {}))
1951     
1952     def analyse_declarations(self, env):
1953         self.is_classmethod = self.is_staticmethod = False
1954         if self.decorators:
1955             for decorator in self.decorators:
1956                 func = decorator.decorator
1957                 if func.is_name:
1958                     self.is_classmethod |= func.name == 'classmethod'
1959                     self.is_staticmethod |= func.name == 'staticmethod'
1960
1961         if self.is_classmethod and env.lookup_here('classmethod'):
1962             # classmethod() was overridden - not much we can do here ...
1963             self.is_classmethod = False
1964         if self.is_staticmethod and env.lookup_here('staticmethod'):
1965             # staticmethod() was overridden - not much we can do here ...
1966             self.is_staticmethod = False
1967
1968         if self.name == '__new__':
1969             self.is_staticmethod = 1
1970
1971         self.analyse_argument_types(env)
1972         if self.name == '<lambda>':
1973             self.declare_lambda_function(env)
1974         else:
1975             self.declare_pyfunction(env)
1976         self.analyse_signature(env)
1977         self.return_type = self.entry.signature.return_type()
1978         self.create_local_scope(env)
1979
1980     def analyse_argument_types(self, env):
1981         directive_locals = self.directive_locals = env.directives['locals']
1982         allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1983         for arg in self.args:
1984             if hasattr(arg, 'name'):
1985                 type = arg.type
1986                 name_declarator = None
1987             else:
1988                 base_type = arg.base_type.analyse(env)
1989                 name_declarator, type = \
1990                     arg.declarator.analyse(base_type, env)
1991                 arg.name = name_declarator.name
1992             if arg.name in directive_locals:
1993                 type_node = directive_locals[arg.name]
1994                 other_type = type_node.analyse_as_type(env)
1995                 if other_type is None:
1996                     error(type_node.pos, "Not a type")
1997                 elif (type is not PyrexTypes.py_object_type 
1998                         and not type.same_as(other_type)):
1999                     error(arg.base_type.pos, "Signature does not agree with previous declaration")
2000                     error(type_node.pos, "Previous declaration here")
2001                 else:
2002                     type = other_type
2003             if name_declarator and name_declarator.cname:
2004                 error(self.pos,
2005                     "Python function argument cannot have C name specification")
2006             arg.type = type.as_argument_type()
2007             arg.hdr_type = None
2008             arg.needs_conversion = 0
2009             arg.needs_type_test = 0
2010             arg.is_generic = 1
2011             if arg.type.is_pyobject:
2012                 if arg.or_none:
2013                     arg.accept_none = True
2014                 elif arg.not_none:
2015                     arg.accept_none = False
2016                 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2017                     if arg.default and arg.default.constant_result is None:
2018                         # special case: def func(MyType obj = None)
2019                         arg.accept_none = True
2020                     else:
2021                         # default depends on compiler directive
2022                         arg.accept_none = allow_none_for_extension_args
2023                 else:
2024                     # probably just a plain 'object'
2025                     arg.accept_none = True
2026             else:
2027                 arg.accept_none = True # won't be used, but must be there
2028                 if arg.not_none:
2029                     error(arg.pos, "Only Python type arguments can have 'not None'")
2030                 if arg.or_none:
2031                     error(arg.pos, "Only Python type arguments can have 'or None'")
2032
2033     def analyse_signature(self, env):
2034         if self.entry.is_special:
2035             self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2036         elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2037             # Use the simpler calling signature for zero- and one-argument functions.
2038             if self.entry.signature is TypeSlots.pyfunction_signature:
2039                 if len(self.args) == 0:
2040                     self.entry.signature = TypeSlots.pyfunction_noargs
2041                 elif len(self.args) == 1:
2042                     if self.args[0].default is None and not self.args[0].kw_only:
2043                         self.entry.signature = TypeSlots.pyfunction_onearg
2044             elif self.entry.signature is TypeSlots.pymethod_signature:
2045                 if len(self.args) == 1:
2046                     self.entry.signature = TypeSlots.unaryfunc
2047                 elif len(self.args) == 2:
2048                     if self.args[1].default is None and not self.args[1].kw_only:
2049                         self.entry.signature = TypeSlots.ibinaryfunc
2050
2051         sig = self.entry.signature
2052         nfixed = sig.num_fixed_args()
2053         if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2054                and len(self.args) == 0 and self.star_arg:
2055             # this is the only case where a diverging number of
2056             # arguments is not an error - when we have no explicit
2057             # 'self' parameter as in method(*args)
2058             sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2059             self.self_in_stararg = 1
2060             nfixed = 0
2061
2062         for i in range(min(nfixed, len(self.args))):
2063             arg = self.args[i]
2064             arg.is_generic = 0
2065             if sig.is_self_arg(i) and not self.is_staticmethod:
2066                 if self.is_classmethod:
2067                     arg.is_type_arg = 1
2068                     arg.hdr_type = arg.type = Builtin.type_type
2069                 else:
2070                     arg.is_self_arg = 1
2071                     arg.hdr_type = arg.type = env.parent_type
2072                 arg.needs_conversion = 0
2073             else:
2074                 arg.hdr_type = sig.fixed_arg_type(i)
2075                 if not arg.type.same_as(arg.hdr_type):
2076                     if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2077                         arg.needs_type_test = 1
2078                     else:
2079                         arg.needs_conversion = 1
2080             if arg.needs_conversion:
2081                 arg.hdr_cname = Naming.arg_prefix + arg.name
2082             else:
2083                 arg.hdr_cname = Naming.var_prefix + arg.name
2084
2085         if nfixed > len(self.args):
2086             self.bad_signature()
2087             return
2088         elif nfixed < len(self.args):
2089             if not sig.has_generic_args:
2090                 self.bad_signature()
2091             for arg in self.args:
2092                 if arg.is_generic and \
2093                         (arg.type.is_extension_type or arg.type.is_builtin_type):
2094                     arg.needs_type_test = 1
2095
2096     def bad_signature(self):
2097         sig = self.entry.signature
2098         expected_str = "%d" % sig.num_fixed_args()
2099         if sig.has_generic_args:
2100             expected_str = expected_str + " or more"
2101         name = self.name
2102         if name.startswith("__") and name.endswith("__"):
2103             desc = "Special method"
2104         else:
2105             desc = "Method"
2106         error(self.pos,
2107             "%s %s has wrong number of arguments "
2108             "(%d declared, %s expected)" % (
2109                 desc, self.name, len(self.args), expected_str))
2110
2111     def signature_has_nongeneric_args(self):
2112         argcount = len(self.args)
2113         if argcount == 0 or (
2114                 argcount == 1 and (self.args[0].is_self_arg or
2115                                    self.args[0].is_type_arg)):
2116             return 0
2117         return 1
2118
2119     def signature_has_generic_args(self):
2120         return self.entry.signature.has_generic_args
2121     
2122     def declare_pyfunction(self, env):
2123         #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2124         name = self.name
2125         entry = env.lookup_here(name)
2126         if entry and entry.type.is_cfunction and not self.is_wrapper:
2127             warning(self.pos, "Overriding cdef method with def method.", 5)
2128         entry = env.declare_pyfunction(name, self.pos)
2129         self.entry = entry
2130         prefix = env.scope_prefix
2131         entry.func_cname = \
2132             Naming.pyfunc_prefix + prefix + name
2133         entry.pymethdef_cname = \
2134             Naming.pymethdef_prefix + prefix + name
2135         if Options.docstrings:
2136             entry.doc = embed_position(self.pos, self.doc)
2137             entry.doc_cname = \
2138                 Naming.funcdoc_prefix + prefix + name
2139             if entry.is_special:
2140                 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2141                     entry.wrapperbase_cname = None
2142                 else:
2143                     entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2144         else:
2145             entry.doc = None
2146
2147     def declare_lambda_function(self, env):
2148         name = self.name
2149         prefix = env.scope_prefix
2150         func_cname = \
2151             Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2152         entry = env.declare_lambda_function(func_cname, self.pos)
2153         entry.pymethdef_cname = \
2154             Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2155         entry.qualified_name = env.qualify_name(self.lambda_name)
2156         entry.doc = None
2157         self.entry = entry
2158
2159     def declare_arguments(self, env):
2160         for arg in self.args:
2161             if not arg.name:
2162                 error(arg.pos, "Missing argument name")
2163             else:
2164                 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2165                 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2166             if arg.needs_conversion:
2167                 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2168                 if arg.type.is_pyobject:
2169                     arg.entry.init = "0"
2170                 arg.entry.init_to_none = 0
2171             else:
2172                 arg.entry = self.declare_argument(env, arg)
2173             arg.entry.used = 1
2174             arg.entry.is_self_arg = arg.is_self_arg
2175             if arg.hdr_type:
2176                 if arg.is_self_arg or arg.is_type_arg or \
2177                     (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2178                         arg.entry.is_declared_generic = 1
2179         self.declare_python_arg(env, self.star_arg)
2180         self.declare_python_arg(env, self.starstar_arg)
2181
2182     def declare_python_arg(self, env, arg):
2183         if arg:
2184             if env.directives['infer_types'] != False:
2185                 type = PyrexTypes.unspecified_type
2186             else:
2187                 type = py_object_type
2188             entry = env.declare_var(arg.name, type, arg.pos)
2189             entry.used = 1
2190             entry.init = "0"
2191             entry.init_to_none = 0
2192             entry.xdecref_cleanup = 1
2193             arg.entry = entry
2194             env.control_flow.set_state((), (arg.name, 'initialized'), True)
2195             
2196     def analyse_expressions(self, env):
2197         self.local_scope.directives = env.directives
2198         self.analyse_default_values(env)
2199         if self.needs_assignment_synthesis(env):
2200             # Shouldn't we be doing this at the module level too?
2201             self.synthesize_assignment_node(env)
2202
2203     def needs_assignment_synthesis(self, env, code=None):
2204         # Should enable for module level as well, that will require more testing...
2205         if env.is_module_scope:
2206             if code is None:
2207                 return env.directives['binding']
2208             else:
2209                 return code.globalstate.directives['binding']
2210         return env.is_py_class_scope or env.is_closure_scope
2211
2212     def synthesize_assignment_node(self, env):
2213         import ExprNodes
2214         if env.is_py_class_scope:
2215             rhs = ExprNodes.PyCFunctionNode(self.pos,
2216                         pymethdef_cname = self.entry.pymethdef_cname)
2217             if not self.is_staticmethod and not self.is_classmethod:
2218                 rhs.binding = True
2219
2220         elif env.is_closure_scope:
2221             rhs = ExprNodes.InnerFunctionNode(
2222                 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2223         else:
2224             rhs = ExprNodes.PyCFunctionNode(
2225                 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2226         self.assmt = SingleAssignmentNode(self.pos,
2227             lhs = ExprNodes.NameNode(self.pos, name = self.name),
2228             rhs = rhs)
2229         self.assmt.analyse_declarations(env)
2230         self.assmt.analyse_expressions(env)
2231             
2232     def generate_function_header(self, code, with_pymethdef, proto_only=0):
2233         arg_code_list = []
2234         sig = self.entry.signature
2235         if sig.has_dummy_arg or self.self_in_stararg:
2236             arg_code_list.append(
2237                 "PyObject *%s" % Naming.self_cname)
2238         for arg in self.args:
2239             if not arg.is_generic:
2240                 if arg.is_self_arg or arg.is_type_arg:
2241                     arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2242                 else:
2243                     arg_code_list.append(
2244                         arg.hdr_type.declaration_code(arg.hdr_cname))
2245         if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2246             arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2247         if sig.has_generic_args:
2248             arg_code_list.append(
2249                 "PyObject *%s, PyObject *%s"
2250                     % (Naming.args_cname, Naming.kwds_cname))
2251         arg_code = ", ".join(arg_code_list)
2252         dc = self.return_type.declaration_code(self.entry.func_cname)
2253         mf = " ".join(self.modifiers).upper()
2254         if mf: mf += " "
2255         header = "static %s%s(%s)" % (mf, dc, arg_code)
2256         code.putln("%s; /*proto*/" % header)
2257         if proto_only:
2258             return
2259         if (Options.docstrings and self.entry.doc and
2260                 not self.entry.scope.is_property_scope and
2261                 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2262             docstr = self.entry.doc
2263             if docstr.is_unicode:
2264                 docstr = docstr.utf8encode()
2265             code.putln(
2266                 'static char %s[] = "%s";' % (
2267                     self.entry.doc_cname,
2268                     split_string_literal(escape_byte_string(docstr))))
2269             if self.entry.is_special:
2270                 code.putln(
2271                     "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2272         if with_pymethdef:
2273             code.put(
2274                 "static PyMethodDef %s = " % 
2275                     self.entry.pymethdef_cname)
2276             code.put_pymethoddef(self.entry, ";", allow_skip=False)
2277         code.putln("%s {" % header)
2278
2279     def generate_argument_declarations(self, env, code):
2280         for arg in self.args:
2281             if arg.is_generic: # or arg.needs_conversion:
2282                 if arg.needs_conversion:
2283                     code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2284                 elif not arg.entry.in_closure:
2285                     code.put_var_declaration(arg.entry)
2286
2287     def generate_keyword_list(self, code):
2288         if self.signature_has_generic_args() and \
2289                 self.signature_has_nongeneric_args():
2290             code.put(
2291                 "static PyObject **%s[] = {" %
2292                     Naming.pykwdlist_cname)
2293             for arg in self.args:
2294                 if arg.is_generic:
2295                     pystring_cname = code.intern_identifier(arg.name)
2296                     code.put('&%s,' % pystring_cname)
2297             code.putln("0};")
2298
2299     def generate_argument_parsing_code(self, env, code):
2300         # Generate PyArg_ParseTuple call for generic
2301         # arguments, if any.
2302         if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2303             # get rid of unused argument warning
2304             code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2305
2306         old_error_label = code.new_error_label()
2307         our_error_label = code.error_label
2308         end_label = code.new_label("argument_unpacking_done")
2309
2310         has_kwonly_args = self.num_kwonly_args > 0
2311         has_star_or_kw_args = self.star_arg is not None \
2312             or self.starstar_arg is not None or has_kwonly_args
2313
2314         for arg in self.args:
2315             if not arg.type.is_pyobject:
2316                 done = arg.type.create_from_py_utility_code(env)
2317                 if not done: pass # will fail later
2318
2319         if not self.signature_has_generic_args():
2320             if has_star_or_kw_args:
2321                 error(self.pos, "This method cannot have * or keyword arguments")
2322             self.generate_argument_conversion_code(code)
2323
2324         elif not self.signature_has_nongeneric_args():
2325             # func(*args) or func(**kw) or func(*args, **kw)
2326             self.generate_stararg_copy_code(code)
2327
2328         else:
2329             positional_args = []
2330             kw_only_args = []
2331             for arg in self.args:
2332                 arg_entry = arg.entry
2333                 if arg.is_generic:
2334                     if arg.default:
2335                         if not arg.is_self_arg and not arg.is_type_arg:
2336                             if arg.kw_only:
2337                                 kw_only_args.append(arg)
2338                             else:
2339                                 positional_args.append(arg)
2340                     elif arg.kw_only:
2341                         kw_only_args.append(arg)
2342                     elif not arg.is_self_arg and not arg.is_type_arg:
2343                         positional_args.append(arg)
2344
2345             self.generate_tuple_and_keyword_parsing_code(
2346                 positional_args, kw_only_args, end_label, code)
2347
2348         code.error_label = old_error_label
2349         if code.label_used(our_error_label):
2350             if not code.label_used(end_label):
2351                 code.put_goto(end_label)
2352             code.put_label(our_error_label)
2353             if has_star_or_kw_args:
2354                 self.generate_arg_decref(self.star_arg, code)
2355                 if self.starstar_arg:
2356                     if self.starstar_arg.entry.xdecref_cleanup:
2357                         code.put_var_xdecref(self.starstar_arg.entry)
2358                     else:
2359                         code.put_var_decref(self.starstar_arg.entry)
2360             code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2361             # The arguments are put into the closure one after the
2362             # other, so when type errors are found, all references in
2363             # the closure instance must be properly ref-counted to
2364             # facilitate generic closure instance deallocation.  In
2365             # the case of an argument type error, it's best to just
2366             # DECREF+clear the already handled references, as this
2367             # frees their references as early as possible.
2368             for arg in self.args:
2369                 if arg.type.is_pyobject and arg.entry.in_closure:
2370                     code.put_var_xdecref_clear(arg.entry)
2371             if self.needs_closure:
2372                 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2373             code.put_finish_refcount_context()
2374             code.putln("return %s;" % self.error_value())
2375         if code.label_used(end_label):
2376             code.put_label(end_label)
2377
2378     def generate_arg_assignment(self, arg, item, code):
2379         if arg.type.is_pyobject:
2380             if arg.is_generic:
2381                 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2382             entry = arg.entry
2383             code.putln("%s = %s;" % (entry.cname, item))
2384             if entry.in_closure:
2385                 code.put_var_incref(entry)
2386         else:
2387             func = arg.type.from_py_function
2388             if func:
2389                 code.putln("%s = %s(%s); %s" % (
2390                     arg.entry.cname,
2391                     func,
2392                     item,
2393                     code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2394             else:
2395                 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2396     
2397     def generate_arg_xdecref(self, arg, code):
2398         if arg:
2399             code.put_var_xdecref(arg.entry)
2400     
2401     def generate_arg_decref(self, arg, code):
2402         if arg:
2403             code.put_var_decref(arg.entry)
2404
2405     def generate_stararg_copy_code(self, code):
2406         if not self.star_arg:
2407             code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2408             code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2409                        Naming.args_cname)
2410             code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2411                     self.name, Naming.args_cname, self.error_value()))
2412             code.putln("}")
2413
2414         code.globalstate.use_utility_code(keyword_string_check_utility_code)
2415
2416         if self.starstar_arg:
2417             if self.star_arg:
2418                 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2419             else:
2420                 kwarg_check = "%s" % Naming.kwds_cname
2421         else:
2422             kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2423                 Naming.kwds_cname, Naming.kwds_cname)
2424         code.putln(
2425             "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2426                 kwarg_check, Naming.kwds_cname, self.name,
2427                 bool(self.starstar_arg), self.error_value()))
2428
2429         if self.starstar_arg:
2430             code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2431                     self.starstar_arg.entry.cname,
2432                     Naming.kwds_cname,
2433                     Naming.kwds_cname))
2434             code.putln("if (unlikely(!%s)) return %s;" % (
2435                     self.starstar_arg.entry.cname, self.error_value()))
2436             self.starstar_arg.entry.xdecref_cleanup = 0
2437             code.put_gotref(self.starstar_arg.entry.cname)
2438
2439         if self.self_in_stararg:
2440             # need to create a new tuple with 'self' inserted as first item
2441             code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2442                     self.star_arg.entry.cname,
2443                     Naming.args_cname,
2444                     self.star_arg.entry.cname))
2445             if self.starstar_arg:
2446                 code.putln("{")
2447                 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2448                 code.putln("return %s;" % self.error_value())
2449                 code.putln("}")
2450             else:
2451                 code.putln("return %s;" % self.error_value())
2452             code.put_gotref(self.star_arg.entry.cname)
2453             code.put_incref(Naming.self_cname, py_object_type)
2454             code.put_giveref(Naming.self_cname)
2455             code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2456                 self.star_arg.entry.cname, Naming.self_cname))
2457             temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2458             code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2459                 temp, temp, Naming.args_cname, temp))
2460             code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2461                 Naming.args_cname, temp))
2462             code.put_incref("item", py_object_type)
2463             code.put_giveref("item")
2464             code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2465                 self.star_arg.entry.cname, temp))
2466             code.putln("}")
2467             code.funcstate.release_temp(temp)
2468             self.star_arg.entry.xdecref_cleanup = 0
2469         elif self.star_arg:
2470             code.put_incref(Naming.args_cname, py_object_type)
2471             code.putln("%s = %s;" % (
2472                     self.star_arg.entry.cname,
2473                     Naming.args_cname))
2474             self.star_arg.entry.xdecref_cleanup = 0
2475
2476     def generate_tuple_and_keyword_parsing_code(self, positional_args,
2477                                                 kw_only_args, success_label, code):
2478         argtuple_error_label = code.new_label("argtuple_error")
2479
2480         min_positional_args = self.num_required_args - self.num_required_kw_args
2481         if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2482             min_positional_args -= 1
2483         max_positional_args = len(positional_args)
2484         has_fixed_positional_count = not self.star_arg and \
2485             min_positional_args == max_positional_args
2486
2487         code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2488         code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2489         if self.num_required_kw_args:
2490             code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2491
2492         if self.starstar_arg or self.star_arg:
2493             self.generate_stararg_init_code(max_positional_args, code)
2494
2495         # --- optimised code when we receive keyword arguments
2496         if self.num_required_kw_args:
2497             likely_hint = "likely"
2498         else:
2499             likely_hint = "unlikely"
2500         code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2501         self.generate_keyword_unpacking_code(
2502             min_positional_args, max_positional_args,
2503             has_fixed_positional_count,
2504             positional_args, kw_only_args, argtuple_error_label, code)
2505
2506         # --- optimised code when we do not receive any keyword arguments
2507         if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2508             # Python raises arg tuple related errors first, so we must
2509             # check the length here
2510             if min_positional_args == max_positional_args and not self.star_arg:
2511                 compare = '!='
2512             else:
2513                 compare = '<'
2514             code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2515                     Naming.args_cname, compare, min_positional_args))
2516             code.put_goto(argtuple_error_label)
2517
2518         if self.num_required_kw_args:
2519             # pure error case: keywords required but not passed
2520             if max_positional_args > min_positional_args and not self.star_arg:
2521                 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2522                         Naming.args_cname, max_positional_args))
2523                 code.put_goto(argtuple_error_label)
2524             code.putln('} else {')
2525             for i, arg in enumerate(kw_only_args):
2526                 if not arg.default:
2527                     pystring_cname = code.intern_identifier(arg.name)
2528                     # required keyword-only argument missing
2529                     code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2530                             self.name,
2531                             pystring_cname))
2532                     code.putln(code.error_goto(self.pos))
2533                     break
2534
2535         elif min_positional_args == max_positional_args:
2536             # parse the exact number of positional arguments from the
2537             # args tuple
2538             code.putln('} else {')
2539             for i, arg in enumerate(positional_args):
2540                 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2541                 self.generate_arg_assignment(arg, item, code)
2542             self.generate_arg_default_assignments(code)
2543
2544         else:
2545             # parse the positional arguments from the variable length
2546             # args tuple
2547             code.putln('} else {')
2548             self.generate_arg_default_assignments(code)
2549             code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2550             if self.star_arg:
2551                 code.putln('default:')
2552             reversed_args = list(enumerate(positional_args))[::-1]
2553             for i, arg in reversed_args:
2554                 if i >= min_positional_args-1:
2555                     if min_positional_args > 1:
2556                         code.putln('case %2d:' % (i+1)) # pure code beautification
2557                     else:
2558                         code.put('case %2d: ' % (i+1))
2559                 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2560                 self.generate_arg_assignment(arg, item, code)
2561             if min_positional_args == 0:
2562                 code.put('case  0: ')
2563             code.putln('break;')
2564             if self.star_arg:
2565                 if min_positional_args:
2566                     for i in range(min_positional_args-1, -1, -1):
2567                         code.putln('case %2d:' % i)
2568                     code.put_goto(argtuple_error_label)
2569             else:
2570                 code.put('default: ')
2571                 code.put_goto(argtuple_error_label)
2572             code.putln('}')
2573
2574         code.putln('}')
2575
2576         if code.label_used(argtuple_error_label):
2577             code.put_goto(success_label)
2578             code.put_label(argtuple_error_label)
2579             code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2580                     self.name, has_fixed_positional_count,
2581                     min_positional_args, max_positional_args,
2582                     Naming.args_cname))
2583             code.putln(code.error_goto(self.pos))
2584
2585     def generate_arg_default_assignments(self, code):
2586         for arg in self.args:
2587             if arg.is_generic and arg.default:
2588                 code.putln(
2589                     "%s = %s;" % (
2590                         arg.entry.cname,
2591                         arg.calculate_default_value_code(code)))
2592
2593     def generate_stararg_init_code(self, max_positional_args, code):
2594         if self.starstar_arg:
2595             self.starstar_arg.entry.xdecref_cleanup = 0
2596             code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2597                     self.starstar_arg.entry.cname,
2598                     self.starstar_arg.entry.cname,
2599                     self.error_value()))
2600             code.put_gotref(self.starstar_arg.entry.cname)
2601         if self.star_arg:
2602             self.star_arg.entry.xdecref_cleanup = 0
2603             code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2604                     Naming.args_cname,
2605                     max_positional_args))
2606             code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2607                     self.star_arg.entry.cname, Naming.args_cname,
2608                     max_positional_args, Naming.args_cname))
2609             code.put_gotref(self.star_arg.entry.cname)
2610             if self.starstar_arg:
2611                 code.putln("")
2612                 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2613                 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2614                 code.putln('return %s;' % self.error_value())
2615                 code.putln('}')
2616             else:
2617                 code.putln("if (unlikely(!%s)) return %s;" % (
2618                         self.star_arg.entry.cname, self.error_value()))
2619             code.putln('} else {')
2620             code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2621             code.put_incref(Naming.empty_tuple, py_object_type)
2622             code.putln('}')
2623
2624     def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2625                                         has_fixed_positional_count, positional_args,
2626                                         kw_only_args, argtuple_error_label, code):
2627         all_args = tuple(positional_args) + tuple(kw_only_args)
2628         max_args = len(all_args)
2629
2630         code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2631                    Naming.kwds_cname)
2632         # the 'values' array collects borrowed references to arguments
2633         # before doing any type coercion etc.
2634         code.putln("PyObject* values[%d] = {%s};" % (
2635             max_args, ','.join('0'*max_args)))
2636
2637         # assign borrowed Python default values to the values array,
2638         # so that they can be overwritten by received arguments below
2639         for i, arg in enumerate(all_args):
2640             if arg.default and arg.type.is_pyobject:
2641                 default_value = arg.calculate_default_value_code(code)
2642                 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2643
2644         # parse the args tuple and check that it's not too long
2645         code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2646         if self.star_arg:
2647             code.putln('default:')
2648         for i in range(max_positional_args-1, -1, -1):
2649             code.put('case %2d: ' % (i+1))
2650             code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2651                     i, Naming.args_cname, i))
2652         code.putln('case  0: break;')
2653         if not self.star_arg:
2654             code.put('default: ') # more arguments than allowed
2655             code.put_goto(argtuple_error_label)
2656         code.putln('}')
2657
2658         # now fill up the positional/required arguments with values
2659         # from the kw dict
2660         if self.num_required_args or max_positional_args > 0:
2661             last_required_arg = -1
2662             for i, arg in enumerate(all_args):
2663                 if not arg.default:
2664                     last_required_arg = i
2665             if last_required_arg < max_positional_args:
2666                 last_required_arg = max_positional_args-1
2667             num_required_args = self.num_required_args
2668             if max_positional_args > 0:
2669                 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2670             for i, arg in enumerate(all_args[:last_required_arg+1]):
2671                 if max_positional_args > 0 and i <= max_positional_args:
2672                     if self.star_arg and i == max_positional_args:
2673                         code.putln('default:')
2674                     else:
2675                         code.putln('case %2d:' % i)
2676                 pystring_cname = code.intern_identifier(arg.name)
2677                 if arg.default:
2678                     if arg.kw_only:
2679                         # handled separately below
2680                         continue
2681                     code.putln('if (kw_args > 0) {')
2682                     code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2683                         Naming.kwds_cname, pystring_cname))
2684                     code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2685                     code.putln('}')
2686                 else:
2687                     num_required_args -= 1
2688                     code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2689                         i, Naming.kwds_cname, pystring_cname))
2690                     code.putln('if (likely(values[%d])) kw_args--;' % i);
2691                     if i < min_positional_args:
2692                         if i == 0:
2693                             # special case: we know arg 0 is missing
2694                             code.put('else ')
2695                             code.put_goto(argtuple_error_label)
2696                         else:
2697                             # print the correct number of values (args or
2698                             # kwargs) that were passed into positional
2699                             # arguments up to this point
2700                             code.putln('else {')
2701                             code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2702                                     self.name, has_fixed_positional_count,
2703                                     min_positional_args, max_positional_args, i))
2704                             code.putln(code.error_goto(self.pos))
2705                             code.putln('}')
2706                     elif arg.kw_only:
2707                         code.putln('else {')
2708                         code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2709                                 self.name, pystring_cname))
2710                         code.putln(code.error_goto(self.pos))
2711                         code.putln('}')
2712             if max_positional_args > 0:
2713                 code.putln('}')
2714
2715         if kw_only_args and not self.starstar_arg:
2716             # unpack optional keyword-only arguments
2717             # checking for interned strings in a dict is faster than iterating
2718             # but it's too likely that we must iterate if we expect **kwargs
2719             optional_args = []
2720             for i, arg in enumerate(all_args[max_positional_args:]):
2721                 if not arg.kw_only or not arg.default:
2722                     continue
2723                 optional_args.append((i+max_positional_args, arg))
2724             if optional_args:
2725                 # this mimics an unrolled loop so that we can "break" out of it
2726                 code.putln('while (kw_args > 0) {')
2727                 code.putln('PyObject* value;')
2728                 for i, arg in optional_args:
2729                     pystring_cname = code.intern_identifier(arg.name)
2730                     code.putln(
2731                         'value = PyDict_GetItem(%s, %s);' % (
2732                         Naming.kwds_cname, pystring_cname))
2733                     code.putln(
2734                         'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2735                 code.putln('break;')
2736                 code.putln('}')
2737
2738         code.putln('if (unlikely(kw_args > 0)) {')
2739         # non-positional/-required kw args left in dict: default args,
2740         # kw-only args, **kwargs or error
2741         #
2742         # This is sort of a catch-all: except for checking required
2743         # arguments, this will always do the right thing for unpacking
2744         # keyword arguments, so that we can concentrate on optimising
2745         # common cases above.
2746         if max_positional_args == 0:
2747             pos_arg_count = "0"
2748         elif self.star_arg:
2749             code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2750                     Naming.args_cname, max_positional_args,
2751                     Naming.args_cname, max_positional_args))
2752             pos_arg_count = "used_pos_args"
2753         else:
2754             pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2755         code.globalstate.use_utility_code(parse_keywords_utility_code)
2756         code.put(
2757             'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2758                 Naming.kwds_cname,
2759                 Naming.pykwdlist_cname,
2760                 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2761                 pos_arg_count,
2762                 self.name))
2763         code.putln(code.error_goto(self.pos))
2764         code.putln('}')
2765
2766         # convert arg values to their final type and assign them
2767         for i, arg in enumerate(all_args):
2768             if arg.default and not arg.type.is_pyobject:
2769                 code.putln("if (values[%d]) {" % i)
2770             self.generate_arg_assignment(arg, "values[%d]" % i, code)
2771             if arg.default and not arg.type.is_pyobject:
2772                 code.putln('} else {')
2773                 code.putln(
2774                     "%s = %s;" % (
2775                         arg.entry.cname,
2776                         arg.calculate_default_value_code(code)))
2777                 code.putln('}')
2778
2779     def generate_argument_conversion_code(self, code):
2780         # Generate code to convert arguments from signature type to
2781         # declared type, if needed.  Also copies signature arguments
2782         # into closure fields.
2783         for arg in self.args:
2784             if arg.needs_conversion:
2785                 self.generate_arg_conversion(arg, code)
2786             elif arg.entry.in_closure:
2787                 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2788                 if arg.type.is_pyobject:
2789                     code.put_var_incref(arg.entry)
2790
2791     def generate_arg_conversion(self, arg, code):
2792         # Generate conversion code for one argument.
2793         old_type = arg.hdr_type
2794         new_type = arg.type
2795         if old_type.is_pyobject:
2796             if arg.default:
2797                 code.putln("if (%s) {" % arg.hdr_cname)
2798             else:
2799                 code.putln("assert(%s); {" % arg.hdr_cname)
2800             self.generate_arg_conversion_from_pyobject(arg, code)
2801             code.putln("}")
2802         elif new_type.is_pyobject:
2803             self.generate_arg_conversion_to_pyobject(arg, code)
2804         else:
2805             if new_type.assignable_from(old_type):
2806                 code.putln(
2807                     "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2808             else:
2809                 error(arg.pos,
2810                     "Cannot convert 1 argument from '%s' to '%s'" %
2811                         (old_type, new_type))
2812     
2813     def generate_arg_conversion_from_pyobject(self, arg, code):
2814         new_type = arg.type
2815         func = new_type.from_py_function
2816         # copied from CoerceFromPyTypeNode
2817         if func:
2818             lhs = arg.entry.cname
2819             rhs = "%s(%s)" % (func, arg.hdr_cname)
2820             if new_type.is_enum:
2821                 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2822             code.putln("%s = %s; %s" % (
2823                 lhs, 
2824                 rhs,
2825                 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2826         else:
2827             error(arg.pos, 
2828                 "Cannot convert Python object argument to type '%s'" 
2829                     % new_type)
2830     
2831     def generate_arg_conversion_to_pyobject(self, arg, code):
2832         old_type = arg.hdr_type
2833         func = old_type.to_py_function
2834         if func:
2835             code.putln("%s = %s(%s); %s" % (
2836                 arg.entry.cname,
2837                 func,
2838                 arg.hdr_cname,
2839                 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2840             code.put_var_gotref(arg.entry)
2841         else:
2842             error(arg.pos,
2843                 "Cannot convert argument of type '%s' to Python object"
2844                     % old_type)
2845
2846     def generate_argument_type_tests(self, code):
2847         # Generate type tests for args whose signature
2848         # type is PyObject * and whose declared type is
2849         # a subtype thereof.
2850         for arg in self.args:
2851             if arg.needs_type_test:
2852                 self.generate_arg_type_test(arg, code)
2853             elif not arg.accept_none and arg.type.is_pyobject:
2854                 self.generate_arg_none_check(arg, code)
2855
2856     def error_value(self):
2857         return self.entry.signature.error_value
2858     
2859     def caller_will_check_exceptions(self):
2860         return 1
2861             
2862 class OverrideCheckNode(StatNode):
2863     # A Node for dispatching to the def method if it
2864     # is overriden. 
2865     #
2866     #  py_func
2867     #
2868     #  args
2869     #  func_temp
2870     #  body
2871     
2872     child_attrs = ['body']
2873     
2874     body = None
2875
2876     def analyse_expressions(self, env):
2877         self.args = env.arg_entries
2878         if self.py_func.is_module_scope:
2879             first_arg = 0
2880         else:
2881             first_arg = 1
2882         import ExprNodes
2883         self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2884         call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2885         call_node = ExprNodes.SimpleCallNode(self.pos,
2886                                              function=self.func_node, 
2887                                              args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2888         self.body = ReturnStatNode(self.pos, value=call_node)
2889         self.body.analyse_expressions(env)
2890         
2891     def generate_execution_code(self, code):
2892         interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2893         # Check to see if we are an extension type
2894         if self.py_func.is_module_scope:
2895             self_arg = "((PyObject *)%s)" % Naming.module_cname
2896         else:
2897             self_arg = "((PyObject *)%s)" % self.args[0].cname
2898         code.putln("/* Check if called by wrapper */")
2899         code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2900         code.putln("/* Check if overriden in Python */")
2901         if self.py_func.is_module_scope:
2902             code.putln("else {")
2903         else:
2904             code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2905         func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2906         self.func_node.set_cname(func_node_temp)
2907         # need to get attribute manually--scope would return cdef method
2908         err = code.error_goto_if_null(func_node_temp, self.pos)
2909         code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2910             func_node_temp, self_arg, interned_attr_cname, err))
2911         code.put_gotref(func_node_temp)
2912         is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2913         is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2914             func_node_temp, self.py_func.entry.func_cname)
2915         code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2916         self.body.generate_execution_code(code)
2917         code.putln("}")
2918         code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2919         code.funcstate.release_temp(func_node_temp)
2920         code.putln("}")
2921
2922 class ClassDefNode(StatNode, BlockNode):
2923     pass
2924
2925 class PyClassDefNode(ClassDefNode):
2926     #  A Python class definition.
2927     #
2928     #  name     EncodedString   Name of the class
2929     #  doc      string or None
2930     #  body     StatNode        Attribute definition code
2931     #  entry    Symtab.Entry
2932     #  scope    PyClassScope
2933     #  decorators    [DecoratorNode]        list of decorators or None
2934     #
2935     #  The following subnodes are constructed internally:
2936     #
2937     #  dict     DictNode   Class dictionary or Py3 namespace
2938     #  classobj ClassNode  Class object
2939     #  target   NameNode   Variable to assign class object to
2940
2941     child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2942     decorators = None
2943     py3_style_class = False # Python3 style class
2944     
2945     def __init__(self, pos, name, bases, doc, body, decorators = None,
2946                  keyword_args = None, starstar_arg = None):
2947         StatNode.__init__(self, pos)
2948         self.name = name
2949         self.doc = doc
2950         self.body = body
2951         self.decorators = decorators
2952         import ExprNodes
2953         if self.doc and Options.docstrings:
2954             doc = embed_position(self.pos, self.doc)
2955             doc_node = ExprNodes.StringNode(pos, value = doc)
2956         else:
2957             doc_node = None
2958         if keyword_args or starstar_arg:
2959             self.py3_style_class = True
2960             self.bases = bases
2961             self.metaclass = None
2962             if keyword_args and not starstar_arg and len(keyword_args.key_value_pairs) == 1:
2963                 item = keyword_args.key_value_pairs[0]
2964                 if item.key.value == 'metaclass':
2965                     # special case: we already know the metaclass and
2966                     # it's the only kwarg, so we don't need to do the
2967                     # "build kwargs, find metaclass" dance at runtime
2968                     self.metaclass = item.value
2969                     self.mkw = ExprNodes.NullNode(pos)
2970             if self.metaclass is None:
2971                 self.mkw = ExprNodes.KeywordArgsNode(
2972                     pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
2973                 self.metaclass = ExprNodes.PyClassMetaclassNode(
2974                     pos, mkw = self.mkw, bases = self.bases)
2975             self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
2976                         doc = doc_node, metaclass = self.metaclass, bases = self.bases,
2977                         mkw = self.mkw, )
2978             self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
2979                     bases = self.bases, dict = self.dict, doc = doc_node,
2980                     metaclass = self.metaclass, mkw = self.mkw)
2981         else:
2982             self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2983             self.metaclass = None
2984             self.mkw = None
2985             self.bases = None
2986             self.classobj = ExprNodes.ClassNode(pos, name = name,
2987                     bases = bases, dict = self.dict, doc = doc_node)
2988         self.target = ExprNodes.NameNode(pos, name = name)
2989         
2990     def as_cclass(self):
2991         """
2992         Return this node as if it were declared as an extension class
2993         """
2994         if self.py3_style_class:
2995             error(self.classobj.pos, "Python3 style class could not be represented as C class")
2996             return
2997         bases = self.classobj.bases.args
2998         if len(bases) == 0:
2999             base_class_name = None
3000             base_class_module = None
3001         elif len(bases) == 1:
3002             base = bases[0]
3003             path = []
3004             from ExprNodes import AttributeNode, NameNode
3005             while isinstance(base, AttributeNode):
3006                 path.insert(0, base.attribute)
3007                 base = base.obj
3008             if isinstance(base, NameNode):
3009                 path.insert(0, base.name)
3010                 base_class_name = path[-1]
3011                 if len(path) > 1:
3012                     base_class_module = u'.'.join(path[:-1])
3013                 else:
3014                     base_class_module = None
3015             else:
3016                 error(self.classobj.bases.args.pos, "Invalid base class")
3017         else:
3018             error(self.classobj.bases.args.pos, "C class may only have one base class")
3019             return None
3020         
3021         return CClassDefNode(self.pos, 
3022                              visibility = 'private',
3023                              module_name = None,
3024                              class_name = self.name,
3025                              base_class_module = base_class_module,
3026                              base_class_name = base_class_name,
3027                              decorators = self.decorators,
3028                              body = self.body,
3029                              in_pxd = False,
3030                              doc = self.doc)
3031         
3032     def create_scope(self, env):
3033         genv = env
3034         while env.is_py_class_scope or env.is_c_class_scope:
3035             env = env.outer_scope
3036         cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3037         return cenv
3038     
3039     def analyse_declarations(self, env):
3040         self.target.analyse_target_declaration(env)
3041         cenv = self.create_scope(env)
3042         cenv.directives = env.directives
3043         cenv.class_obj_cname = self.target.entry.cname
3044         self.body.analyse_declarations(cenv)
3045     
3046     def analyse_expressions(self, env):
3047         if self.py3_style_class:
3048             self.bases.analyse_expressions(env)
3049             self.metaclass.analyse_expressions(env)
3050             self.mkw.analyse_expressions(env)
3051         self.dict.analyse_expressions(env)
3052         self.classobj.analyse_expressions(env)
3053         genv = env.global_scope()
3054         cenv = self.scope
3055         self.body.analyse_expressions(cenv)
3056         self.target.analyse_target_expression(env, self.classobj)
3057     
3058     def generate_function_definitions(self, env, code):
3059         self.body.generate_function_definitions(self.scope, code)
3060     
3061     def generate_execution_code(self, code):
3062         code.pyclass_stack.append(self)
3063         cenv = self.scope
3064         if self.py3_style_class:
3065             self.bases.generate_evaluation_code(code)
3066             self.mkw.generate_evaluation_code(code)
3067             self.metaclass.generate_evaluation_code(code)
3068         self.dict.generate_evaluation_code(code)
3069         cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3070         self.body.generate_execution_code(code)
3071         self.classobj.generate_evaluation_code(code)
3072         cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3073         self.target.generate_assignment_code(self.classobj, code)
3074         self.dict.generate_disposal_code(code)
3075         self.dict.free_temps(code)
3076         if self.py3_style_class:
3077             self.mkw.generate_disposal_code(code)
3078             self.mkw.free_temps(code)
3079             self.metaclass.generate_disposal_code(code)
3080             self.metaclass.free_temps(code)
3081             self.bases.generate_disposal_code(code)
3082             self.bases.free_temps(code)
3083         code.pyclass_stack.pop()
3084
3085 class CClassDefNode(ClassDefNode):
3086     #  An extension type definition.
3087     #
3088     #  visibility         'private' or 'public' or 'extern'
3089     #  typedef_flag       boolean
3090     #  api                boolean
3091     #  module_name        string or None    For import of extern type objects
3092     #  class_name         string            Unqualified name of class
3093     #  as_name            string or None    Name to declare as in this scope
3094     #  base_class_module  string or None    Module containing the base class
3095     #  base_class_name    string or None    Name of the base class
3096     #  objstruct_name     string or None    Specified C name of object struct
3097     #  typeobj_name       string or None    Specified C name of type object
3098     #  in_pxd             boolean           Is in a .pxd file
3099     #  decorators         [DecoratorNode]   list of decorators or None
3100     #  doc                string or None
3101     #  body               StatNode or None
3102     #  entry              Symtab.Entry
3103     #  base_type          PyExtensionType or None
3104     #  buffer_defaults_node DictNode or None Declares defaults for a buffer
3105     #  buffer_defaults_pos
3106
3107     child_attrs = ["body"]
3108     buffer_defaults_node = None
3109     buffer_defaults_pos = None
3110     typedef_flag = False
3111     api = False
3112     objstruct_name = None
3113     typeobj_name = None
3114     decorators = None
3115
3116     def analyse_declarations(self, env):
3117         #print "CClassDefNode.analyse_declarations:", self.class_name
3118         #print "...visibility =", self.visibility
3119         #print "...module_name =", self.module_name
3120
3121         import Buffer
3122         if self.buffer_defaults_node:
3123             buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3124                                                             env, [], self.buffer_defaults_node,
3125                                                             need_complete=False)
3126         else:
3127             buffer_defaults = None
3128
3129         if env.in_cinclude and not self.objstruct_name:
3130             error(self.pos, "Object struct name specification required for "
3131                 "C class defined in 'extern from' block")
3132         self.base_type = None
3133         # Now that module imports are cached, we need to 
3134         # import the modules for extern classes. 
3135         if self.module_name:
3136             self.module = None
3137             for module in env.cimported_modules:
3138                 if module.name == self.module_name:
3139                     self.module = module
3140             if self.module is None:
3141                 self.module = ModuleScope(self.module_name, None, env.context)
3142                 self.module.has_extern_class = 1
3143                 env.add_imported_module(self.module)
3144
3145         if self.base_class_name:
3146             if self.base_class_module:
3147                 base_class_scope = env.find_module(self.base_class_module, self.pos)
3148             else:
3149                 base_class_scope = env
3150             if self.base_class_name == 'object':
3151                 # extension classes are special and don't need to inherit from object
3152                 if base_class_scope is None or base_class_scope.lookup('object') is None:
3153                     self.base_class_name = None
3154                     self.base_class_module = None
3155                     base_class_scope = None
3156             if base_class_scope:
3157                 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3158                 if base_class_entry:
3159                     if not base_class_entry.is_type:
3160                         error(self.pos, "'%s' is not a type name" % self.base_class_name)
3161                     elif not base_class_entry.type.is_extension_type:
3162                         error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3163                     elif not base_class_entry.type.is_complete():
3164                         error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3165                             self.base_class_name, self.class_name))
3166                     elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3167                              base_class_entry.type.scope.directives['final']:
3168                         error(self.pos, "Base class '%s' of type '%s' is final" % (
3169                             self.base_class_name, self.class_name))
3170                     else:
3171                         self.base_type = base_class_entry.type
3172         has_body = self.body is not None
3173         if self.module_name and self.visibility != 'extern':
3174             module_path = self.module_name.split(".")
3175             home_scope = env.find_imported_module(module_path, self.pos)
3176             if not home_scope:
3177                 return
3178         else:
3179             home_scope = env
3180
3181         if self.visibility == 'extern':
3182             if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3183                 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3184
3185         self.entry = home_scope.declare_c_class(
3186             name = self.class_name, 
3187             pos = self.pos,
3188             defining = has_body and self.in_pxd,
3189             implementing = has_body and not self.in_pxd,
3190             module_name = self.module_name,
3191             base_type = self.base_type,
3192             objstruct_cname = self.objstruct_name,
3193             typeobj_cname = self.typeobj_name,
3194             visibility = self.visibility,
3195             typedef_flag = self.typedef_flag,
3196             api = self.api,
3197             buffer_defaults = buffer_defaults)
3198         if home_scope is not env and self.visibility == 'extern':
3199             env.add_imported_entry(self.class_name, self.entry, pos)
3200         self.scope = scope = self.entry.type.scope
3201         if scope is not None:
3202             scope.directives = env.directives
3203
3204         if self.doc and Options.docstrings:
3205             scope.doc = embed_position(self.pos, self.doc)
3206             
3207         if has_body:
3208             self.body.analyse_declarations(scope)
3209             if self.in_pxd:
3210                 scope.defined = 1
3211             else:
3212                 scope.implemented = 1
3213         env.allocate_vtable_names(self.entry)
3214         
3215     def analyse_expressions(self, env):
3216         if self.body:
3217             scope = self.entry.type.scope
3218             self.body.analyse_expressions(scope)
3219     
3220     def generate_function_definitions(self, env, code):
3221         if self.body:
3222             self.body.generate_function_definitions(
3223                 self.entry.type.scope, code)
3224     
3225     def generate_execution_code(self, code):
3226         # This is needed to generate evaluation code for
3227         # default values of method arguments.
3228         if self.body:
3229             self.body.generate_execution_code(code)
3230             
3231     def annotate(self, code):
3232         if self.body:
3233             self.body.annotate(code)
3234
3235
3236 class PropertyNode(StatNode):
3237     #  Definition of a property in an extension type.
3238     #
3239     #  name   string
3240     #  doc    EncodedString or None    Doc string
3241     #  body   StatListNode
3242     
3243     child_attrs = ["body"]
3244
3245     def analyse_declarations(self, env):
3246         entry = env.declare_property(self.name, self.doc, self.pos)
3247         if entry:
3248             entry.scope.directives = env.directives
3249             self.body.analyse_declarations(entry.scope)
3250
3251     def analyse_expressions(self, env):
3252         self.body.analyse_expressions(env)
3253     
3254     def generate_function_definitions(self, env, code):
3255         self.body.generate_function_definitions(env, code)
3256
3257     def generate_execution_code(self, code):
3258         pass
3259
3260     def annotate(self, code):
3261         self.body.annotate(code)
3262
3263
3264 class GlobalNode(StatNode):
3265     # Global variable declaration.
3266     #
3267     # names    [string]
3268     
3269     child_attrs = []
3270
3271     def analyse_declarations(self, env):
3272         for name in self.names:
3273             env.declare_global(name, self.pos)
3274
3275     def analyse_expressions(self, env):
3276         pass
3277     
3278     def generate_execution_code(self, code):
3279         pass
3280
3281
3282 class ExprStatNode(StatNode):
3283     #  Expression used as a statement.
3284     #
3285     #  expr   ExprNode
3286
3287     child_attrs = ["expr"]
3288     
3289     def analyse_declarations(self, env):
3290         import ExprNodes
3291         if isinstance(self.expr, ExprNodes.GeneralCallNode):
3292             func = self.expr.function.as_cython_attribute()
3293             if func == u'declare':
3294                 args, kwds = self.expr.explicit_args_kwds()
3295                 if len(args):
3296                     error(self.expr.pos, "Variable names must be specified.")
3297                 for var, type_node in kwds.key_value_pairs:
3298                     type = type_node.analyse_as_type(env)
3299                     if type is None:
3300                         error(type_node.pos, "Unknown type")
3301                     else:
3302                         env.declare_var(var.value, type, var.pos, is_cdef = True)
3303                 self.__class__ = PassStatNode
3304     
3305     def analyse_expressions(self, env):
3306         self.expr.analyse_expressions(env)
3307     
3308     def generate_execution_code(self, code):
3309         self.expr.generate_evaluation_code(code)
3310         if not self.expr.is_temp and self.expr.result():
3311             code.putln("%s;" % self.expr.result())
3312         self.expr.generate_disposal_code(code)
3313         self.expr.free_temps(code)
3314
3315     def generate_function_definitions(self, env, code):
3316         self.expr.generate_function_definitions(env, code)
3317
3318     def annotate(self, code):
3319         self.expr.annotate(code)
3320
3321
3322 class AssignmentNode(StatNode):
3323     #  Abstract base class for assignment nodes.
3324     #
3325     #  The analyse_expressions and generate_execution_code
3326     #  phases of assignments are split into two sub-phases
3327     #  each, to enable all the right hand sides of a
3328     #  parallel assignment to be evaluated before assigning
3329     #  to any of the left hand sides.
3330
3331     def analyse_expressions(self, env):
3332         self.analyse_types(env)
3333
3334 #       def analyse_expressions(self, env):
3335 #           self.analyse_expressions_1(env)
3336 #           self.analyse_expressions_2(env)
3337
3338     def generate_execution_code(self, code):
3339         self.generate_rhs_evaluation_code(code)
3340         self.generate_assignment_code(code)
3341         
3342
3343 class SingleAssignmentNode(AssignmentNode):
3344     #  The simplest case:
3345     #
3346     #    a = b
3347     #
3348     #  lhs      ExprNode      Left hand side
3349     #  rhs      ExprNode      Right hand side
3350     #  first    bool          Is this guaranteed the first assignment to lhs?
3351     
3352     child_attrs = ["lhs", "rhs"]
3353     first = False
3354     declaration_only = False
3355
3356     def analyse_declarations(self, env):
3357         import ExprNodes
3358         
3359         # handle declarations of the form x = cython.foo()
3360         if isinstance(self.rhs, ExprNodes.CallNode):
3361             func_name = self.rhs.function.as_cython_attribute()
3362             if func_name:
3363                 args, kwds = self.rhs.explicit_args_kwds()
3364                 
3365                 if func_name in ['declare', 'typedef']:
3366                     if len(args) > 2 or kwds is not None:
3367                         error(rhs.pos, "Can only declare one type at a time.")
3368                         return
3369                     type = args[0].analyse_as_type(env)
3370                     if type is None:
3371                         error(args[0].pos, "Unknown type")
3372                         return
3373                     lhs = self.lhs
3374                     if func_name == 'declare':
3375                         if isinstance(lhs, ExprNodes.NameNode):
3376                             vars = [(lhs.name, lhs.pos)]
3377                         elif isinstance(lhs, ExprNodes.TupleNode):
3378                             vars = [(var.name, var.pos) for var in lhs.args]
3379                         else:
3380                             error(lhs.pos, "Invalid declaration")
3381                             return
3382                         for var, pos in vars:
3383                             env.declare_var(var, type, pos, is_cdef = True)
3384                         if len(args) == 2:
3385                             # we have a value
3386                             self.rhs = args[1]
3387                         else:
3388                             self.declaration_only = True
3389                     else:
3390                         self.declaration_only = True
3391                         if not isinstance(lhs, ExprNodes.NameNode):
3392                             error(lhs.pos, "Invalid declaration.")
3393                         env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3394                     
3395                 elif func_name in ['struct', 'union']:
3396                     self.declaration_only = True
3397                     if len(args) > 0 or kwds is None:
3398                         error(rhs.pos, "Struct or union members must be given by name.")
3399                         return
3400                     members = []
3401                     for member, type_node in kwds.key_value_pairs:
3402                         type = type_node.analyse_as_type(env)
3403                         if type is None:
3404                             error(type_node.pos, "Unknown type")
3405                         else:
3406                             members.append((member.value, type, member.pos))
3407                     if len(members) < len(kwds.key_value_pairs):
3408                         return
3409                     if not isinstance(self.lhs, ExprNodes.NameNode):
3410                         error(self.lhs.pos, "Invalid declaration.")
3411                     name = self.lhs.name
3412                     scope = StructOrUnionScope(name)
3413                     env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3414                     for member, type, pos in members:
3415                         scope.declare_var(member, type, pos)
3416                     
3417         if self.declaration_only:
3418             return
3419         else:
3420             self.lhs.analyse_target_declaration(env)
3421     
3422     def analyse_types(self, env, use_temp = 0):
3423         self.rhs.analyse_types(env)
3424         self.lhs.analyse_target_types(env)
3425         self.lhs.gil_assignment_check(env)
3426         self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3427         if use_temp:
3428             self.rhs = self.rhs.coerce_to_temp(env)
3429     
3430     def generate_rhs_evaluation_code(self, code):
3431         self.rhs.generate_evaluation_code(code)
3432     
3433     def generate_assignment_code(self, code):
3434         self.lhs.generate_assignment_code(self.rhs, code)
3435
3436     def generate_function_definitions(self, env, code):
3437         self.rhs.generate_function_definitions(env, code)
3438
3439     def annotate(self, code):
3440         self.lhs.annotate(code)
3441         self.rhs.annotate(code)
3442
3443
3444 class CascadedAssignmentNode(AssignmentNode):
3445     #  An assignment with multiple left hand sides:
3446     #
3447     #    a = b = c
3448     #
3449     #  lhs_list   [ExprNode]   Left hand sides
3450     #  rhs        ExprNode     Right hand sides
3451     #
3452     #  Used internally:
3453     #
3454     #  coerced_rhs_list   [ExprNode]   RHS coerced to type of each LHS
3455     
3456     child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3457     coerced_rhs_list = None
3458
3459     def analyse_declarations(self, env):
3460         for lhs in self.lhs_list:
3461             lhs.analyse_target_declaration(env)
3462     
3463     def analyse_types(self, env, use_temp = 0):
3464         self.rhs.analyse_types(env)
3465         if not self.rhs.is_simple():
3466             if use_temp:
3467                 self.rhs = self.rhs.coerce_to_temp(env)
3468             else:
3469                 self.rhs = self.rhs.coerce_to_simple(env)
3470         from ExprNodes import CloneNode
3471         self.coerced_rhs_list = []
3472         for lhs in self.lhs_list:
3473             lhs.analyse_target_types(env)
3474             lhs.gil_assignment_check(env)
3475             rhs = CloneNode(self.rhs)
3476             rhs = rhs.coerce_to(lhs.type, env)
3477             self.coerced_rhs_list.append(rhs)
3478
3479     def generate_rhs_evaluation_code(self, code):
3480         self.rhs.generate_evaluation_code(code)
3481     
3482     def generate_assignment_code(self, code):
3483         for i in range(len(self.lhs_list)):
3484             lhs = self.lhs_list[i]
3485             rhs = self.coerced_rhs_list[i]
3486             rhs.generate_evaluation_code(code)
3487             lhs.generate_assignment_code(rhs, code)
3488             # Assignment has disposed of the cloned RHS
3489         self.rhs.generate_disposal_code(code)
3490         self.rhs.free_temps(code)
3491
3492     def generate_function_definitions(self, env, code):
3493         self.rhs.generate_function_definitions(env, code)
3494
3495     def annotate(self, code):
3496         for i in range(len(self.lhs_list)):
3497             lhs = self.lhs_list[i].annotate(code)
3498             rhs = self.coerced_rhs_list[i].annotate(code)
3499         self.rhs.annotate(code)
3500         
3501
3502 class ParallelAssignmentNode(AssignmentNode):
3503     #  A combined packing/unpacking assignment:
3504     #
3505     #    a, b, c =  d, e, f
3506     #
3507     #  This has been rearranged by the parser into
3508     #
3509     #    a = d ; b = e ; c = f
3510     #
3511     #  but we must evaluate all the right hand sides
3512     #  before assigning to any of the left hand sides.
3513     #
3514     #  stats     [AssignmentNode]   The constituent assignments
3515     
3516     child_attrs = ["stats"]
3517
3518     def analyse_declarations(self, env):
3519         for stat in self.stats:
3520             stat.analyse_declarations(env)
3521     
3522     def analyse_expressions(self, env):
3523         for stat in self.stats:
3524             stat.analyse_types(env, use_temp = 1)
3525
3526 #    def analyse_expressions(self, env):
3527 #        for stat in self.stats:
3528 #            stat.analyse_expressions_1(env, use_temp = 1)
3529 #        for stat in self.stats:
3530 #            stat.analyse_expressions_2(env)
3531     
3532     def generate_execution_code(self, code):
3533         for stat in self.stats:
3534             stat.generate_rhs_evaluation_code(code)
3535         for stat in self.stats:
3536             stat.generate_assignment_code(code)
3537
3538     def generate_function_definitions(self, env, code):
3539         for stat in self.stats:
3540             stat.generate_function_definitions(env, code)
3541
3542     def annotate(self, code):
3543         for stat in self.stats:
3544             stat.annotate(code)
3545
3546
3547 class InPlaceAssignmentNode(AssignmentNode):
3548     #  An in place arithmetic operand:
3549     #
3550     #    a += b
3551     #    a -= b
3552     #    ...
3553     #
3554     #  lhs      ExprNode      Left hand side
3555     #  rhs      ExprNode      Right hand side
3556     #  op       char          one of "+-*/%^&|"
3557     #  dup     (ExprNode)     copy of lhs used for operation (auto-generated)
3558     #
3559     #  This code is a bit tricky because in order to obey Python 
3560     #  semantics the sub-expressions (e.g. indices) of the lhs must 
3561     #  not be evaluated twice. So we must re-use the values calculated 
3562     #  in evaluation phase for the assignment phase as well. 
3563     #  Fortunately, the type of the lhs node is fairly constrained 
3564     #  (it must be a NameNode, AttributeNode, or IndexNode).     
3565     
3566     child_attrs = ["lhs", "rhs"]
3567
3568     def analyse_declarations(self, env):
3569         self.lhs.analyse_target_declaration(env)
3570         
3571     def analyse_types(self, env):
3572         self.rhs.analyse_types(env)
3573         self.lhs.analyse_target_types(env)
3574
3575     def generate_execution_code(self, code):
3576         import ExprNodes
3577         self.rhs.generate_evaluation_code(code)
3578         self.lhs.generate_subexpr_evaluation_code(code)
3579         c_op = self.operator
3580         if c_op == "//":
3581             c_op = "/"
3582         elif c_op == "**":
3583             error(self.pos, "No C inplace power operator")
3584         if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3585             if self.lhs.type.is_pyobject:
3586                 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3587             if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3588                 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3589             self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3590         else:
3591             # C++
3592             # TODO: make sure overload is declared
3593             code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3594         self.lhs.generate_subexpr_disposal_code(code)
3595         self.lhs.free_subexpr_temps(code)
3596         self.rhs.generate_disposal_code(code)
3597         self.rhs.free_temps(code)
3598
3599     def annotate(self, code):
3600         self.lhs.annotate(code)
3601         self.rhs.annotate(code)
3602     
3603     def create_binop_node(self):
3604         import ExprNodes
3605         return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3606
3607
3608 class PrintStatNode(StatNode):
3609     #  print statement
3610     #
3611     #  arg_tuple         TupleNode
3612     #  stream            ExprNode or None (stdout)
3613     #  append_newline    boolean
3614
3615     child_attrs = ["arg_tuple", "stream"]
3616
3617     def analyse_expressions(self, env):
3618         if self.stream:
3619             self.stream.analyse_expressions(env)
3620             self.stream = self.stream.coerce_to_pyobject(env)
3621         self.arg_tuple.analyse_expressions(env)
3622         self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3623         env.use_utility_code(printing_utility_code)
3624         if len(self.arg_tuple.args) == 1 and self.append_newline:
3625             env.use_utility_code(printing_one_utility_code)
3626
3627     nogil_check = Node.gil_error
3628     gil_message = "Python print statement"
3629
3630     def generate_execution_code(self, code):
3631         if self.stream:
3632             self.stream.generate_evaluation_code(code)
3633             stream_result = self.stream.py_result()
3634         else:
3635             stream_result = '0'
3636         if len(self.arg_tuple.args) == 1 and self.append_newline:
3637             arg = self.arg_tuple.args[0]
3638             arg.generate_evaluation_code(code)
3639             
3640             code.putln(
3641                 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3642                     stream_result,
3643                     arg.py_result(),
3644                     code.error_goto(self.pos)))
3645             arg.generate_disposal_code(code)
3646             arg.free_temps(code)
3647         else:
3648             self.arg_tuple.generate_evaluation_code(code)
3649             code.putln(
3650                 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3651                     stream_result,
3652                     self.arg_tuple.py_result(),
3653                     self.append_newline,
3654                     code.error_goto(self.pos)))
3655             self.arg_tuple.generate_disposal_code(code)
3656             self.arg_tuple.free_temps(code)
3657
3658         if self.stream:
3659             self.stream.generate_disposal_code(code)
3660             self.stream.free_temps(code)
3661
3662     def generate_function_definitions(self, env, code):
3663         if self.stream:
3664             self.stream.generate_function_definitions(env, code)
3665         self.arg_tuple.generate_function_definitions(env, code)
3666
3667     def annotate(self, code):
3668         if self.stream:
3669             self.stream.annotate(code)
3670         self.arg_tuple.annotate(code)
3671
3672
3673 class ExecStatNode(StatNode):
3674     #  exec statement
3675     #
3676     #  args     [ExprNode]
3677
3678     child_attrs = ["args"]
3679
3680     def analyse_expressions(self, env):
3681         for i, arg in enumerate(self.args):
3682             arg.analyse_expressions(env)
3683             arg = arg.coerce_to_pyobject(env)
3684             self.args[i] = arg
3685         env.use_utility_code(Builtin.pyexec_utility_code)
3686
3687     nogil_check = Node.gil_error
3688     gil_message = "Python exec statement"
3689
3690     def generate_execution_code(self, code):
3691         args = []
3692         for arg in self.args:
3693             arg.generate_evaluation_code(code)
3694             args.append( arg.py_result() )
3695         args = tuple(args + ['0', '0'][:3-len(args)])
3696         temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3697         code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3698                 (temp_result,) + args))
3699         for arg in self.args:
3700             arg.generate_disposal_code(code)
3701             arg.free_temps(code)
3702         code.putln(
3703             code.error_goto_if_null(temp_result, self.pos))
3704         code.put_gotref(temp_result)
3705         code.put_decref_clear(temp_result, py_object_type)
3706         code.funcstate.release_temp(temp_result)
3707
3708     def annotate(self, code):
3709         for arg in self.args:
3710             arg.annotate(code)
3711
3712
3713 class DelStatNode(StatNode):
3714     #  del statement
3715     #
3716     #  args     [ExprNode]
3717     
3718     child_attrs = ["args"]
3719
3720     def analyse_declarations(self, env):
3721         for arg in self.args:
3722             arg.analyse_target_declaration(env)
3723     
3724     def analyse_expressions(self, env):
3725         for arg in self.args:
3726             arg.analyse_target_expression(env, None)
3727             if arg.type.is_pyobject:
3728                 pass
3729             elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3730                 self.cpp_check(env)
3731             elif arg.type.is_cpp_class:
3732                 error(arg.pos, "Deletion of non-heap C++ object")
3733             else:
3734                 error(arg.pos, "Deletion of non-Python, non-C++ object")
3735             #arg.release_target_temp(env)
3736
3737     def nogil_check(self, env):
3738         for arg in self.args:
3739             if arg.type.is_pyobject:
3740                 self.gil_error()
3741
3742     gil_message = "Deleting Python object"
3743
3744     def generate_execution_code(self, code):
3745         for arg in self.args:
3746             if arg.type.is_pyobject:
3747                 arg.generate_deletion_code(code)
3748             elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3749                 arg.generate_result_code(code)
3750                 code.putln("delete %s;" % arg.result())
3751             # else error reported earlier
3752
3753     def annotate(self, code):
3754         for arg in self.args:
3755             arg.annotate(code)
3756
3757
3758 class PassStatNode(StatNode):
3759     #  pass statement
3760
3761     child_attrs = []
3762     
3763     def analyse_expressions(self, env):
3764         pass
3765     
3766     def generate_execution_code(self, code):
3767         pass
3768
3769
3770 class BreakStatNode(StatNode):
3771
3772     child_attrs = []
3773
3774     def analyse_expressions(self, env):
3775         pass
3776     
3777     def generate_execution_code(self, code):
3778         if not code.break_label:
3779             error(self.pos, "break statement not inside loop")
3780         else:
3781             code.put_goto(code.break_label)
3782
3783
3784 class ContinueStatNode(StatNode):
3785
3786     child_attrs = []
3787
3788     def analyse_expressions(self, env):
3789         pass
3790     
3791     def generate_execution_code(self, code):
3792         if code.funcstate.in_try_finally:
3793             error(self.pos, "continue statement inside try of try...finally")
3794         elif not code.continue_label:
3795             error(self.pos, "continue statement not inside loop")
3796         else:
3797             code.put_goto(code.continue_label)
3798
3799
3800 class ReturnStatNode(StatNode):
3801     #  return statement
3802     #
3803     #  value         ExprNode or None
3804     #  return_type   PyrexType
3805     
3806     child_attrs = ["value"]
3807
3808     def analyse_expressions(self, env):
3809         return_type = env.return_type
3810         self.return_type = return_type
3811         if not return_type:
3812             error(self.pos, "Return not inside a function body")
3813             return
3814         if self.value:
3815             self.value.analyse_types(env)
3816             if return_type.is_void or return_type.is_returncode:
3817                 error(self.value.pos, 
3818                     "Return with value in void function")
3819             else:
3820                 self.value = self.value.coerce_to(env.return_type, env)
3821         else:
3822             if (not return_type.is_void
3823                 and not return_type.is_pyobject
3824                 and not return_type.is_returncode):
3825                     error(self.pos, "Return value required")
3826
3827     def nogil_check(self, env):
3828         if self.return_type.is_pyobject:
3829             self.gil_error()
3830
3831     gil_message = "Returning Python object"
3832
3833     def generate_execution_code(self, code):
3834         code.mark_pos(self.pos)
3835         if not self.return_type:
3836             # error reported earlier
3837             return
3838         if self.return_type.is_pyobject:
3839             code.put_xdecref(Naming.retval_cname,
3840                              self.return_type)
3841         if self.value:
3842             self.value.generate_evaluation_code(code)
3843             self.value.make_owned_reference(code)
3844             code.putln(
3845                 "%s = %s;" % (
3846                     Naming.retval_cname,
3847                     self.value.result_as(self.return_type)))
3848             self.value.generate_post_assignment_code(code)
3849             self.value.free_temps(code)
3850         else:
3851             if self.return_type.is_pyobject:
3852                 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3853             elif self.return_type.is_returncode:
3854                 code.putln(
3855                     "%s = %s;" % (
3856                         Naming.retval_cname,
3857                         self.return_type.default_value))
3858         for cname, type in code.funcstate.temps_holding_reference():
3859             code.put_decref_clear(cname, type)
3860         code.put_goto(code.return_label)
3861
3862     def generate_function_definitions(self, env, code):
3863         if self.value is not None:
3864             self.value.generate_function_definitions(env, code)
3865         
3866     def annotate(self, code):
3867         if self.value:
3868             self.value.annotate(code)
3869
3870
3871 class RaiseStatNode(StatNode):
3872     #  raise statement
3873     #
3874     #  exc_type    ExprNode or None
3875     #  exc_value   ExprNode or None
3876     #  exc_tb      ExprNode or None
3877     
3878     child_attrs = ["exc_type", "exc_value", "exc_tb"]
3879
3880     def analyse_expressions(self, env):
3881         if self.exc_type:
3882             self.exc_type.analyse_types(env)
3883             self.exc_type = self.exc_type.coerce_to_pyobject(env)
3884         if self.exc_value:
3885             self.exc_value.analyse_types(env)
3886             self.exc_value = self.exc_value.coerce_to_pyobject(env)
3887         if self.exc_tb:
3888             self.exc_tb.analyse_types(env)
3889             self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3890         env.use_utility_code(raise_utility_code)
3891
3892     nogil_check = Node.gil_error
3893     gil_message = "Raising exception"
3894
3895     def generate_execution_code(self, code):
3896         if self.exc_type:
3897             self.exc_type.generate_evaluation_code(code)
3898             type_code = self.exc_type.py_result()
3899         else:
3900             type_code = "0"
3901         if self.exc_value:
3902             self.exc_value.generate_evaluation_code(code)
3903             value_code = self.exc_value.py_result()
3904         else:
3905             value_code = "0"
3906         if self.exc_tb:
3907             self.exc_tb.generate_evaluation_code(code)
3908             tb_code = self.exc_tb.py_result()
3909         else:
3910             tb_code = "0"
3911         code.putln(
3912             "__Pyx_Raise(%s, %s, %s);" % (
3913                 type_code,
3914                 value_code,
3915                 tb_code))
3916         for obj in (self.exc_type, self.exc_value, self.exc_tb):
3917             if obj:
3918                 obj.generate_disposal_code(code)
3919                 obj.free_temps(code)
3920         code.putln(
3921             code.error_goto(self.pos))
3922
3923     def generate_function_definitions(self, env, code):
3924         if self.exc_type is not None:
3925             self.exc_type.generate_function_definitions(env, code)
3926         if self.exc_value is not None:
3927             self.exc_value.generate_function_definitions(env, code)
3928         if self.exc_tb is not None:
3929             self.exc_tb.generate_function_definitions(env, code)
3930
3931     def annotate(self, code):
3932         if self.exc_type:
3933             self.exc_type.annotate(code)
3934         if self.exc_value:
3935             self.exc_value.annotate(code)
3936         if self.exc_tb:
3937             self.exc_tb.annotate(code)
3938
3939
3940 class ReraiseStatNode(StatNode):
3941
3942     child_attrs = []
3943
3944     def analyse_expressions(self, env):
3945         env.use_utility_code(restore_exception_utility_code)
3946
3947     nogil_check = Node.gil_error
3948     gil_message = "Raising exception"
3949
3950     def generate_execution_code(self, code):
3951         vars = code.funcstate.exc_vars
3952         if vars:
3953             for varname in vars:
3954                 code.put_giveref(varname)
3955             code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3956             for varname in vars:
3957                 code.put("%s = 0; " % varname)
3958             code.putln()
3959             code.putln(code.error_goto(self.pos))
3960         else:
3961             error(self.pos, "Reraise not inside except clause")
3962         
3963
3964 class AssertStatNode(StatNode):
3965     #  assert statement
3966     #
3967     #  cond    ExprNode
3968     #  value   ExprNode or None
3969     
3970     child_attrs = ["cond", "value"]
3971
3972     def analyse_expressions(self, env):
3973         self.cond = self.cond.analyse_boolean_expression(env)
3974         if self.value:
3975             self.value.analyse_types(env)
3976             self.value = self.value.coerce_to_pyobject(env)
3977
3978     nogil_check = Node.gil_error
3979     gil_message = "Raising exception"
3980     
3981     def generate_execution_code(self, code):
3982         code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3983         self.cond.generate_evaluation_code(code)
3984         code.putln(
3985             "if (unlikely(!%s)) {" %
3986                 self.cond.result())
3987         if self.value:
3988             self.value.generate_evaluation_code(code)
3989             code.putln(
3990                 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3991                     self.value.py_result())
3992             self.value.generate_disposal_code(code)
3993             self.value.free_temps(code)
3994         else:
3995             code.putln(
3996                 "PyErr_SetNone(PyExc_AssertionError);")
3997         code.putln(
3998                 code.error_goto(self.pos))
3999         code.putln(
4000             "}")
4001         self.cond.generate_disposal_code(code)
4002         self.cond.free_temps(code)
4003         code.putln("#endif")
4004
4005     def generate_function_definitions(self, env, code):
4006         self.cond.generate_function_definitions(env, code)
4007         if self.value is not None:
4008             self.value.generate_function_definitions(env, code)
4009
4010     def annotate(self, code):
4011         self.cond.annotate(code)
4012         if self.value:
4013             self.value.annotate(code)
4014
4015
4016 class IfStatNode(StatNode):
4017     #  if statement
4018     #
4019     #  if_clauses   [IfClauseNode]
4020     #  else_clause  StatNode or None
4021
4022     child_attrs = ["if_clauses", "else_clause"]
4023     
4024     def analyse_control_flow(self, env):
4025         env.start_branching(self.pos)
4026         for if_clause in self.if_clauses:
4027             if_clause.analyse_control_flow(env)
4028             env.next_branch(if_clause.end_pos())
4029         if self.else_clause:
4030             self.else_clause.analyse_control_flow(env)
4031         env.finish_branching(self.end_pos())
4032
4033     def analyse_declarations(self, env):
4034         for if_clause in self.if_clauses:
4035             if_clause.analyse_declarations(env)
4036         if self.else_clause:
4037             self.else_clause.analyse_declarations(env)
4038     
4039     def analyse_expressions(self, env):
4040         for if_clause in self.if_clauses:
4041             if_clause.analyse_expressions(env)
4042         if self.else_clause:
4043             self.else_clause.analyse_expressions(env)
4044
4045     def generate_execution_code(self, code):
4046         code.mark_pos(self.pos)
4047         end_label = code.new_label()
4048         for if_clause in self.if_clauses:
4049             if_clause.generate_execution_code(code, end_label)
4050         if self.else_clause:
4051             code.putln("/*else*/ {")
4052             self.else_clause.generate_execution_code(code)
4053             code.putln("}")
4054         code.put_label(end_label)
4055
4056     def generate_function_definitions(self, env, code):
4057         for clause in self.if_clauses:
4058             clause.generate_function_definitions(env, code)
4059         if self.else_clause is not None:
4060             self.else_clause.generate_function_definitions(env, code)
4061
4062     def annotate(self, code):
4063         for if_clause in self.if_clauses:
4064             if_clause.annotate(code)
4065         if self.else_clause:
4066             self.else_clause.annotate(code)
4067
4068
4069 class IfClauseNode(Node):
4070     #  if or elif clause in an if statement
4071     #
4072     #  condition   ExprNode
4073     #  body        StatNode
4074     
4075     child_attrs = ["condition", "body"]
4076
4077     def analyse_control_flow(self, env):
4078         self.body.analyse_control_flow(env)
4079         
4080     def analyse_declarations(self, env):
4081         self.body.analyse_declarations(env)
4082     
4083     def analyse_expressions(self, env):
4084         self.condition = \
4085             self.condition.analyse_temp_boolean_expression(env)
4086         self.body.analyse_expressions(env)
4087
4088     def get_constant_condition_result(self):
4089         if self.condition.has_constant_result():
4090             return bool(self.condition.constant_result)
4091         else:
4092             return None
4093
4094     def generate_execution_code(self, code, end_label):
4095         self.condition.generate_evaluation_code(code)
4096         code.putln(
4097             "if (%s) {" %
4098                 self.condition.result())
4099         self.condition.generate_disposal_code(code)
4100         self.condition.free_temps(code)
4101         self.body.generate_execution_code(code)
4102         code.put_goto(end_label)
4103         code.putln("}")
4104
4105     def generate_function_definitions(self, env, code):
4106         self.condition.generate_function_definitions(env, code)
4107         self.body.generate_function_definitions(env, code)
4108
4109     def annotate(self, code):
4110         self.condition.annotate(code)
4111         self.body.annotate(code)
4112         
4113
4114 class SwitchCaseNode(StatNode):
4115     # Generated in the optimization of an if-elif-else node
4116     #
4117     # conditions    [ExprNode]
4118     # body          StatNode
4119     
4120     child_attrs = ['conditions', 'body']
4121
4122     def generate_execution_code(self, code):
4123         for cond in self.conditions:
4124             code.mark_pos(cond.pos)
4125             cond.generate_evaluation_code(code)
4126             code.putln("case %s:" % cond.result())
4127         self.body.generate_execution_code(code)
4128         code.putln("break;")
4129
4130     def generate_function_definitions(self, env, code):
4131         for cond in self.conditions:
4132             cond.generate_function_definitions(env, code)
4133         self.body.generate_function_definitions(env, code)
4134         
4135     def annotate(self, code):
4136         for cond in self.conditions:
4137             cond.annotate(code)
4138         self.body.annotate(code)
4139
4140 class SwitchStatNode(StatNode):
4141     # Generated in the optimization of an if-elif-else node
4142     #
4143     # test          ExprNode
4144     # cases         [SwitchCaseNode]
4145     # else_clause   StatNode or None
4146     
4147     child_attrs = ['test', 'cases', 'else_clause']
4148     
4149     def generate_execution_code(self, code):
4150         self.test.generate_evaluation_code(code)
4151         code.putln("switch (%s) {" % self.test.result())
4152         for case in self.cases:
4153             case.generate_execution_code(code)
4154         if self.else_clause is not None:
4155             code.putln("default:")
4156             self.else_clause.generate_execution_code(code)
4157             code.putln("break;")
4158         code.putln("}")
4159
4160     def generate_function_definitions(self, env, code):
4161         self.test.generate_function_definitions(env, code)
4162         for case in self.cases:
4163             case.generate_function_definitions(env, code)
4164         if self.else_clause is not None:
4165             self.else_clause.generate_function_definitions(env, code)
4166
4167     def annotate(self, code):
4168         self.test.annotate(code)
4169         for case in self.cases:
4170             case.annotate(code)
4171         if self.else_clause is not None:
4172             self.else_clause.annotate(code)
4173             
4174 class LoopNode(object):
4175     
4176     def analyse_control_flow(self, env):
4177         env.start_branching(self.pos)
4178         self.body.analyse_control_flow(env)
4179         env.next_branch(self.body.end_pos())
4180         if self.else_clause:
4181             self.else_clause.analyse_control_flow(env)
4182         env.finish_branching(self.end_pos())
4183
4184     
4185 class WhileStatNode(LoopNode, StatNode):
4186     #  while statement
4187     #
4188     #  condition    ExprNode
4189     #  body         StatNode
4190     #  else_clause  StatNode
4191
4192     child_attrs = ["condition", "body", "else_clause"]
4193
4194     def analyse_declarations(self, env):
4195         self.body.analyse_declarations(env)
4196         if self.else_clause:
4197             self.else_clause.analyse_declarations(env)
4198     
4199     def analyse_expressions(self, env):
4200         self.condition = \
4201             self.condition.analyse_temp_boolean_expression(env)
4202         self.body.analyse_expressions(env)
4203         if self.else_clause:
4204             self.else_clause.analyse_expressions(env)
4205     
4206     def generate_execution_code(self, code):
4207         old_loop_labels = code.new_loop_labels()
4208         code.putln(
4209             "while (1) {")
4210         self.condition.generate_evaluation_code(code)
4211         self.condition.generate_disposal_code(code)
4212         code.putln(
4213             "if (!%s) break;" %
4214                 self.condition.result())
4215         self.condition.free_temps(code)
4216         self.body.generate_execution_code(code)
4217         code.put_label(code.continue_label)
4218         code.putln("}")
4219         break_label = code.break_label
4220         code.set_loop_labels(old_loop_labels)
4221         if self.else_clause:
4222             code.putln("/*else*/ {")
4223             self.else_clause.generate_execution_code(code)
4224             code.putln("}")
4225         code.put_label(break_label)
4226
4227     def generate_function_definitions(self, env, code):
4228         self.condition.generate_function_definitions(env, code)
4229         self.body.generate_function_definitions(env, code)
4230         if self.else_clause is not None:
4231             self.else_clause.generate_function_definitions(env, code)
4232
4233     def annotate(self, code):
4234         self.condition.annotate(code)
4235         self.body.annotate(code)
4236         if self.else_clause:
4237             self.else_clause.annotate(code)
4238
4239
4240 def ForStatNode(pos, **kw):
4241     if 'iterator' in kw:
4242         return ForInStatNode(pos, **kw)
4243     else:
4244         return ForFromStatNode(pos, **kw)
4245
4246 class ForInStatNode(LoopNode, StatNode):
4247     #  for statement
4248     #
4249     #  target        ExprNode
4250     #  iterator      IteratorNode
4251     #  body          StatNode
4252     #  else_clause   StatNode
4253     #  item          NextNode       used internally
4254     
4255     child_attrs = ["target", "iterator", "body", "else_clause"]
4256     item = None
4257     
4258     def analyse_declarations(self, env):
4259         self.target.analyse_target_declaration(env)
4260         self.body.analyse_declarations(env)
4261         if self.else_clause:
4262             self.else_clause.analyse_declarations(env)
4263
4264     def analyse_expressions(self, env):
4265         import ExprNodes
4266         self.target.analyse_target_types(env)
4267         self.iterator.analyse_expressions(env)
4268         self.item = ExprNodes.NextNode(self.iterator, env)
4269         self.item = self.item.coerce_to(self.target.type, env)
4270         self.body.analyse_expressions(env)
4271         if self.else_clause:
4272             self.else_clause.analyse_expressions(env)
4273
4274     def generate_execution_code(self, code):
4275         old_loop_labels = code.new_loop_labels()
4276         self.iterator.allocate_counter_temp(code)
4277         self.iterator.generate_evaluation_code(code)
4278         code.putln(
4279             "for (;;) {")
4280         self.item.generate_evaluation_code(code)
4281         self.target.generate_assignment_code(self.item, code)
4282         self.body.generate_execution_code(code)
4283         code.put_label(code.continue_label)
4284         code.putln(
4285             "}")
4286         break_label = code.break_label
4287         code.set_loop_labels(old_loop_labels)
4288
4289         if self.else_clause:
4290             # in nested loops, the 'else' block can contain a
4291             # 'continue' statement for the outer loop, but we may need
4292             # to generate cleanup code before taking that path, so we
4293             # intercept it here
4294             orig_continue_label = code.continue_label
4295             code.continue_label = code.new_label('outer_continue')
4296
4297             code.putln("/*else*/ {")
4298             self.else_clause.generate_execution_code(code)
4299             code.putln("}")
4300
4301             if code.label_used(code.continue_label):
4302                 code.put_goto(break_label)
4303                 code.put_label(code.continue_label)
4304                 self.iterator.generate_disposal_code(code)
4305                 code.put_goto(orig_continue_label)
4306             code.set_loop_labels(old_loop_labels)
4307
4308         if code.label_used(break_label):
4309             code.put_label(break_label)
4310         self.iterator.release_counter_temp(code)
4311         self.iterator.generate_disposal_code(code)
4312         self.iterator.free_temps(code)
4313
4314     def generate_function_definitions(self, env, code):
4315         self.target.generate_function_definitions(env, code)
4316         self.iterator.generate_function_definitions(env, code)
4317         self.body.generate_function_definitions(env, code)
4318         if self.else_clause is not None:
4319             self.else_clause.generate_function_definitions(env, code)
4320
4321     def annotate(self, code):
4322         self.target.annotate(code)
4323         self.iterator.annotate(code)
4324         self.body.annotate(code)
4325         if self.else_clause:
4326             self.else_clause.annotate(code)
4327         self.item.annotate(code)
4328
4329
4330 class ForFromStatNode(LoopNode, StatNode):
4331     #  for name from expr rel name rel expr
4332     #
4333     #  target        NameNode
4334     #  bound1        ExprNode
4335     #  relation1     string
4336     #  relation2     string
4337     #  bound2        ExprNode
4338     #  step          ExprNode or None
4339     #  body          StatNode
4340     #  else_clause   StatNode or None
4341     #
4342     #  Used internally:
4343     #
4344     #  from_range         bool
4345     #  is_py_target       bool
4346     #  loopvar_node       ExprNode (usually a NameNode or temp node)
4347     #  py_loopvar_node    PyTempNode or None
4348     child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4349
4350     is_py_target = False
4351     loopvar_node = None
4352     py_loopvar_node = None
4353     from_range = False
4354
4355     gil_message = "For-loop using object bounds or target"
4356
4357     def nogil_check(self, env):
4358         for x in (self.target, self.bound1, self.bound2):
4359             if x.type.is_pyobject:
4360                 self.gil_error()
4361
4362     def analyse_declarations(self, env):
4363         self.target.analyse_target_declaration(env)
4364         self.body.analyse_declarations(env)
4365         if self.else_clause:
4366             self.else_clause.analyse_declarations(env)
4367
4368     def analyse_expressions(self, env):
4369         import ExprNodes
4370         self.target.analyse_target_types(env)
4371         self.bound1.analyse_types(env)
4372         self.bound2.analyse_types(env)
4373         if self.step is not None:
4374             if isinstance(self.step, ExprNodes.UnaryMinusNode):
4375                 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4376             self.step.analyse_types(env)
4377         
4378         target_type = self.target.type
4379         if self.target.type.is_numeric:
4380             loop_type = self.target.type
4381         else:
4382             loop_type = PyrexTypes.c_int_type
4383             if not self.bound1.type.is_pyobject:
4384                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4385             if not self.bound2.type.is_pyobject:
4386                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4387             if self.step is not None and not self.step.type.is_pyobject:
4388                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4389         self.bound1 = self.bound1.coerce_to(loop_type, env)
4390         self.bound2 = self.bound2.coerce_to(loop_type, env)
4391         if not self.bound2.is_literal:
4392             self.bound2 = self.bound2.coerce_to_temp(env)
4393         if self.step is not None:
4394             self.step = self.step.coerce_to(loop_type, env)            
4395             if not self.step.is_literal:
4396                 self.step = self.step.coerce_to_temp(env)
4397
4398         target_type = self.target.type
4399         if not (target_type.is_pyobject or target_type.is_numeric):
4400             error(self.target.pos,
4401                 "for-from loop variable must be c numeric type or Python object")
4402         if target_type.is_numeric:
4403             self.is_py_target = False
4404             if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4405                 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4406             self.loopvar_node = self.target
4407             self.py_loopvar_node = None
4408         else:
4409             self.is_py_target = True
4410             c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4411             self.loopvar_node = c_loopvar_node
4412             self.py_loopvar_node = \
4413                 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4414         self.body.analyse_expressions(env)
4415         if self.else_clause:
4416             self.else_clause.analyse_expressions(env)
4417             
4418     def generate_execution_code(self, code):
4419         old_loop_labels = code.new_loop_labels()
4420         from_range = self.from_range
4421         self.bound1.generate_evaluation_code(code)
4422         self.bound2.generate_evaluation_code(code)
4423         offset, incop = self.relation_table[self.relation1]
4424         if self.step is not None:
4425             self.step.generate_evaluation_code(code)
4426             step = self.step.result()
4427             incop = "%s=%s" % (incop[0], step)
4428         import ExprNodes
4429         if isinstance(self.loopvar_node, ExprNodes.TempNode):
4430             self.loopvar_node.allocate(code)
4431         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4432             self.py_loopvar_node.allocate(code)
4433         if from_range:
4434             loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4435         else:
4436             loopvar_name = self.loopvar_node.result()
4437         code.putln(
4438             "for (%s = %s%s; %s %s %s; %s%s) {" % (
4439                 loopvar_name,
4440                 self.bound1.result(), offset,
4441                 loopvar_name, self.relation2, self.bound2.result(),
4442                 loopvar_name, incop))
4443         if self.py_loopvar_node:
4444             self.py_loopvar_node.generate_evaluation_code(code)
4445             self.target.generate_assignment_code(self.py_loopvar_node, code)
4446         elif from_range:
4447             code.putln("%s = %s;" % (
4448                             self.target.result(), loopvar_name))
4449         self.body.generate_execution_code(code)
4450         code.put_label(code.continue_label)
4451         if self.py_loopvar_node:
4452             # This mess is to make for..from loops with python targets behave 
4453             # exactly like those with C targets with regards to re-assignment 
4454             # of the loop variable. 
4455             import ExprNodes
4456             if self.target.entry.is_pyglobal:
4457                 # We know target is a NameNode, this is the only ugly case. 
4458                 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4459                 target_node.allocate(code)
4460                 interned_cname = code.intern_identifier(self.target.entry.name)
4461                 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4462                 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4463                                 target_node.result(),
4464                                 Naming.module_cname, 
4465                                 interned_cname,
4466                                 code.error_goto_if_null(target_node.result(), self.target.pos)))
4467                 code.put_gotref(target_node.result())
4468             else:
4469                 target_node = self.target
4470             from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4471             from_py_node.temp_code = loopvar_name
4472             from_py_node.generate_result_code(code)
4473             if self.target.entry.is_pyglobal:
4474                 code.put_decref(target_node.result(), target_node.type)
4475                 target_node.release(code)
4476         code.putln("}")
4477         if self.py_loopvar_node:
4478             # This is potentially wasteful, but we don't want the semantics to 
4479             # depend on whether or not the loop is a python type. 
4480             self.py_loopvar_node.generate_evaluation_code(code)
4481             self.target.generate_assignment_code(self.py_loopvar_node, code)
4482         if from_range:
4483             code.funcstate.release_temp(loopvar_name)
4484         break_label = code.break_label
4485         code.set_loop_labels(old_loop_labels)
4486         if self.else_clause:
4487             code.putln("/*else*/ {")
4488             self.else_clause.generate_execution_code(code)
4489             code.putln("}")
4490         code.put_label(break_label)
4491         self.bound1.generate_disposal_code(code)
4492         self.bound1.free_temps(code)
4493         self.bound2.generate_disposal_code(code)
4494         self.bound2.free_temps(code)
4495         if isinstance(self.loopvar_node, ExprNodes.TempNode):
4496             self.loopvar_node.release(code)
4497         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4498             self.py_loopvar_node.release(code)
4499         if self.step is not None:
4500             self.step.generate_disposal_code(code)
4501             self.step.free_temps(code)
4502     
4503     relation_table = {
4504         # {relop : (initial offset, increment op)}
4505         '<=': ("",   "++"),
4506         '<' : ("+1", "++"),
4507         '>=': ("",   "--"),
4508         '>' : ("-1", "--")
4509     }
4510
4511     def generate_function_definitions(self, env, code):
4512         self.target.generate_function_definitions(env, code)
4513         self.bound1.generate_function_definitions(env, code)
4514         self.bound2.generate_function_definitions(env, code)
4515         if self.step is not None:
4516             self.step.generate_function_definitions(env, code)
4517         self.body.generate_function_definitions(env, code)
4518         if self.else_clause is not None:
4519             self.else_clause.generate_function_definitions(env, code)
4520     
4521     def annotate(self, code):
4522         self.target.annotate(code)
4523         self.bound1.annotate(code)
4524         self.bound2.annotate(code)
4525         if self.step:
4526             self.step.annotate(code)
4527         self.body.annotate(code)
4528         if self.else_clause:
4529             self.else_clause.annotate(code)
4530
4531
4532 class WithStatNode(StatNode):
4533     """
4534     Represents a Python with statement.
4535     
4536     This is only used at parse tree level; and is not present in
4537     analysis or generation phases.
4538     """
4539     #  manager          The with statement manager object
4540     #  target            Node (lhs expression)
4541     #  body             StatNode
4542     child_attrs = ["manager", "target", "body"]
4543
4544 class TryExceptStatNode(StatNode):
4545     #  try .. except statement
4546     #
4547     #  body             StatNode
4548     #  except_clauses   [ExceptClauseNode]
4549     #  else_clause      StatNode or None
4550
4551     child_attrs = ["body", "except_clauses", "else_clause"]
4552     
4553     def analyse_control_flow(self, env):
4554         env.start_branching(self.pos)
4555         self.body.analyse_control_flow(env)
4556         successful_try = env.control_flow # grab this for later
4557         env.next_branch(self.body.end_pos())
4558         env.finish_branching(self.body.end_pos())
4559         
4560         env.start_branching(self.except_clauses[0].pos)
4561         for except_clause in self.except_clauses:
4562             except_clause.analyse_control_flow(env)
4563             env.next_branch(except_clause.end_pos())
4564             
4565         # the else cause it executed only when the try clause finishes
4566         env.control_flow.incoming = successful_try
4567         if self.else_clause:
4568             self.else_clause.analyse_control_flow(env)
4569         env.finish_branching(self.end_pos())
4570
4571     def analyse_declarations(self, env):
4572         self.body.analyse_declarations(env)
4573         for except_clause in self.except_clauses:
4574             except_clause.analyse_declarations(env)
4575         if self.else_clause:
4576             self.else_clause.analyse_declarations(env)
4577         env.use_utility_code(reset_exception_utility_code)
4578
4579     def analyse_expressions(self, env):
4580         self.body.analyse_expressions(env)
4581         default_clause_seen = 0
4582         for except_clause in self.except_clauses:
4583             except_clause.analyse_expressions(env)
4584             if default_clause_seen:
4585                 error(except_clause.pos, "default 'except:' must be last")
4586             if not except_clause.pattern:
4587                 default_clause_seen = 1
4588         self.has_default_clause = default_clause_seen
4589         if self.else_clause:
4590             self.else_clause.analyse_expressions(env)
4591
4592     nogil_check = Node.gil_error
4593     gil_message = "Try-except statement"
4594
4595     def generate_execution_code(self, code):
4596         old_return_label = code.return_label
4597         old_break_label = code.break_label
4598         old_continue_label = code.continue_label
4599         old_error_label = code.new_error_label()
4600         our_error_label = code.error_label
4601         except_end_label = code.new_label('exception_handled')
4602         except_error_label = code.new_label('except_error')
4603         except_return_label = code.new_label('except_return')
4604         try_return_label = code.new_label('try_return')
4605         try_break_label = code.new_label('try_break')
4606         try_continue_label = code.new_label('try_continue')
4607         try_end_label = code.new_label('try_end')
4608
4609         code.putln("{")
4610         code.putln("PyObject %s;" %
4611                    ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4612         code.putln("__Pyx_ExceptionSave(%s);" %
4613                    ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4614         for var in Naming.exc_save_vars:
4615             code.put_xgotref(var)
4616         code.putln(
4617             "/*try:*/ {")
4618         code.return_label = try_return_label
4619         code.break_label = try_break_label
4620         code.continue_label = try_continue_label
4621         self.body.generate_execution_code(code)
4622         code.putln(
4623             "}")
4624         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4625         code.error_label = except_error_label
4626         code.return_label = except_return_label
4627         if self.else_clause:
4628             code.putln(
4629                 "/*else:*/ {")
4630             self.else_clause.generate_execution_code(code)
4631             code.putln(
4632                 "}")
4633         for var in Naming.exc_save_vars:
4634             code.put_xdecref_clear(var, py_object_type)
4635         code.put_goto(try_end_label)
4636         if code.label_used(try_return_label):
4637             code.put_label(try_return_label)
4638             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4639             code.putln("__Pyx_ExceptionReset(%s);" %
4640                        ', '.join(Naming.exc_save_vars))
4641             code.put_goto(old_return_label)
4642         code.put_label(our_error_label)
4643         for temp_name, type in temps_to_clean_up:
4644             code.put_xdecref_clear(temp_name, type)
4645         for except_clause in self.except_clauses:
4646             except_clause.generate_handling_code(code, except_end_label)
4647
4648         error_label_used = code.label_used(except_error_label)
4649         if error_label_used or not self.has_default_clause:
4650             if error_label_used:
4651                 code.put_label(except_error_label)
4652             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4653             code.putln("__Pyx_ExceptionReset(%s);" %
4654                        ', '.join(Naming.exc_save_vars))
4655             code.put_goto(old_error_label)
4656
4657         for exit_label, old_label in zip(
4658             [try_break_label, try_continue_label, except_return_label],
4659             [old_break_label, old_continue_label, old_return_label]):
4660
4661             if code.label_used(exit_label):
4662                 code.put_label(exit_label)
4663                 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4664                 code.putln("__Pyx_ExceptionReset(%s);" %
4665                            ', '.join(Naming.exc_save_vars))
4666                 code.put_goto(old_label)
4667
4668         if code.label_used(except_end_label):
4669             code.put_label(except_end_label)
4670             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4671             code.putln("__Pyx_ExceptionReset(%s);" %
4672                        ', '.join(Naming.exc_save_vars))
4673         code.put_label(try_end_label)
4674         code.putln("}")
4675
4676         code.return_label = old_return_label
4677         code.break_label = old_break_label
4678         code.continue_label = old_continue_label
4679         code.error_label = old_error_label
4680
4681     def generate_function_definitions(self, env, code):
4682         self.body.generate_function_definitions(env, code)
4683         for except_clause in self.except_clauses:
4684             except_clause.generate_function_definitions(env, code)
4685         if self.else_clause is not None:
4686             self.else_clause.generate_function_definitions(env, code)
4687
4688     def annotate(self, code):
4689         self.body.annotate(code)
4690         for except_node in self.except_clauses:
4691             except_node.annotate(code)
4692         if self.else_clause:
4693             self.else_clause.annotate(code)
4694
4695
4696 class ExceptClauseNode(Node):
4697     #  Part of try ... except statement.
4698     #
4699     #  pattern        [ExprNode]
4700     #  target         ExprNode or None
4701     #  body           StatNode
4702     #  excinfo_target NameNode or None   optional target for exception info
4703     #  match_flag     string             result of exception match
4704     #  exc_value      ExcValueNode       used internally
4705     #  function_name  string             qualified name of enclosing function
4706     #  exc_vars       (string * 3)       local exception variables
4707
4708     # excinfo_target is never set by the parser, but can be set by a transform
4709     # in order to extract more extensive information about the exception as a
4710     # sys.exc_info()-style tuple into a target variable
4711     
4712     child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4713
4714     exc_value = None
4715     excinfo_target = None
4716
4717     def analyse_declarations(self, env):
4718         if self.target:
4719             self.target.analyse_target_declaration(env)
4720         if self.excinfo_target is not None:
4721             self.excinfo_target.analyse_target_declaration(env)
4722         self.body.analyse_declarations(env)
4723     
4724     def analyse_expressions(self, env):
4725         import ExprNodes
4726         genv = env.global_scope()
4727         self.function_name = env.qualified_name
4728         if self.pattern:
4729             # normalise/unpack self.pattern into a list
4730             for i, pattern in enumerate(self.pattern):
4731                 pattern.analyse_expressions(env)
4732                 self.pattern[i] = pattern.coerce_to_pyobject(env)
4733
4734         if self.target:
4735             self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4736             self.target.analyse_target_expression(env, self.exc_value)
4737         if self.excinfo_target is not None:
4738             import ExprNodes
4739             self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4740                 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4741             self.excinfo_tuple.analyse_expressions(env)
4742             self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4743
4744         self.body.analyse_expressions(env)
4745
4746     def generate_handling_code(self, code, end_label):
4747         code.mark_pos(self.pos)
4748         if self.pattern:
4749             exc_tests = []
4750             for pattern in self.pattern:
4751                 pattern.generate_evaluation_code(code)
4752                 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4753
4754             match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4755             code.putln(
4756                 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4757             for pattern in self.pattern:
4758                 pattern.generate_disposal_code(code)
4759                 pattern.free_temps(code)
4760             code.putln(
4761                 "if (%s) {" %
4762                     match_flag)
4763             code.funcstate.release_temp(match_flag)
4764         else:
4765             code.putln("/*except:*/ {")
4766
4767         if not getattr(self.body, 'stats', True) and \
4768                 self.excinfo_target is None and self.target is None:
4769             # most simple case: no exception variable, empty body (pass)
4770             # => reset the exception state, done
4771             code.putln("PyErr_Restore(0,0,0);")
4772             code.put_goto(end_label)
4773             code.putln("}")
4774             return
4775         
4776         exc_vars = [code.funcstate.allocate_temp(py_object_type,
4777                                                  manage_ref=True)
4778                     for i in xrange(3)]
4779         code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4780         # We always have to fetch the exception value even if
4781         # there is no target, because this also normalises the 
4782         # exception and stores it in the thread state.
4783         code.globalstate.use_utility_code(get_exception_utility_code)
4784         exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4785         code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4786             code.error_goto(self.pos)))
4787         for x in exc_vars:
4788             code.put_gotref(x)
4789         if self.target:
4790             self.exc_value.set_var(exc_vars[1])
4791             self.exc_value.generate_evaluation_code(code)
4792             self.target.generate_assignment_code(self.exc_value, code)
4793         if self.excinfo_target is not None:
4794             for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4795                 node.set_var(tempvar)
4796             self.excinfo_tuple.generate_evaluation_code(code)
4797             self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4798
4799         old_break_label, old_continue_label = code.break_label, code.continue_label
4800         code.break_label = code.new_label('except_break')
4801         code.continue_label = code.new_label('except_continue')
4802
4803         old_exc_vars = code.funcstate.exc_vars
4804         code.funcstate.exc_vars = exc_vars
4805         self.body.generate_execution_code(code)
4806         code.funcstate.exc_vars = old_exc_vars
4807         for var in exc_vars:
4808             code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4809         code.put_goto(end_label)
4810         
4811         if code.label_used(code.break_label):
4812             code.put_label(code.break_label)
4813             for var in exc_vars:
4814                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4815             code.put_goto(old_break_label)
4816         code.break_label = old_break_label
4817
4818         if code.label_used(code.continue_label):
4819             code.put_label(code.continue_label)
4820             for var in exc_vars:
4821                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4822             code.put_goto(old_continue_label)
4823         code.continue_label = old_continue_label
4824
4825         for temp in exc_vars:
4826             code.funcstate.release_temp(temp)
4827
4828         code.putln(
4829             "}")
4830
4831     def generate_function_definitions(self, env, code):
4832         if self.target is not None:
4833             self.target.generate_function_definitions(env, code)
4834         self.body.generate_function_definitions(env, code)
4835         
4836     def annotate(self, code):
4837         if self.pattern:
4838             for pattern in self.pattern:
4839                 pattern.annotate(code)
4840         if self.target:
4841             self.target.annotate(code)
4842         self.body.annotate(code)
4843
4844
4845 class TryFinallyStatNode(StatNode):
4846     #  try ... finally statement
4847     #
4848     #  body             StatNode
4849     #  finally_clause   StatNode
4850     #
4851     #  The plan is that we funnel all continue, break
4852     #  return and error gotos into the beginning of the
4853     #  finally block, setting a variable to remember which
4854     #  one we're doing. At the end of the finally block, we
4855     #  switch on the variable to figure out where to go.
4856     #  In addition, if we're doing an error, we save the
4857     #  exception on entry to the finally block and restore
4858     #  it on exit.
4859
4860     child_attrs = ["body", "finally_clause"]
4861     
4862     preserve_exception = 1
4863     
4864     disallow_continue_in_try_finally = 0
4865     # There doesn't seem to be any point in disallowing
4866     # continue in the try block, since we have no problem
4867     # handling it.
4868
4869     def create_analysed(pos, env, body, finally_clause):
4870         node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4871         return node
4872     create_analysed = staticmethod(create_analysed)
4873     
4874     def analyse_control_flow(self, env):
4875         env.start_branching(self.pos)
4876         self.body.analyse_control_flow(env)
4877         env.next_branch(self.body.end_pos())
4878         env.finish_branching(self.body.end_pos())
4879         self.finally_clause.analyse_control_flow(env)
4880
4881     def analyse_declarations(self, env):
4882         self.body.analyse_declarations(env)
4883         self.finally_clause.analyse_declarations(env)
4884     
4885     def analyse_expressions(self, env):
4886         self.body.analyse_expressions(env)
4887         self.finally_clause.analyse_expressions(env)
4888
4889     nogil_check = Node.gil_error
4890     gil_message = "Try-finally statement"
4891
4892     def generate_execution_code(self, code):
4893         old_error_label = code.error_label
4894         old_labels = code.all_new_labels()
4895         new_labels = code.get_all_labels()
4896         new_error_label = code.error_label
4897         catch_label = code.new_label()
4898         code.putln(
4899             "/*try:*/ {")
4900         if self.disallow_continue_in_try_finally:
4901             was_in_try_finally = code.funcstate.in_try_finally
4902             code.funcstate.in_try_finally = 1
4903         self.body.generate_execution_code(code)
4904         if self.disallow_continue_in_try_finally:
4905             code.funcstate.in_try_finally = was_in_try_finally
4906         code.putln(
4907             "}")
4908         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4909         code.mark_pos(self.finally_clause.pos)
4910         code.putln(
4911             "/*finally:*/ {")
4912         cases_used = []
4913         error_label_used = 0
4914         for i, new_label in enumerate(new_labels):
4915             if new_label in code.labels_used:
4916                 cases_used.append(i)
4917                 if new_label == new_error_label:
4918                     error_label_used = 1
4919                     error_label_case = i
4920         if cases_used:
4921             code.putln(
4922                     "int __pyx_why;")
4923             if error_label_used and self.preserve_exception:
4924                 code.putln(
4925                     "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4926                 code.putln(
4927                     "int %s;" % Naming.exc_lineno_name)
4928                 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4929                 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4930                 code.putln(exc_var_init_zero)
4931             else:
4932                 exc_var_init_zero = None
4933             code.use_label(catch_label)
4934             code.putln(
4935                     "__pyx_why = 0; goto %s;" % catch_label)
4936             for i in cases_used:
4937                 new_label = new_labels[i]
4938                 #if new_label and new_label != "<try>":
4939                 if new_label == new_error_label and self.preserve_exception:
4940                     self.put_error_catcher(code, 
4941                         new_error_label, i+1, catch_label, temps_to_clean_up)
4942                 else:
4943                     code.put('%s: ' % new_label)
4944                     if exc_var_init_zero:
4945                         code.putln(exc_var_init_zero)
4946                     code.putln("__pyx_why = %s; goto %s;" % (
4947                             i+1,
4948                             catch_label))
4949             code.put_label(catch_label)
4950         code.set_all_labels(old_labels)
4951         if error_label_used:
4952             code.new_error_label()
4953             finally_error_label = code.error_label
4954         self.finally_clause.generate_execution_code(code)
4955         if error_label_used:
4956             if finally_error_label in code.labels_used and self.preserve_exception:
4957                 over_label = code.new_label()
4958                 code.put_goto(over_label);
4959                 code.put_label(finally_error_label)
4960                 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4961                 for var in Naming.exc_vars:
4962                     code.putln("Py_XDECREF(%s);" % var)
4963                 code.putln("}")
4964                 code.put_goto(old_error_label)
4965                 code.put_label(over_label)
4966             code.error_label = old_error_label
4967         if cases_used:
4968             code.putln(
4969                 "switch (__pyx_why) {")
4970             for i in cases_used:
4971                 old_label = old_labels[i]
4972                 if old_label == old_error_label and self.preserve_exception:
4973                     self.put_error_uncatcher(code, i+1, old_error_label)
4974                 else:
4975                     code.use_label(old_label)
4976                     code.putln(
4977                         "case %s: goto %s;" % (
4978                             i+1,
4979                             old_label))
4980             code.putln(
4981                 "}")
4982         code.putln(
4983             "}")
4984
4985     def generate_function_definitions(self, env, code):
4986         self.body.generate_function_definitions(env, code)
4987         self.finally_clause.generate_function_definitions(env, code)
4988
4989     def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4990         code.globalstate.use_utility_code(restore_exception_utility_code)
4991         code.putln(
4992             "%s: {" %
4993                 error_label)
4994         code.putln(
4995                 "__pyx_why = %s;" %
4996                     i)
4997         for temp_name, type in temps_to_clean_up:
4998             code.put_xdecref_clear(temp_name, type)
4999         code.putln(
5000                 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5001                     Naming.exc_vars)
5002         code.putln(
5003                 "%s = %s;" % (
5004                     Naming.exc_lineno_name, Naming.lineno_cname))
5005         code.put_goto(catch_label)
5006         code.putln("}")
5007             
5008     def put_error_uncatcher(self, code, i, error_label):
5009         code.globalstate.use_utility_code(restore_exception_utility_code)
5010         code.putln(
5011             "case %s: {" %
5012                 i)
5013         code.putln(
5014                 "__Pyx_ErrRestore(%s, %s, %s);" %
5015                     Naming.exc_vars)
5016         code.putln(
5017                 "%s = %s;" % (
5018                     Naming.lineno_cname, Naming.exc_lineno_name))
5019         for var in Naming.exc_vars:
5020             code.putln(
5021                 "%s = 0;" %
5022                     var)
5023         code.put_goto(error_label)
5024         code.putln(
5025             "}")
5026
5027     def annotate(self, code):
5028         self.body.annotate(code)
5029         self.finally_clause.annotate(code)
5030
5031
5032 class GILStatNode(TryFinallyStatNode):
5033     #  'with gil' or 'with nogil' statement
5034     #
5035     #   state   string   'gil' or 'nogil'
5036
5037 #    child_attrs = []
5038     
5039     preserve_exception = 0
5040
5041     def __init__(self, pos, state, body):
5042         self.state = state
5043         TryFinallyStatNode.__init__(self, pos,
5044             body = body,
5045             finally_clause = GILExitNode(pos, state = state))
5046
5047     def analyse_expressions(self, env):
5048         env.use_utility_code(force_init_threads_utility_code)
5049         was_nogil = env.nogil
5050         env.nogil = 1
5051         TryFinallyStatNode.analyse_expressions(self, env)
5052         env.nogil = was_nogil
5053
5054     nogil_check = None
5055
5056     def generate_execution_code(self, code):
5057         code.mark_pos(self.pos)
5058         code.putln("{")
5059         if self.state == 'gil':
5060             code.putln("#ifdef WITH_THREAD")
5061             code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5062             code.putln("#endif")
5063         else:
5064             code.putln("#ifdef WITH_THREAD")
5065             code.putln("PyThreadState *_save;")
5066             code.putln("#endif")
5067             code.putln("Py_UNBLOCK_THREADS")
5068         TryFinallyStatNode.generate_execution_code(self, code)
5069         code.putln("}")
5070
5071
5072 class GILExitNode(StatNode):
5073     #  Used as the 'finally' block in a GILStatNode
5074     #
5075     #  state   string   'gil' or 'nogil'
5076
5077     child_attrs = []
5078
5079     def analyse_expressions(self, env):
5080         pass
5081
5082     def generate_execution_code(self, code):
5083         if self.state == 'gil':
5084             code.putln("#ifdef WITH_THREAD")
5085             code.putln("PyGILState_Release(_save);")
5086             code.putln("#endif")
5087         else:
5088             code.putln("Py_BLOCK_THREADS")
5089
5090
5091 class CImportStatNode(StatNode):
5092     #  cimport statement
5093     #
5094     #  module_name   string           Qualified name of module being imported
5095     #  as_name       string or None   Name specified in "as" clause, if any
5096
5097     child_attrs = []
5098     
5099     def analyse_declarations(self, env):
5100         if not env.is_module_scope:
5101             error(self.pos, "cimport only allowed at module level")
5102             return
5103         module_scope = env.find_module(self.module_name, self.pos)
5104         if "." in self.module_name:
5105             names = [EncodedString(name) for name in self.module_name.split(".")]
5106             top_name = names[0]
5107             top_module_scope = env.context.find_submodule(top_name)
5108             module_scope = top_module_scope
5109             for name in names[1:]:
5110                 submodule_scope = module_scope.find_submodule(name)
5111                 module_scope.declare_module(name, submodule_scope, self.pos)
5112                 module_scope = submodule_scope
5113             if self.as_name:
5114                 env.declare_module(self.as_name, module_scope, self.pos)
5115             else:
5116                 env.declare_module(top_name, top_module_scope, self.pos)
5117         else:
5118             name = self.as_name or self.module_name
5119             env.declare_module(name, module_scope, self.pos)
5120
5121     def analyse_expressions(self, env):
5122         pass
5123     
5124     def generate_execution_code(self, code):
5125         pass
5126     
5127
5128 class FromCImportStatNode(StatNode):
5129     #  from ... cimport statement
5130     #
5131     #  module_name     string                        Qualified name of module
5132     #  imported_names  [(pos, name, as_name, kind)]  Names to be imported
5133     
5134     child_attrs = []
5135
5136     def analyse_declarations(self, env):
5137         if not env.is_module_scope:
5138             error(self.pos, "cimport only allowed at module level")
5139             return
5140         module_scope = env.find_module(self.module_name, self.pos)
5141         env.add_imported_module(module_scope)
5142         for pos, name, as_name, kind in self.imported_names:
5143             if name == "*":
5144                 for local_name, entry in module_scope.entries.items():
5145                     env.add_imported_entry(local_name, entry, pos)
5146             else:
5147                 entry = module_scope.lookup(name)
5148                 if entry:
5149                     if kind and not self.declaration_matches(entry, kind):
5150                         entry.redeclared(pos)
5151                 else:
5152                     if kind == 'struct' or kind == 'union':
5153                         entry = module_scope.declare_struct_or_union(name,
5154                             kind = kind, scope = None, typedef_flag = 0, pos = pos)
5155                     elif kind == 'class':
5156                         entry = module_scope.declare_c_class(name, pos = pos,
5157                             module_name = self.module_name)
5158                     else:
5159                         submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5160                         if submodule_scope.parent_module is module_scope:
5161                             env.declare_module(as_name or name, submodule_scope, self.pos)
5162                         else:
5163                             error(pos, "Name '%s' not declared in module '%s'"
5164                                 % (name, self.module_name))
5165                         
5166                 if entry:
5167                     local_name = as_name or name
5168                     env.add_imported_entry(local_name, entry, pos)
5169     
5170     def declaration_matches(self, entry, kind):
5171         if not entry.is_type:
5172             return 0
5173         type = entry.type
5174         if kind == 'class':
5175             if not type.is_extension_type:
5176                 return 0
5177         else:
5178             if not type.is_struct_or_union:
5179                 return 0
5180             if kind != type.kind:
5181                 return 0
5182         return 1
5183
5184     def analyse_expressions(self, env):
5185         pass
5186     
5187     def generate_execution_code(self, code):
5188         pass
5189
5190
5191 class FromImportStatNode(StatNode):
5192     #  from ... import statement
5193     #
5194     #  module           ImportNode
5195     #  items            [(string, NameNode)]
5196     #  interned_items   [(string, NameNode, ExprNode)]
5197     #  item             PyTempNode            used internally
5198     #  import_star      boolean               used internally
5199
5200     child_attrs = ["module"]
5201     import_star = 0
5202     
5203     def analyse_declarations(self, env):
5204         for name, target in self.items:
5205             if name == "*":
5206                 if not env.is_module_scope:
5207                     error(self.pos, "import * only allowed at module level")
5208                     return
5209                 env.has_import_star = 1
5210                 self.import_star = 1
5211             else:
5212                 target.analyse_target_declaration(env)
5213     
5214     def analyse_expressions(self, env):
5215         import ExprNodes
5216         self.module.analyse_expressions(env)
5217         self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5218         self.interned_items = []
5219         for name, target in self.items:
5220             if name == '*':
5221                 for _, entry in env.entries.items():
5222                     if not entry.is_type and entry.type.is_extension_type:
5223                         env.use_utility_code(ExprNodes.type_test_utility_code)
5224                         break
5225             else:
5226                 entry =  env.lookup(target.name)
5227                 # check whether or not entry is already cimported
5228                 if (entry.is_type and entry.type.name == name
5229                     and hasattr(entry.type, 'module_name')):
5230                     if entry.type.module_name == self.module.module_name.value:
5231                         # cimported with absolute name
5232                         continue
5233                     try:
5234                         # cimported with relative name
5235                         module = env.find_module(self.module.module_name.value,
5236                                                  pos=None)
5237                         if entry.type.module_name == module.qualified_name:
5238                             continue
5239                     except AttributeError:
5240                         pass 
5241                 target.analyse_target_expression(env, None)
5242                 if target.type is py_object_type:
5243                     coerced_item = None
5244                 else:
5245                     coerced_item = self.item.coerce_to(target.type, env)
5246                 self.interned_items.append((name, target, coerced_item))
5247     
5248     def generate_execution_code(self, code):
5249         self.module.generate_evaluation_code(code)
5250         if self.import_star:
5251             code.putln(
5252                 'if (%s(%s) < 0) %s;' % (
5253                     Naming.import_star,
5254                     self.module.py_result(),
5255                     code.error_goto(self.pos)))
5256         item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5257         self.item.set_cname(item_temp)
5258         for name, target, coerced_item in self.interned_items:
5259             cname = code.intern_identifier(name)
5260             code.putln(
5261                 '%s = PyObject_GetAttr(%s, %s); %s' % (
5262                     item_temp,
5263                     self.module.py_result(),
5264                     cname,
5265                     code.error_goto_if_null(item_temp, self.pos)))
5266             code.put_gotref(item_temp)
5267             if coerced_item is None:
5268                 target.generate_assignment_code(self.item, code)
5269             else:
5270                 coerced_item.allocate_temp_result(code)
5271                 coerced_item.generate_result_code(code)
5272                 target.generate_assignment_code(coerced_item, code)
5273             code.put_decref_clear(item_temp, py_object_type)
5274         code.funcstate.release_temp(item_temp)
5275         self.module.generate_disposal_code(code)
5276         self.module.free_temps(code)
5277
5278
5279
5280 #------------------------------------------------------------------------------------
5281 #
5282 #  Runtime support code
5283 #
5284 #------------------------------------------------------------------------------------
5285
5286 utility_function_predeclarations = \
5287 """
5288 /* inline attribute */
5289 #ifndef CYTHON_INLINE
5290   #if defined(__GNUC__)
5291     #define CYTHON_INLINE __inline__
5292   #elif defined(_MSC_VER)
5293     #define CYTHON_INLINE __inline
5294   #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5295     #define CYTHON_INLINE inline
5296   #else
5297     #define CYTHON_INLINE 
5298   #endif
5299 #endif
5300
5301 /* unused attribute */
5302 #ifndef CYTHON_UNUSED
5303 # if defined(__GNUC__)
5304 #   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5305 #     define CYTHON_UNUSED __attribute__ ((__unused__)) 
5306 #   else
5307 #     define CYTHON_UNUSED
5308 #   endif
5309 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5310 #   define CYTHON_UNUSED __attribute__ ((__unused__)) 
5311 # else
5312 #   define CYTHON_UNUSED 
5313 # endif
5314 #endif
5315
5316 typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
5317
5318 """
5319
5320 if Options.gcc_branch_hints:
5321     branch_prediction_macros = \
5322     """
5323 #ifdef __GNUC__
5324 /* Test for GCC > 2.95 */
5325 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) 
5326 #define likely(x)   __builtin_expect(!!(x), 1)
5327 #define unlikely(x) __builtin_expect(!!(x), 0)
5328 #else /* __GNUC__ > 2 ... */
5329 #define likely(x)   (x)
5330 #define unlikely(x) (x)
5331 #endif /* __GNUC__ > 2 ... */
5332 #else /* __GNUC__ */
5333 #define likely(x)   (x)
5334 #define unlikely(x) (x)
5335 #endif /* __GNUC__ */
5336     """
5337 else:
5338     branch_prediction_macros = \
5339     """
5340 #define likely(x)   (x)
5341 #define unlikely(x) (x)
5342     """
5343
5344 #get_name_predeclaration = \
5345 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5346
5347 #get_name_interned_predeclaration = \
5348 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5349
5350 #------------------------------------------------------------------------------------
5351
5352 printing_utility_code = UtilityCode(
5353 proto = """
5354 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5355 #if PY_MAJOR_VERSION >= 3
5356 static PyObject* %s = 0;
5357 static PyObject* %s = 0;
5358 #endif
5359 """ % (Naming.print_function, Naming.print_function_kwargs),
5360 cleanup = """
5361 #if PY_MAJOR_VERSION >= 3
5362 Py_CLEAR(%s);
5363 Py_CLEAR(%s);
5364 #endif
5365 """ % (Naming.print_function, Naming.print_function_kwargs),
5366 impl = r"""
5367 #if PY_MAJOR_VERSION < 3
5368 static PyObject *__Pyx_GetStdout(void) {
5369     PyObject *f = PySys_GetObject((char *)"stdout");
5370     if (!f) {
5371         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5372     }
5373     return f;
5374 }
5375
5376 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5377     PyObject* v;
5378     int i;
5379
5380     if (!f) {
5381         if (!(f = __Pyx_GetStdout()))
5382             return -1;
5383     }
5384     for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5385         if (PyFile_SoftSpace(f, 1)) {
5386             if (PyFile_WriteString(" ", f) < 0)
5387                 return -1;
5388         }
5389         v = PyTuple_GET_ITEM(arg_tuple, i);
5390         if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5391             return -1;
5392         if (PyString_Check(v)) {
5393             char *s = PyString_AsString(v);
5394             Py_ssize_t len = PyString_Size(v);
5395             if (len > 0 &&
5396                 isspace(Py_CHARMASK(s[len-1])) &&
5397                 s[len-1] != ' ')
5398                     PyFile_SoftSpace(f, 0);
5399         }
5400     }
5401     if (newline) {
5402         if (PyFile_WriteString("\n", f) < 0)
5403             return -1;
5404         PyFile_SoftSpace(f, 0);
5405     }
5406     return 0;
5407 }
5408
5409 #else /* Python 3 has a print function */
5410
5411 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5412     PyObject* kwargs = 0;
5413     PyObject* result = 0;
5414     PyObject* end_string;
5415     if (unlikely(!%(PRINT_FUNCTION)s)) {
5416         %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5417         if (!%(PRINT_FUNCTION)s)
5418             return -1;
5419     }
5420     if (stream) {
5421         kwargs = PyDict_New();
5422         if (unlikely(!kwargs))
5423             return -1;
5424         if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5425             goto bad;
5426         if (!newline) {
5427             end_string = PyUnicode_FromStringAndSize(" ", 1);
5428             if (unlikely(!end_string))
5429                 goto bad;
5430             if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5431                 Py_DECREF(end_string);
5432                 goto bad;
5433             }
5434             Py_DECREF(end_string);
5435         }
5436     } else if (!newline) {
5437         if (unlikely(!%(PRINT_KWARGS)s)) {
5438             %(PRINT_KWARGS)s = PyDict_New();
5439             if (unlikely(!%(PRINT_KWARGS)s))
5440                 return -1;
5441             end_string = PyUnicode_FromStringAndSize(" ", 1);
5442             if (unlikely(!end_string))
5443                 return -1;
5444             if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5445                 Py_DECREF(end_string);
5446                 return -1;
5447             }
5448             Py_DECREF(end_string);
5449         }
5450         kwargs = %(PRINT_KWARGS)s;
5451     }
5452     result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5453     if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5454         Py_DECREF(kwargs);
5455     if (!result)
5456         return -1;
5457     Py_DECREF(result);
5458     return 0;
5459 bad:
5460     if (kwargs != %(PRINT_KWARGS)s)
5461         Py_XDECREF(kwargs);
5462     return -1;
5463 }
5464
5465 #endif
5466 """ % {'BUILTINS'       : Naming.builtins_cname,
5467        'PRINT_FUNCTION' : Naming.print_function,
5468        'PRINT_KWARGS'   : Naming.print_function_kwargs}
5469 )
5470
5471
5472 printing_one_utility_code = UtilityCode(
5473 proto = """
5474 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5475 """,
5476 impl = r"""
5477 #if PY_MAJOR_VERSION < 3
5478
5479 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5480     if (!f) {
5481         if (!(f = __Pyx_GetStdout()))
5482             return -1;
5483     }
5484     if (PyFile_SoftSpace(f, 0)) {
5485         if (PyFile_WriteString(" ", f) < 0)
5486             return -1;
5487     }
5488     if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5489         return -1;
5490     if (PyFile_WriteString("\n", f) < 0)
5491         return -1;
5492     return 0;
5493     /* the line below is just to avoid compiler
5494      * compiler warnings about unused functions */
5495     return __Pyx_Print(f, NULL, 0);
5496 }
5497
5498 #else /* Python 3 has a print function */
5499
5500 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5501     int res;
5502     PyObject* arg_tuple = PyTuple_New(1);
5503     if (unlikely(!arg_tuple))
5504         return -1;
5505     Py_INCREF(o);
5506     PyTuple_SET_ITEM(arg_tuple, 0, o);
5507     res = __Pyx_Print(stream, arg_tuple, 1);
5508     Py_DECREF(arg_tuple);
5509     return res;
5510 }
5511
5512 #endif
5513 """,
5514 requires=[printing_utility_code])
5515
5516
5517
5518 #------------------------------------------------------------------------------------
5519
5520 # Exception raising code
5521 #
5522 # Exceptions are raised by __Pyx_Raise() and stored as plain
5523 # type/value/tb in PyThreadState->curexc_*.  When being caught by an
5524 # 'except' statement, curexc_* is moved over to exc_* by
5525 # __Pyx_GetException()
5526
5527 restore_exception_utility_code = UtilityCode(
5528 proto = """
5529 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5530 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5531 """,
5532 impl = """
5533 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5534     PyObject *tmp_type, *tmp_value, *tmp_tb;
5535     PyThreadState *tstate = PyThreadState_GET();
5536
5537     tmp_type = tstate->curexc_type;
5538     tmp_value = tstate->curexc_value;
5539     tmp_tb = tstate->curexc_traceback;
5540     tstate->curexc_type = type;
5541     tstate->curexc_value = value;
5542     tstate->curexc_traceback = tb;
5543     Py_XDECREF(tmp_type);
5544     Py_XDECREF(tmp_value);
5545     Py_XDECREF(tmp_tb);
5546 }
5547
5548 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5549     PyThreadState *tstate = PyThreadState_GET();
5550     *type = tstate->curexc_type;
5551     *value = tstate->curexc_value;
5552     *tb = tstate->curexc_traceback;
5553
5554     tstate->curexc_type = 0;
5555     tstate->curexc_value = 0;
5556     tstate->curexc_traceback = 0;
5557 }
5558
5559 """)
5560
5561 # The following function is based on do_raise() from ceval.c. There
5562 # are separate versions for Python2 and Python3 as exception handling
5563 # has changed quite a lot between the two versions.
5564
5565 raise_utility_code = UtilityCode(
5566 proto = """
5567 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5568 """,
5569 impl = """
5570 #if PY_MAJOR_VERSION < 3
5571 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5572     Py_XINCREF(type);
5573     Py_XINCREF(value);
5574     Py_XINCREF(tb);
5575     /* First, check the traceback argument, replacing None with NULL. */
5576     if (tb == Py_None) {
5577         Py_DECREF(tb);
5578         tb = 0;
5579     }
5580     else if (tb != NULL && !PyTraceBack_Check(tb)) {
5581         PyErr_SetString(PyExc_TypeError,
5582             "raise: arg 3 must be a traceback or None");
5583         goto raise_error;
5584     }
5585     /* Next, replace a missing value with None */
5586     if (value == NULL) {
5587         value = Py_None;
5588         Py_INCREF(value);
5589     }
5590     #if PY_VERSION_HEX < 0x02050000
5591     if (!PyClass_Check(type))
5592     #else
5593     if (!PyType_Check(type))
5594     #endif
5595     {
5596         /* Raising an instance.  The value should be a dummy. */
5597         if (value != Py_None) {
5598             PyErr_SetString(PyExc_TypeError,
5599                 "instance exception may not have a separate value");
5600             goto raise_error;
5601         }
5602         /* Normalize to raise <class>, <instance> */
5603         Py_DECREF(value);
5604         value = type;
5605         #if PY_VERSION_HEX < 0x02050000
5606             if (PyInstance_Check(type)) {
5607                 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5608                 Py_INCREF(type);
5609             }
5610             else {
5611                 type = 0;
5612                 PyErr_SetString(PyExc_TypeError,
5613                     "raise: exception must be an old-style class or instance");
5614                 goto raise_error;
5615             }
5616         #else
5617             type = (PyObject*) Py_TYPE(type);
5618             Py_INCREF(type);
5619             if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5620                 PyErr_SetString(PyExc_TypeError,
5621                     "raise: exception class must be a subclass of BaseException");
5622                 goto raise_error;
5623             }
5624         #endif
5625     }
5626
5627     __Pyx_ErrRestore(type, value, tb);
5628     return;
5629 raise_error:
5630     Py_XDECREF(value);
5631     Py_XDECREF(type);
5632     Py_XDECREF(tb);
5633     return;
5634 }
5635
5636 #else /* Python 3+ */
5637
5638 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5639     if (tb == Py_None) {
5640         tb = 0;
5641     } else if (tb && !PyTraceBack_Check(tb)) {
5642         PyErr_SetString(PyExc_TypeError,
5643             "raise: arg 3 must be a traceback or None");
5644         goto bad;
5645     }
5646     if (value == Py_None)
5647         value = 0;
5648
5649     if (PyExceptionInstance_Check(type)) {
5650         if (value) {
5651             PyErr_SetString(PyExc_TypeError,
5652                 "instance exception may not have a separate value");
5653             goto bad;
5654         }
5655         value = type;
5656         type = (PyObject*) Py_TYPE(value);
5657     } else if (!PyExceptionClass_Check(type)) {
5658         PyErr_SetString(PyExc_TypeError,
5659             "raise: exception class must be a subclass of BaseException");
5660         goto bad;
5661     }
5662
5663     PyErr_SetObject(type, value);
5664
5665     if (tb) {
5666         PyThreadState *tstate = PyThreadState_GET();
5667         PyObject* tmp_tb = tstate->curexc_traceback;
5668         if (tb != tmp_tb) {
5669             Py_INCREF(tb);
5670             tstate->curexc_traceback = tb;
5671             Py_XDECREF(tmp_tb);
5672         }
5673     }
5674
5675 bad:
5676     return;
5677 }
5678 #endif
5679 """,
5680 requires=[restore_exception_utility_code])
5681
5682 #------------------------------------------------------------------------------------
5683
5684 get_exception_utility_code = UtilityCode(
5685 proto = """
5686 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5687 """,
5688 impl = """
5689 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5690     PyObject *local_type, *local_value, *local_tb;
5691     PyObject *tmp_type, *tmp_value, *tmp_tb;
5692     PyThreadState *tstate = PyThreadState_GET();
5693     local_type = tstate->curexc_type;
5694     local_value = tstate->curexc_value;
5695     local_tb = tstate->curexc_traceback;
5696     tstate->curexc_type = 0;
5697     tstate->curexc_value = 0;
5698     tstate->curexc_traceback = 0;
5699     PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5700     if (unlikely(tstate->curexc_type))
5701         goto bad;
5702     #if PY_MAJOR_VERSION >= 3
5703     if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5704         goto bad;
5705     #endif
5706     *type = local_type;
5707     *value = local_value;
5708     *tb = local_tb;
5709     Py_INCREF(local_type);
5710     Py_INCREF(local_value);
5711     Py_INCREF(local_tb);
5712     tmp_type = tstate->exc_type;
5713     tmp_value = tstate->exc_value;
5714     tmp_tb = tstate->exc_traceback;
5715     tstate->exc_type = local_type;
5716     tstate->exc_value = local_value;
5717     tstate->exc_traceback = local_tb;
5718     /* Make sure tstate is in a consistent state when we XDECREF
5719        these objects (XDECREF may run arbitrary code). */
5720     Py_XDECREF(tmp_type);
5721     Py_XDECREF(tmp_value);
5722     Py_XDECREF(tmp_tb);
5723     return 0;
5724 bad:
5725     *type = 0;
5726     *value = 0;
5727     *tb = 0;
5728     Py_XDECREF(local_type);
5729     Py_XDECREF(local_value);
5730     Py_XDECREF(local_tb);
5731     return -1;
5732 }
5733
5734 """)
5735
5736 #------------------------------------------------------------------------------------
5737
5738 get_exception_tuple_utility_code = UtilityCode(proto="""
5739 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5740 """,
5741 # I doubt that calling __Pyx_GetException() here is correct as it moves
5742 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5743 # exception handlers later on from receiving it.
5744 impl = """
5745 static PyObject *__Pyx_GetExceptionTuple(void) {
5746     PyObject *type = NULL, *value = NULL, *tb = NULL;
5747     if (__Pyx_GetException(&type, &value, &tb) == 0) {
5748         PyObject* exc_info = PyTuple_New(3);
5749         if (exc_info) {
5750             Py_INCREF(type);
5751             Py_INCREF(value);
5752             Py_INCREF(tb);
5753             PyTuple_SET_ITEM(exc_info, 0, type);
5754             PyTuple_SET_ITEM(exc_info, 1, value);
5755             PyTuple_SET_ITEM(exc_info, 2, tb);
5756             return exc_info;
5757         }
5758     }
5759     return NULL;
5760 }
5761 """,
5762 requires=[get_exception_utility_code])
5763
5764 #------------------------------------------------------------------------------------
5765
5766 reset_exception_utility_code = UtilityCode(
5767 proto = """
5768 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5769 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5770 """,
5771 impl = """
5772 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5773     PyThreadState *tstate = PyThreadState_GET();
5774     *type = tstate->exc_type;
5775     *value = tstate->exc_value;
5776     *tb = tstate->exc_traceback;
5777     Py_XINCREF(*type);
5778     Py_XINCREF(*value);
5779     Py_XINCREF(*tb);
5780 }
5781
5782 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5783     PyObject *tmp_type, *tmp_value, *tmp_tb;
5784     PyThreadState *tstate = PyThreadState_GET();
5785     tmp_type = tstate->exc_type;
5786     tmp_value = tstate->exc_value;
5787     tmp_tb = tstate->exc_traceback;
5788     tstate->exc_type = type;
5789     tstate->exc_value = value;
5790     tstate->exc_traceback = tb;
5791     Py_XDECREF(tmp_type);
5792     Py_XDECREF(tmp_value);
5793     Py_XDECREF(tmp_tb);
5794 }
5795 """)
5796
5797 #------------------------------------------------------------------------------------
5798
5799 arg_type_test_utility_code = UtilityCode(
5800 proto = """
5801 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5802     const char *name, int exact); /*proto*/
5803 """,
5804 impl = """
5805 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5806     const char *name, int exact)
5807 {
5808     if (!type) {
5809         PyErr_Format(PyExc_SystemError, "Missing type object");
5810         return 0;
5811     }
5812     if (none_allowed && obj == Py_None) return 1;
5813     else if (exact) {
5814         if (Py_TYPE(obj) == type) return 1;
5815     }
5816     else {
5817         if (PyObject_TypeCheck(obj, type)) return 1;
5818     }
5819     PyErr_Format(PyExc_TypeError,
5820         "Argument '%s' has incorrect type (expected %s, got %s)",
5821         name, type->tp_name, Py_TYPE(obj)->tp_name);
5822     return 0;
5823 }
5824 """)
5825
5826 #------------------------------------------------------------------------------------
5827 #
5828 #  __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5829 #  many or too few positional arguments were found.  This handles
5830 #  Py_ssize_t formatting correctly.
5831
5832 raise_argtuple_invalid_utility_code = UtilityCode(
5833 proto = """
5834 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5835     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5836 """,
5837 impl = """
5838 static void __Pyx_RaiseArgtupleInvalid(
5839     const char* func_name,
5840     int exact,
5841     Py_ssize_t num_min,
5842     Py_ssize_t num_max,
5843     Py_ssize_t num_found)
5844 {
5845     Py_ssize_t num_expected;
5846     const char *number, *more_or_less;
5847
5848     if (num_found < num_min) {
5849         num_expected = num_min;
5850         more_or_less = "at least";
5851     } else {
5852         num_expected = num_max;
5853         more_or_less = "at most";
5854     }
5855     if (exact) {
5856         more_or_less = "exactly";
5857     }
5858     number = (num_expected == 1) ? "" : "s";
5859     PyErr_Format(PyExc_TypeError,
5860         #if PY_VERSION_HEX < 0x02050000
5861             "%s() takes %s %d positional argument%s (%d given)",
5862         #else
5863             "%s() takes %s %zd positional argument%s (%zd given)",
5864         #endif
5865         func_name, more_or_less, num_expected, number, num_found);
5866 }
5867 """)
5868
5869 raise_keyword_required_utility_code = UtilityCode(
5870 proto = """
5871 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5872 """,
5873 impl = """
5874 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5875     const char* func_name,
5876     PyObject* kw_name)
5877 {
5878     PyErr_Format(PyExc_TypeError,
5879         #if PY_MAJOR_VERSION >= 3
5880         "%s() needs keyword-only argument %U", func_name, kw_name);
5881         #else
5882         "%s() needs keyword-only argument %s", func_name,
5883         PyString_AS_STRING(kw_name));
5884         #endif
5885 }
5886 """)
5887
5888 raise_double_keywords_utility_code = UtilityCode(
5889 proto = """
5890 static void __Pyx_RaiseDoubleKeywordsError(
5891     const char* func_name, PyObject* kw_name); /*proto*/
5892 """,
5893 impl = """
5894 static void __Pyx_RaiseDoubleKeywordsError(
5895     const char* func_name,
5896     PyObject* kw_name)
5897 {
5898     PyErr_Format(PyExc_TypeError,
5899         #if PY_MAJOR_VERSION >= 3
5900         "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5901         #else
5902         "%s() got multiple values for keyword argument '%s'", func_name,
5903         PyString_AS_STRING(kw_name));
5904         #endif
5905 }
5906 """)
5907
5908 #------------------------------------------------------------------------------------
5909 #
5910 #  __Pyx_CheckKeywordStrings raises an error if non-string keywords
5911 #  were passed to a function, or if any keywords were passed to a
5912 #  function that does not accept them.
5913
5914 keyword_string_check_utility_code = UtilityCode(
5915 proto = """
5916 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5917     const char* function_name, int kw_allowed); /*proto*/
5918 """,
5919 impl = """
5920 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5921     PyObject *kwdict,
5922     const char* function_name,
5923     int kw_allowed)
5924 {
5925     PyObject* key = 0;
5926     Py_ssize_t pos = 0;
5927     while (PyDict_Next(kwdict, &pos, &key, 0)) {
5928         #if PY_MAJOR_VERSION < 3
5929         if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5930         #else
5931         if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5932         #endif
5933             goto invalid_keyword_type;
5934     }
5935     if ((!kw_allowed) && unlikely(key))
5936         goto invalid_keyword;
5937     return 1;
5938 invalid_keyword_type:
5939     PyErr_Format(PyExc_TypeError,
5940         "%s() keywords must be strings", function_name);
5941     return 0;
5942 invalid_keyword:
5943     PyErr_Format(PyExc_TypeError,
5944     #if PY_MAJOR_VERSION < 3
5945         "%s() got an unexpected keyword argument '%s'",
5946         function_name, PyString_AsString(key));
5947     #else
5948         "%s() got an unexpected keyword argument '%U'",
5949         function_name, key);
5950     #endif
5951     return 0;
5952 }
5953 """)
5954
5955 #------------------------------------------------------------------------------------
5956 #
5957 #  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5958 #  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
5959 #  keywords will raise an invalid keyword error.
5960 #
5961 #  Three kinds of errors are checked: 1) non-string keywords, 2)
5962 #  unexpected keywords and 3) overlap with positional arguments.
5963 #
5964 #  If num_posargs is greater 0, it denotes the number of positional
5965 #  arguments that were passed and that must therefore not appear
5966 #  amongst the keywords as well.
5967 #
5968 #  This method does not check for required keyword arguments.
5969 #
5970
5971 parse_keywords_utility_code = UtilityCode(
5972 proto = """
5973 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5974     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5975     const char* function_name); /*proto*/
5976 """,
5977 impl = """
5978 static int __Pyx_ParseOptionalKeywords(
5979     PyObject *kwds,
5980     PyObject **argnames[],
5981     PyObject *kwds2,
5982     PyObject *values[],
5983     Py_ssize_t num_pos_args,
5984     const char* function_name)
5985 {
5986     PyObject *key = 0, *value = 0;
5987     Py_ssize_t pos = 0;
5988     PyObject*** name;
5989     PyObject*** first_kw_arg = argnames + num_pos_args;
5990
5991     while (PyDict_Next(kwds, &pos, &key, &value)) {
5992         name = first_kw_arg;
5993         while (*name && (**name != key)) name++;
5994         if (*name) {
5995             values[name-argnames] = value;
5996         } else {
5997             #if PY_MAJOR_VERSION < 3
5998             if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5999             #else
6000             if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6001             #endif
6002                 goto invalid_keyword_type;
6003             } else {
6004                 for (name = first_kw_arg; *name; name++) {
6005                     #if PY_MAJOR_VERSION >= 3
6006                     if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6007                         PyUnicode_Compare(**name, key) == 0) break;
6008                     #else
6009                     if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6010                         _PyString_Eq(**name, key)) break;
6011                     #endif
6012                 }
6013                 if (*name) {
6014                     values[name-argnames] = value;
6015                 } else {
6016                     /* unexpected keyword found */
6017                     for (name=argnames; name != first_kw_arg; name++) {
6018                         if (**name == key) goto arg_passed_twice;
6019                         #if PY_MAJOR_VERSION >= 3
6020                         if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6021                             PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6022                         #else
6023                         if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6024                             _PyString_Eq(**name, key)) goto arg_passed_twice;
6025                         #endif
6026                     }
6027                     if (kwds2) {
6028                         if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6029                     } else {
6030                         goto invalid_keyword;
6031                     }
6032                 }
6033             }
6034         }
6035     }
6036     return 0;
6037 arg_passed_twice:
6038     __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6039     goto bad;
6040 invalid_keyword_type:
6041     PyErr_Format(PyExc_TypeError,
6042         "%s() keywords must be strings", function_name);
6043     goto bad;
6044 invalid_keyword:
6045     PyErr_Format(PyExc_TypeError,
6046     #if PY_MAJOR_VERSION < 3
6047         "%s() got an unexpected keyword argument '%s'",
6048         function_name, PyString_AsString(key));
6049     #else
6050         "%s() got an unexpected keyword argument '%U'",
6051         function_name, key);
6052     #endif
6053 bad:
6054     return -1;
6055 }
6056 """)
6057
6058 #------------------------------------------------------------------------------------
6059
6060 traceback_utility_code = UtilityCode(
6061 proto = """
6062 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6063 """,
6064 impl = """
6065 #include "compile.h"
6066 #include "frameobject.h"
6067 #include "traceback.h"
6068
6069 static void __Pyx_AddTraceback(const char *funcname) {
6070     PyObject *py_srcfile = 0;
6071     PyObject *py_funcname = 0;
6072     PyObject *py_globals = 0;
6073     PyCodeObject *py_code = 0;
6074     PyFrameObject *py_frame = 0;
6075
6076     #if PY_MAJOR_VERSION < 3
6077     py_srcfile = PyString_FromString(%(FILENAME)s);
6078     #else
6079     py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6080     #endif
6081     if (!py_srcfile) goto bad;
6082     if (%(CLINENO)s) {
6083         #if PY_MAJOR_VERSION < 3
6084         py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6085         #else
6086         py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6087         #endif
6088     }
6089     else {
6090         #if PY_MAJOR_VERSION < 3
6091         py_funcname = PyString_FromString(funcname);
6092         #else
6093         py_funcname = PyUnicode_FromString(funcname);
6094         #endif
6095     }
6096     if (!py_funcname) goto bad;
6097     py_globals = PyModule_GetDict(%(GLOBALS)s);
6098     if (!py_globals) goto bad;
6099     py_code = PyCode_New(
6100         0,            /*int argcount,*/
6101         #if PY_MAJOR_VERSION >= 3
6102         0,            /*int kwonlyargcount,*/
6103         #endif
6104         0,            /*int nlocals,*/
6105         0,            /*int stacksize,*/
6106         0,            /*int flags,*/
6107         %(EMPTY_BYTES)s, /*PyObject *code,*/
6108         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6109         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6110         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6111         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6112         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6113         py_srcfile,   /*PyObject *filename,*/
6114         py_funcname,  /*PyObject *name,*/
6115         %(LINENO)s,   /*int firstlineno,*/
6116         %(EMPTY_BYTES)s  /*PyObject *lnotab*/
6117     );
6118     if (!py_code) goto bad;
6119     py_frame = PyFrame_New(
6120         PyThreadState_GET(), /*PyThreadState *tstate,*/
6121         py_code,             /*PyCodeObject *code,*/
6122         py_globals,          /*PyObject *globals,*/
6123         0                    /*PyObject *locals*/
6124     );
6125     if (!py_frame) goto bad;
6126     py_frame->f_lineno = %(LINENO)s;
6127     PyTraceBack_Here(py_frame);
6128 bad:
6129     Py_XDECREF(py_srcfile);
6130     Py_XDECREF(py_funcname);
6131     Py_XDECREF(py_code);
6132     Py_XDECREF(py_frame);
6133 }
6134 """ % {
6135     'FILENAME': Naming.filename_cname,
6136     'LINENO':  Naming.lineno_cname,
6137     'CFILENAME': Naming.cfilenm_cname,
6138     'CLINENO':  Naming.clineno_cname,
6139     'GLOBALS': Naming.module_cname,
6140     'EMPTY_TUPLE' : Naming.empty_tuple,
6141     'EMPTY_BYTES' : Naming.empty_bytes,
6142 })
6143
6144 #------------------------------------------------------------------------------------
6145
6146 unraisable_exception_utility_code = UtilityCode(
6147 proto = """
6148 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6149 """,
6150 impl = """
6151 static void __Pyx_WriteUnraisable(const char *name) {
6152     PyObject *old_exc, *old_val, *old_tb;
6153     PyObject *ctx;
6154     __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6155     #if PY_MAJOR_VERSION < 3
6156     ctx = PyString_FromString(name);
6157     #else
6158     ctx = PyUnicode_FromString(name);
6159     #endif
6160     __Pyx_ErrRestore(old_exc, old_val, old_tb);
6161     if (!ctx) {
6162         PyErr_WriteUnraisable(Py_None);
6163     } else {
6164         PyErr_WriteUnraisable(ctx);
6165         Py_DECREF(ctx);
6166     }
6167 }
6168 """,
6169 requires=[restore_exception_utility_code])
6170
6171 #------------------------------------------------------------------------------------
6172
6173 set_vtable_utility_code = UtilityCode(
6174 proto = """
6175 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6176 """,
6177 impl = """
6178 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6179 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6180     PyObject *ob = PyCapsule_New(vtable, 0, 0);
6181 #else
6182     PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6183 #endif
6184     if (!ob)
6185         goto bad;
6186     if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6187         goto bad;
6188     Py_DECREF(ob);
6189     return 0;
6190 bad:
6191     Py_XDECREF(ob);
6192     return -1;
6193 }
6194 """)
6195
6196 #------------------------------------------------------------------------------------
6197
6198 get_vtable_utility_code = UtilityCode(
6199 proto = """
6200 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6201 """,
6202 impl = r"""
6203 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6204     PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6205     if (!ob)
6206         goto bad;
6207 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6208     *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6209 #else
6210     *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6211 #endif
6212     if (!*(void **)vtabptr)
6213         goto bad;
6214     Py_DECREF(ob);
6215     return 0;
6216 bad:
6217     Py_XDECREF(ob);
6218     return -1;
6219 }
6220 """)
6221
6222 #------------------------------------------------------------------------------------
6223
6224 init_string_tab_utility_code = UtilityCode(
6225 proto = """
6226 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6227 """,
6228 impl = """
6229 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6230     while (t->p) {
6231         #if PY_MAJOR_VERSION < 3
6232         if (t->is_unicode) {
6233             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6234         } else if (t->intern) {
6235             *t->p = PyString_InternFromString(t->s);
6236         } else {
6237             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6238         }
6239         #else  /* Python 3+ has unicode identifiers */
6240         if (t->is_unicode | t->is_str) {
6241             if (t->intern) {
6242                 *t->p = PyUnicode_InternFromString(t->s);
6243             } else if (t->encoding) {
6244                 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6245             } else {
6246                 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6247             }
6248         } else {
6249             *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6250         }
6251         #endif
6252         if (!*t->p)
6253             return -1;
6254         ++t;
6255     }
6256     return 0;
6257 }
6258 """)
6259
6260 #------------------------------------------------------------------------------------
6261
6262 force_init_threads_utility_code = UtilityCode(
6263 proto="""
6264 #ifndef __PYX_FORCE_INIT_THREADS
6265   #if PY_VERSION_HEX < 0x02040200
6266     #define __PYX_FORCE_INIT_THREADS 1
6267   #else
6268     #define __PYX_FORCE_INIT_THREADS 0
6269   #endif
6270 #endif
6271 """)
6272
6273 #------------------------------------------------------------------------------------
6274
6275 # Note that cPython ignores PyTrace_EXCEPTION, 
6276 # but maybe some other profilers don't. 
6277
6278 profile_utility_code = UtilityCode(proto="""
6279 #ifndef CYTHON_PROFILE
6280   #define CYTHON_PROFILE 1
6281 #endif
6282
6283 #ifndef CYTHON_PROFILE_REUSE_FRAME
6284   #define CYTHON_PROFILE_REUSE_FRAME 0
6285 #endif
6286
6287 #if CYTHON_PROFILE
6288
6289   #include "compile.h"
6290   #include "frameobject.h"
6291   #include "traceback.h"
6292
6293   #if CYTHON_PROFILE_REUSE_FRAME
6294     #define CYTHON_FRAME_MODIFIER static
6295     #define CYTHON_FRAME_DEL
6296   #else
6297     #define CYTHON_FRAME_MODIFIER
6298     #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6299   #endif
6300
6301   #define __Pyx_TraceDeclarations                                  \\
6302   static PyCodeObject *%(FRAME_CODE)s = NULL;                      \\
6303   CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL;           \\
6304   int __Pyx_use_tracing = 0;                                                         
6305
6306   #define __Pyx_TraceCall(funcname, srcfile, firstlineno)                            \\
6307   if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) {      \\
6308       __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno);  \\
6309   }
6310
6311   #define __Pyx_TraceException()                                                           \\
6312   if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6313       PyObject *exc_info = __Pyx_GetExceptionTuple();                                      \\
6314       if (exc_info) {                                                                      \\
6315           PyThreadState_GET()->c_profilefunc(                                              \\
6316               PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info);  \\
6317           Py_DECREF(exc_info);                                                             \\
6318       }                                                                                    \\
6319   }
6320
6321   #define __Pyx_TraceReturn(result)                                                  \\
6322   if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6323       PyThreadState_GET()->c_profilefunc(                                            \\
6324           PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result);     \\
6325       CYTHON_FRAME_DEL;                                                               \\
6326   }
6327
6328   static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6329   static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6330
6331 #else
6332
6333   #define __Pyx_TraceDeclarations
6334   #define __Pyx_TraceCall(funcname, srcfile, firstlineno) 
6335   #define __Pyx_TraceException() 
6336   #define __Pyx_TraceReturn(result) 
6337
6338 #endif /* CYTHON_PROFILE */
6339 """ 
6340 % {
6341     "FRAME": Naming.frame_cname,
6342     "FRAME_CODE": Naming.frame_code_cname,
6343 },
6344 impl = """
6345
6346 #if CYTHON_PROFILE
6347
6348 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6349                                    PyFrameObject** frame,
6350                                    const char *funcname,
6351                                    const char *srcfile,
6352                                    int firstlineno) {
6353     if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6354         if (*code == NULL) {
6355             *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6356             if (*code == NULL) return 0;
6357         }
6358         *frame = PyFrame_New(
6359             PyThreadState_GET(),            /*PyThreadState *tstate*/
6360             *code,                          /*PyCodeObject *code*/
6361             PyModule_GetDict(%(MODULE)s),      /*PyObject *globals*/
6362             0                               /*PyObject *locals*/
6363         );
6364         if (*frame == NULL) return 0;
6365     }
6366     else {
6367         (*frame)->f_tstate = PyThreadState_GET();
6368     }
6369     return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6370 }
6371
6372 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6373     PyObject *py_srcfile = 0;
6374     PyObject *py_funcname = 0;
6375     PyCodeObject *py_code = 0;
6376
6377     #if PY_MAJOR_VERSION < 3
6378     py_funcname = PyString_FromString(funcname);
6379     py_srcfile = PyString_FromString(srcfile);
6380     #else
6381     py_funcname = PyUnicode_FromString(funcname);
6382     py_srcfile = PyUnicode_FromString(srcfile);
6383     #endif
6384     if (!py_funcname | !py_srcfile) goto bad;
6385
6386     py_code = PyCode_New(
6387         0,                /*int argcount,*/
6388         #if PY_MAJOR_VERSION >= 3
6389         0,                /*int kwonlyargcount,*/
6390         #endif
6391         0,                /*int nlocals,*/
6392         0,                /*int stacksize,*/
6393         0,                /*int flags,*/
6394         %(EMPTY_BYTES)s,  /*PyObject *code,*/
6395         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6396         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6397         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6398         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6399         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6400         py_srcfile,       /*PyObject *filename,*/
6401         py_funcname,      /*PyObject *name,*/
6402         firstlineno,      /*int firstlineno,*/
6403         %(EMPTY_BYTES)s   /*PyObject *lnotab*/
6404     );
6405
6406 bad: 
6407     Py_XDECREF(py_srcfile);
6408     Py_XDECREF(py_funcname);
6409     
6410     return py_code;
6411 }
6412
6413 #endif /* CYTHON_PROFILE */
6414 """ % {
6415     'EMPTY_TUPLE' : Naming.empty_tuple,
6416     'EMPTY_BYTES' : Naming.empty_bytes,
6417     "MODULE": Naming.module_cname,
6418 })