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