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