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