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