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