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