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