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