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