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