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