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