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