better error when user-declared type conflicts with builtin type (#170)
[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 from DebugFlags import debug_disposal_code
23
24 absolute_path_length = 0
25
26 def relative_position(pos):
27     """
28     We embed the relative filename in the generated C file, since we
29     don't want to have to regnerate and compile all the source code
30     whenever the Python install directory moves (which could happen,
31     e.g,. when distributing binaries.)
32     
33     INPUT:
34         a position tuple -- (absolute filename, line number column position)
35
36     OUTPUT:
37         relative filename
38         line number
39
40     AUTHOR: William Stein
41     """
42     global absolute_path_length
43     if absolute_path_length==0:
44         absolute_path_length = len(os.path.abspath(os.getcwd())) 
45     return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
46
47 def embed_position(pos, docstring):
48     if not Options.embed_pos_in_docstring:
49         return docstring
50     pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
51     if docstring is None:
52         # unicode string
53         return EncodedString(pos_line)
54
55     # make sure we can encode the filename in the docstring encoding
56     # otherwise make the docstring a unicode string
57     encoding = docstring.encoding
58     if encoding is not None:
59         try:
60             encoded_bytes = pos_line.encode(encoding)
61         except UnicodeEncodeError:
62             encoding = None
63
64     if not docstring:
65         # reuse the string encoding of the original docstring
66         doc = EncodedString(pos_line)
67     else:
68         doc = EncodedString(pos_line + u'\n' + docstring)
69     doc.encoding = encoding
70     return doc
71
72
73 from Code import CCodeWriter
74 from types import FunctionType
75
76 def write_func_call(func):
77     def f(*args, **kwds):
78         if len(args) > 1 and isinstance(args[1], CCodeWriter):
79             # here we annotate the code with this function call
80             # but only if new code is generated
81             node, code = args[:2]
82             marker = '                    /* %s -> %s.%s %s */' % (
83                     ' ' * code.call_level,
84                     node.__class__.__name__, 
85                     func.__name__, 
86                     node.pos[1:])
87             pristine = code.buffer.stream.tell()
88             code.putln(marker)
89             start = code.buffer.stream.tell()
90             code.call_level += 4
91             res = func(*args, **kwds)
92             code.call_level -= 4
93             if start == code.buffer.stream.tell():
94                 code.buffer.stream.seek(pristine)
95             else:
96                 marker = marker.replace('->', '<-')
97                 code.putln(marker)
98             return res
99         else:
100             return func(*args, **kwds)
101     return f
102
103 class VerboseCodeWriter(type):
104     # Set this as a metaclass to trace function calls in code.
105     # This slows down code generation and makes much larger files. 
106     def __new__(cls, name, bases, attrs):
107         attrs = dict(attrs)
108         for mname, m in attrs.items():
109             if isinstance(m, FunctionType):
110                 attrs[mname] = write_func_call(m)
111         return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
112
113
114 class Node(object):
115     #  pos         (string, int, int)   Source file position
116     #  is_name     boolean              Is a NameNode
117     #  is_literal  boolean              Is a ConstNode
118
119     if DebugFlags.debug_trace_code_generation:
120         __metaclass__ = VerboseCodeWriter
121     
122     is_name = 0
123     is_literal = 0
124     temps = None
125
126     # All descandants should set child_attrs to a list of the attributes
127     # containing nodes considered "children" in the tree. Each such attribute
128     # can either contain a single node or a list of nodes. See Visitor.py.
129     child_attrs = None
130     
131     def __init__(self, pos, **kw):
132         self.pos = pos
133         self.__dict__.update(kw)
134     
135     gil_message = "Operation"
136
137     def gil_check(self, env):
138         if env.nogil:
139             self.gil_error()
140
141     def gil_error(self):
142         error(self.pos, "%s not allowed without gil" % self.gil_message)
143
144     def clone_node(self):
145         """Clone the node. This is defined as a shallow copy, except for member lists
146            amongst the child attributes (from get_child_accessors) which are also
147            copied. Lists containing child nodes are thus seen as a way for the node
148            to hold multiple children directly; the list is not treated as a seperate
149            level in the tree."""
150         result = copy.copy(self)
151         for attrname in result.child_attrs:
152             value = getattr(result, attrname)
153             if isinstance(value, list):
154                 setattr(result, attrname, [x for x in value])
155         return result
156     
157     
158     #
159     #  There are 4 phases of parse tree processing, applied in order to
160     #  all the statements in a given scope-block:
161     #
162     #  (0) analyse_control_flow
163     #        Create the control flow tree into which state can be asserted and
164     #        queried.
165     #
166     #  (1) analyse_declarations
167     #        Make symbol table entries for all declarations at the current
168     #        level, both explicit (def, cdef, etc.) and implicit (assignment
169     #        to an otherwise undeclared name).
170     #
171     #  (2) analyse_expressions
172     #         Determine the result types of expressions and fill in the
173     #         'type' attribute of each ExprNode. Insert coercion nodes into the
174     #         tree where needed to convert to and from Python objects. 
175     #         Allocate temporary locals for intermediate results. Fill
176     #         in the 'result_code' attribute of each ExprNode with a C code
177     #         fragment.
178     #
179     #  (3) generate_code
180     #         Emit C code for all declarations, statements and expressions.
181     #         Recursively applies the 3 processing phases to the bodies of
182     #         functions.
183     #
184     
185     def analyse_control_flow(self, env):
186         pass
187     
188     def analyse_declarations(self, env):
189         pass
190     
191     def analyse_expressions(self, env):
192         raise InternalError("analyse_expressions not implemented for %s" % \
193             self.__class__.__name__)
194     
195     def generate_code(self, code):
196         raise InternalError("generate_code not implemented for %s" % \
197             self.__class__.__name__)
198             
199     def annotate(self, code):
200         # mro does the wrong thing
201         if isinstance(self, BlockNode):
202             self.body.annotate(code)
203             
204     def end_pos(self):
205         try:
206             return self._end_pos
207         except AttributeError:
208             pos = self.pos
209             if not self.child_attrs:
210                 self._end_pos = pos
211                 return pos
212             for attr in self.child_attrs:
213                 child = getattr(self, attr)
214                 # Sometimes lists, sometimes nodes
215                 if child is None:
216                     pass
217                 elif isinstance(child, list):
218                     for c in child:
219                         pos = max(pos, c.end_pos())
220                 else:
221                     pos = max(pos, child.end_pos())
222             self._end_pos = pos
223             return pos
224
225     def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
226         if cutoff == 0:
227             return "<...nesting level cutoff...>"
228         if encountered is None:
229             encountered = set()
230         if id(self) in encountered:
231             return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
232         encountered.add(id(self))
233         
234         def dump_child(x, level):
235             if isinstance(x, Node):
236                 return x.dump(level, filter_out, cutoff-1, encountered)
237             elif isinstance(x, list):
238                 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
239             else:
240                 return repr(x)
241             
242         
243         attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
244         if len(attrs) == 0:
245             return "<%s (%d)>" % (self.__class__.__name__, id(self))
246         else:
247             indent = "  " * level
248             res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
249             for key, value in attrs:
250                 res += "%s  %s: %s\n" % (indent, key, dump_child(value, level + 1))
251             res += "%s>" % indent
252             return res
253
254 class CompilerDirectivesNode(Node):
255     """
256     Sets compiler directives for the children nodes
257     """
258     #  directives     {string:value}  A dictionary holding the right value for
259     #                                 *all* possible directives.
260     #  body           Node
261     child_attrs = ["body"]
262
263     def analyse_control_flow(self, env):
264         old = env.directives
265         env.directives = self.directives
266         self.body.analyse_control_flow(env)
267         env.directives = old
268
269     def analyse_declarations(self, env):
270         old = env.directives
271         env.directives = self.directives
272         self.body.analyse_declarations(env)
273         env.directives = old
274     
275     def analyse_expressions(self, env):
276         old = env.directives
277         env.directives = self.directives
278         self.body.analyse_expressions(env)
279         env.directives = old
280
281     def generate_function_definitions(self, env, code):
282         env_old = env.directives
283         code_old = code.globalstate.directives
284         code.globalstate.directives = self.directives
285         self.body.generate_function_definitions(env, code)
286         env.directives = env_old
287         code.globalstate.directives = code_old
288             
289     def generate_execution_code(self, code):
290         old = code.globalstate.directives
291         code.globalstate.directives = self.directives
292         self.body.generate_execution_code(code)
293         code.globalstate.directives = old
294             
295     def annotate(self, code):
296         old = code.globalstate.directives
297         code.globalstate.directives = self.directives
298         self.body.annotate(code)
299         code.globalstate.directives = old
300         
301 class BlockNode(object):
302     #  Mixin class for nodes representing a declaration block.
303
304     def generate_const_definitions(self, env, code):
305         if env.const_entries:
306             for entry in env.const_entries:
307                 if not entry.is_interned:
308                     code.globalstate.add_const_definition(entry)
309
310     def generate_interned_string_decls(self, env, code):
311         entries = env.global_scope().new_interned_string_entries
312         if entries:
313             for entry in entries:
314                 code.globalstate.add_interned_string_decl(entry)
315             del entries[:]
316
317     def generate_py_string_decls(self, env, code):
318         if env is None:
319             return # earlier error
320         entries = env.pystring_entries
321         if entries:
322             for entry in entries:
323                 if not entry.is_interned:
324                     code.globalstate.add_py_string_decl(entry)
325
326     def generate_interned_num_decls(self, env, code):
327         #  Flush accumulated interned nums from the global scope
328         #  and generate declarations for them.
329         genv = env.global_scope()
330         entries = genv.interned_nums
331         if entries:
332             for entry in entries:
333                 code.globalstate.add_interned_num_decl(entry)
334             del entries[:]
335
336     def generate_cached_builtins_decls(self, env, code):
337         entries = env.global_scope().undeclared_cached_builtins
338         for entry in entries:
339             code.globalstate.add_cached_builtin_decl(entry)
340         del entries[:]
341         
342
343 class StatListNode(Node):
344     # stats     a list of StatNode
345     
346     child_attrs = ["stats"]
347
348     def create_analysed(pos, env, *args, **kw):
349         node = StatListNode(pos, *args, **kw)
350         return node # No node-specific analysis necesarry
351     create_analysed = staticmethod(create_analysed)
352     
353     def analyse_control_flow(self, env):
354         for stat in self.stats:
355             stat.analyse_control_flow(env)
356
357     def analyse_declarations(self, env):
358         #print "StatListNode.analyse_declarations" ###
359         for stat in self.stats:
360             stat.analyse_declarations(env)
361     
362     def analyse_expressions(self, env):
363         #print "StatListNode.analyse_expressions" ###
364         for stat in self.stats:
365             stat.analyse_expressions(env)
366     
367     def generate_function_definitions(self, env, code):
368         #print "StatListNode.generate_function_definitions" ###
369         for stat in self.stats:
370             stat.generate_function_definitions(env, code)
371             
372     def generate_execution_code(self, code):
373         #print "StatListNode.generate_execution_code" ###
374         for stat in self.stats:
375             code.mark_pos(stat.pos)
376             stat.generate_execution_code(code)
377             
378     def annotate(self, code):
379         for stat in self.stats:
380             stat.annotate(code)
381     
382
383 class StatNode(Node):
384     #
385     #  Code generation for statements is split into the following subphases:
386     #
387     #  (1) generate_function_definitions
388     #        Emit C code for the definitions of any structs,
389     #        unions, enums and functions defined in the current
390     #        scope-block.
391     #
392     #  (2) generate_execution_code
393     #        Emit C code for executable statements.
394     #
395     
396     def generate_function_definitions(self, env, code):
397         pass
398     
399     def generate_execution_code(self, code):
400         raise InternalError("generate_execution_code not implemented for %s" % \
401             self.__class__.__name__)
402
403
404 class CDefExternNode(StatNode):
405     #  include_file   string or None
406     #  body           StatNode
407     
408     child_attrs = ["body"]
409     
410     def analyse_declarations(self, env):
411         if self.include_file:
412             env.add_include_file(self.include_file)
413         old_cinclude_flag = env.in_cinclude
414         env.in_cinclude = 1
415         self.body.analyse_declarations(env)
416         env.in_cinclude = old_cinclude_flag
417     
418     def analyse_expressions(self, env):
419         pass
420     
421     def generate_execution_code(self, code):
422         pass
423
424     def annotate(self, code):
425         self.body.annotate(code)
426         
427
428 class CDeclaratorNode(Node):
429     # Part of a C declaration.
430     #
431     # Processing during analyse_declarations phase:
432     #
433     #   analyse
434     #      Returns (name, type) pair where name is the
435     #      CNameDeclaratorNode of the name being declared 
436     #      and type is the type it is being declared as.
437     #
438     #  calling_convention  string   Calling convention of CFuncDeclaratorNode
439     #                               for which this is a base 
440
441     child_attrs = []
442
443     calling_convention = ""
444
445
446 class CNameDeclaratorNode(CDeclaratorNode):
447     #  name    string             The Pyrex name being declared
448     #  cname   string or None     C name, if specified
449     #  default ExprNode or None   the value assigned on declaration
450     
451     child_attrs = ['default']
452     
453     default = None
454     
455     def analyse(self, base_type, env, nonempty = 0):
456         if nonempty and self.name == '':
457             # May have mistaken the name for the type. 
458             if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
459                 error(self.pos, "Missing argument name")
460             elif base_type.is_void:
461                 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
462             else:
463                 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
464                 base_type = py_object_type
465         self.type = base_type
466         return self, base_type
467         
468 class CPtrDeclaratorNode(CDeclaratorNode):
469     # base     CDeclaratorNode
470     
471     child_attrs = ["base"]
472
473     def analyse(self, base_type, env, nonempty = 0):
474         if base_type.is_pyobject:
475             error(self.pos,
476                 "Pointer base type cannot be a Python object")
477         ptr_type = PyrexTypes.c_ptr_type(base_type)
478         return self.base.analyse(ptr_type, env, nonempty = nonempty)
479         
480 class CArrayDeclaratorNode(CDeclaratorNode):
481     # base        CDeclaratorNode
482     # dimension   ExprNode
483
484     child_attrs = ["base", "dimension"]
485     
486     def analyse(self, base_type, env, nonempty = 0):
487         if self.dimension:
488             self.dimension.analyse_const_expression(env)
489             if not self.dimension.type.is_int:
490                 error(self.dimension.pos, "Array dimension not integer")
491             size = self.dimension.result()
492             try:
493                 size = int(size)
494             except ValueError:
495                 # runtime constant?
496                 pass
497         else:
498             size = None
499         if not base_type.is_complete():
500             error(self.pos,
501                 "Array element type '%s' is incomplete" % base_type)
502         if base_type.is_pyobject:
503             error(self.pos,
504                 "Array element cannot be a Python object")
505         if base_type.is_cfunction:
506             error(self.pos,
507                 "Array element cannot be a function")
508         array_type = PyrexTypes.c_array_type(base_type, size)
509         return self.base.analyse(array_type, env, nonempty = nonempty)
510
511
512 class CFuncDeclaratorNode(CDeclaratorNode):
513     # base             CDeclaratorNode
514     # args             [CArgDeclNode]
515     # has_varargs      boolean
516     # exception_value  ConstNode
517     # exception_check  boolean    True if PyErr_Occurred check needed
518     # nogil            boolean    Can be called without gil
519     # with_gil         boolean    Acquire gil around function body
520     
521     child_attrs = ["base", "args", "exception_value"]
522
523     overridable = 0
524     optional_arg_count = 0
525
526     def analyse(self, return_type, env, nonempty = 0):
527         if nonempty:
528             nonempty -= 1
529         func_type_args = []
530         for arg_node in self.args:
531             name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
532             name = name_declarator.name
533             if name_declarator.cname:
534                 error(self.pos, 
535                     "Function argument cannot have C name specification")
536             # Turn *[] argument into **
537             if type.is_array:
538                 type = PyrexTypes.c_ptr_type(type.base_type)
539             # Catch attempted C-style func(void) decl
540             if type.is_void:
541                 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
542 #            if type.is_pyobject and self.nogil:
543 #                error(self.pos,
544 #                    "Function with Python argument cannot be declared nogil")
545             func_type_args.append(
546                 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
547             if arg_node.default:
548                 self.optional_arg_count += 1
549             elif self.optional_arg_count:
550                 error(self.pos, "Non-default argument follows default argument")
551         
552         if self.optional_arg_count:
553             scope = StructOrUnionScope()
554             scope.declare_var('%sn' % Naming.pyrex_prefix, PyrexTypes.c_int_type, self.pos)
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(py23_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                 error(self.pos, "%s already a builtin Cython type" % self.class_name)
2683                 return
2684
2685         self.entry = home_scope.declare_c_class(
2686             name = self.class_name, 
2687             pos = self.pos,
2688             defining = has_body and self.in_pxd,
2689             implementing = has_body and not self.in_pxd,
2690             module_name = self.module_name,
2691             base_type = self.base_type,
2692             objstruct_cname = self.objstruct_name,
2693             typeobj_cname = self.typeobj_name,
2694             visibility = self.visibility,
2695             typedef_flag = self.typedef_flag,
2696             api = self.api,
2697             buffer_defaults = buffer_defaults)
2698         if home_scope is not env and self.visibility == 'extern':
2699             env.add_imported_entry(self.class_name, self.entry, pos)
2700         scope = self.entry.type.scope
2701
2702         if self.doc and Options.docstrings:
2703             scope.doc = embed_position(self.pos, self.doc)
2704             
2705         if has_body:
2706             self.body.analyse_declarations(scope)
2707             if self.in_pxd:
2708                 scope.defined = 1
2709             else:
2710                 scope.implemented = 1
2711         env.allocate_vtable_names(self.entry)
2712         
2713     def analyse_expressions(self, env):
2714         if self.body:
2715             scope = self.entry.type.scope
2716             self.body.analyse_expressions(scope)
2717     
2718     def generate_function_definitions(self, env, code):
2719         self.generate_py_string_decls(self.entry.type.scope, code)
2720         if self.body:
2721             self.body.generate_function_definitions(
2722                 self.entry.type.scope, code)
2723     
2724     def generate_execution_code(self, code):
2725         # This is needed to generate evaluation code for
2726         # default values of method arguments.
2727         if self.body:
2728             self.body.generate_execution_code(code)
2729             
2730     def annotate(self, code):
2731         if self.body:
2732             self.body.annotate(code)
2733
2734
2735 class PropertyNode(StatNode):
2736     #  Definition of a property in an extension type.
2737     #
2738     #  name   string
2739     #  doc    EncodedString or None    Doc string
2740     #  body   StatListNode
2741     
2742     child_attrs = ["body"]
2743
2744     def analyse_declarations(self, env):
2745         entry = env.declare_property(self.name, self.doc, self.pos)
2746         if entry:
2747             if self.doc and Options.docstrings:
2748                 doc_entry = env.get_string_const(
2749                     self.doc, identifier = False)
2750                 entry.doc_cname = doc_entry.cname
2751             self.body.analyse_declarations(entry.scope)
2752
2753     def analyse_expressions(self, env):
2754         self.body.analyse_expressions(env)
2755     
2756     def generate_function_definitions(self, env, code):
2757         self.body.generate_function_definitions(env, code)
2758
2759     def generate_execution_code(self, code):
2760         pass
2761
2762     def annotate(self, code):
2763         self.body.annotate(code)
2764
2765
2766 class GlobalNode(StatNode):
2767     # Global variable declaration.
2768     #
2769     # names    [string]
2770     
2771     child_attrs = []
2772
2773     def analyse_declarations(self, env):
2774         for name in self.names:
2775             env.declare_global(name, self.pos)
2776
2777     def analyse_expressions(self, env):
2778         pass
2779     
2780     def generate_execution_code(self, code):
2781         pass
2782
2783
2784 class ExprStatNode(StatNode):
2785     #  Expression used as a statement.
2786     #
2787     #  expr   ExprNode
2788
2789     child_attrs = ["expr"]
2790     
2791     def analyse_declarations(self, env):
2792         import ExprNodes
2793         if isinstance(self.expr, ExprNodes.GeneralCallNode):
2794             func = self.expr.function.as_cython_attribute()
2795             if func == u'declare':
2796                 args, kwds = self.expr.explicit_args_kwds()
2797                 if len(args):
2798                     error(self.expr.pos, "Variable names must be specified.")
2799                 for var, type_node in kwds.key_value_pairs:
2800                     type = type_node.analyse_as_type(env)
2801                     if type is None:
2802                         error(type_node.pos, "Unknown type")
2803                     else:
2804                         env.declare_var(var.value, type, var.pos, is_cdef = True)
2805                 self.__class__ = PassStatNode
2806     
2807     def analyse_expressions(self, env):
2808         self.expr.analyse_expressions(env)
2809         self.expr.release_temp(env)
2810     
2811     def generate_execution_code(self, code):
2812         self.expr.generate_evaluation_code(code)
2813         if not self.expr.is_temp and self.expr.result():
2814             code.putln("%s;" % self.expr.result())
2815         self.expr.generate_disposal_code(code)
2816         self.expr.free_temps(code)
2817
2818     def annotate(self, code):
2819         self.expr.annotate(code)
2820
2821
2822 class AssignmentNode(StatNode):
2823     #  Abstract base class for assignment nodes.
2824     #
2825     #  The analyse_expressions and generate_execution_code
2826     #  phases of assignments are split into two sub-phases
2827     #  each, to enable all the right hand sides of a
2828     #  parallel assignment to be evaluated before assigning
2829     #  to any of the left hand sides.
2830
2831     def analyse_expressions(self, env):
2832         self.analyse_types(env)
2833         self.allocate_rhs_temps(env)
2834         self.allocate_lhs_temps(env)
2835
2836 #       def analyse_expressions(self, env):
2837 #           self.analyse_expressions_1(env)
2838 #           self.analyse_expressions_2(env)
2839
2840     def generate_execution_code(self, code):
2841         self.generate_rhs_evaluation_code(code)
2842         self.generate_assignment_code(code)
2843         
2844
2845 class SingleAssignmentNode(AssignmentNode):
2846     #  The simplest case:
2847     #
2848     #    a = b
2849     #
2850     #  lhs      ExprNode      Left hand side
2851     #  rhs      ExprNode      Right hand side
2852     #  first    bool          Is this guaranteed the first assignment to lhs?
2853     
2854     child_attrs = ["lhs", "rhs"]
2855     first = False
2856     declaration_only = False
2857
2858     def analyse_declarations(self, env):
2859         import ExprNodes
2860         
2861         # handle declarations of the form x = cython.foo()
2862         if isinstance(self.rhs, ExprNodes.CallNode):
2863             func_name = self.rhs.function.as_cython_attribute()
2864             if func_name:
2865                 args, kwds = self.rhs.explicit_args_kwds()
2866                 
2867                 if func_name in ['declare', 'typedef']:
2868                     if len(args) > 2 or kwds is not None:
2869                         error(rhs.pos, "Can only declare one type at a time.")
2870                         return
2871                     type = args[0].analyse_as_type(env)
2872                     if type is None:
2873                         error(args[0].pos, "Unknown type")
2874                         return
2875                     lhs = self.lhs
2876                     if func_name == 'declare':
2877                         if isinstance(lhs, ExprNodes.NameNode):
2878                             vars = [(lhs.name, lhs.pos)]
2879                         elif isinstance(lhs, ExprNodes.TupleNode):
2880                             vars = [(var.name, var.pos) for var in lhs.args]
2881                         else:
2882                             error(lhs.pos, "Invalid declaration")
2883                             return
2884                         for var, pos in vars:
2885                             env.declare_var(var, type, pos, is_cdef = True)
2886                         if len(args) == 2:
2887                             # we have a value
2888                             self.rhs = args[1]
2889                         else:
2890                             self.declaration_only = True
2891                     else:
2892                         self.declaration_only = True
2893                         if not isinstance(lhs, ExprNodes.NameNode):
2894                             error(lhs.pos, "Invalid declaration.")
2895                         env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2896                     
2897                 elif func_name in ['struct', 'union']:
2898                     self.declaration_only = True
2899                     if len(args) > 0 or kwds is None:
2900                         error(rhs.pos, "Struct or union members must be given by name.")
2901                         return
2902                     members = []
2903                     for member, type_node in kwds.key_value_pairs:
2904                         type = type_node.analyse_as_type(env)
2905                         if type is None:
2906                             error(type_node.pos, "Unknown type")
2907                         else:
2908                             members.append((member.value, type, member.pos))
2909                     if len(members) < len(kwds.key_value_pairs):
2910                         return
2911                     if not isinstance(self.lhs, ExprNodes.NameNode):
2912                         error(self.lhs.pos, "Invalid declaration.")
2913                     name = self.lhs.name
2914                     scope = StructOrUnionScope(name)
2915                     env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2916                     for member, type, pos in members:
2917                         scope.declare_var(member, type, pos)
2918                     
2919         if self.declaration_only:
2920             return
2921         else:
2922             self.lhs.analyse_target_declaration(env)
2923     
2924     def analyse_types(self, env, use_temp = 0):
2925         self.rhs.analyse_types(env)
2926         self.lhs.analyse_target_types(env)
2927         self.lhs.gil_assignment_check(env)
2928         self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2929         if use_temp:
2930             self.rhs = self.rhs.coerce_to_temp(env)
2931     
2932     def allocate_rhs_temps(self, env):
2933         self.rhs.allocate_temps(env)
2934
2935     def allocate_lhs_temps(self, env):
2936         self.lhs.allocate_target_temps(env, self.rhs)
2937         #self.lhs.release_target_temp(env)
2938         #self.rhs.release_temp(env)
2939
2940     def generate_rhs_evaluation_code(self, code):
2941         self.rhs.generate_evaluation_code(code)
2942     
2943     def generate_assignment_code(self, code):
2944         self.lhs.generate_assignment_code(self.rhs, code)
2945
2946     def annotate(self, code):
2947         self.lhs.annotate(code)
2948         self.rhs.annotate(code)
2949
2950
2951 class CascadedAssignmentNode(AssignmentNode):
2952     #  An assignment with multiple left hand sides:
2953     #
2954     #    a = b = c
2955     #
2956     #  lhs_list   [ExprNode]   Left hand sides
2957     #  rhs        ExprNode     Right hand sides
2958     #
2959     #  Used internally:
2960     #
2961     #  coerced_rhs_list   [ExprNode]   RHS coerced to type of each LHS
2962     
2963     child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2964     coerced_rhs_list = None
2965
2966     def analyse_declarations(self, env):
2967         for lhs in self.lhs_list:
2968             lhs.analyse_target_declaration(env)
2969     
2970     def analyse_types(self, env, use_temp = 0):
2971         self.rhs.analyse_types(env)
2972         if use_temp:
2973             self.rhs = self.rhs.coerce_to_temp(env)
2974         else:
2975             self.rhs = self.rhs.coerce_to_simple(env)
2976         from ExprNodes import CloneNode
2977         self.coerced_rhs_list = []
2978         for lhs in self.lhs_list:
2979             lhs.analyse_target_types(env)
2980             lhs.gil_assignment_check(env)
2981             rhs = CloneNode(self.rhs)
2982             rhs = rhs.coerce_to(lhs.type, env)
2983             self.coerced_rhs_list.append(rhs)
2984
2985     def allocate_rhs_temps(self, env):
2986         self.rhs.allocate_temps(env)
2987     
2988     def allocate_lhs_temps(self, env):
2989         for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2990             rhs.allocate_temps(env)
2991             lhs.allocate_target_temps(env, rhs)
2992             #lhs.release_target_temp(env)
2993             #rhs.release_temp(env)
2994         self.rhs.release_temp(env)
2995     
2996     def generate_rhs_evaluation_code(self, code):
2997         self.rhs.generate_evaluation_code(code)
2998     
2999     def generate_assignment_code(self, code):
3000         for i in range(len(self.lhs_list)):
3001             lhs = self.lhs_list[i]
3002             rhs = self.coerced_rhs_list[i]
3003             rhs.generate_evaluation_code(code)
3004             lhs.generate_assignment_code(rhs, code)
3005             # Assignment has disposed of the cloned RHS
3006         self.rhs.generate_disposal_code(code)
3007         self.rhs.free_temps(code)
3008
3009     def annotate(self, code):
3010         for i in range(len(self.lhs_list)):
3011             lhs = self.lhs_list[i].annotate(code)
3012             rhs = self.coerced_rhs_list[i].annotate(code)
3013         self.rhs.annotate(code)
3014         
3015
3016 class ParallelAssignmentNode(AssignmentNode):
3017     #  A combined packing/unpacking assignment:
3018     #
3019     #    a, b, c =  d, e, f
3020     #
3021     #  This has been rearranged by the parser into
3022     #
3023     #    a = d ; b = e ; c = f
3024     #
3025     #  but we must evaluate all the right hand sides
3026     #  before assigning to any of the left hand sides.
3027     #
3028     #  stats     [AssignmentNode]   The constituent assignments
3029     
3030     child_attrs = ["stats"]
3031
3032     def analyse_declarations(self, env):
3033         for stat in self.stats:
3034             stat.analyse_declarations(env)
3035     
3036     def analyse_expressions(self, env):
3037         for stat in self.stats:
3038             stat.analyse_types(env, use_temp = 1)
3039             stat.allocate_rhs_temps(env)
3040         for stat in self.stats:
3041             stat.allocate_lhs_temps(env)
3042
3043 #    def analyse_expressions(self, env):
3044 #        for stat in self.stats:
3045 #            stat.analyse_expressions_1(env, use_temp = 1)
3046 #        for stat in self.stats:
3047 #            stat.analyse_expressions_2(env)
3048     
3049     def generate_execution_code(self, code):
3050         for stat in self.stats:
3051             stat.generate_rhs_evaluation_code(code)
3052         for stat in self.stats:
3053             stat.generate_assignment_code(code)
3054
3055     def annotate(self, code):
3056         for stat in self.stats:
3057             stat.annotate(code)
3058
3059
3060 class InPlaceAssignmentNode(AssignmentNode):
3061     #  An in place arithmatic operand:
3062     #
3063     #    a += b
3064     #    a -= b
3065     #    ...
3066     #
3067     #  lhs      ExprNode      Left hand side
3068     #  rhs      ExprNode      Right hand side
3069     #  op       char          one of "+-*/%^&|"
3070     #  dup     (ExprNode)     copy of lhs used for operation (auto-generated)
3071     #
3072     #  This code is a bit tricky because in order to obey Python 
3073     #  semantics the sub-expressions (e.g. indices) of the lhs must 
3074     #  not be evaluated twice. So we must re-use the values calculated 
3075     #  in evaluation phase for the assignment phase as well. 
3076     #  Fortunately, the type of the lhs node is fairly constrained 
3077     #  (it must be a NameNode, AttributeNode, or IndexNode).     
3078     
3079     child_attrs = ["lhs", "rhs"]
3080     dup = None
3081
3082     def analyse_declarations(self, env):
3083         self.lhs.analyse_target_declaration(env)
3084         
3085     def analyse_types(self, env):
3086         self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3087         self.rhs.analyse_types(env)
3088         self.lhs.analyse_target_types(env)
3089         if Options.incref_local_binop and self.dup.type.is_pyobject:
3090             self.dup = self.dup.coerce_to_temp(env)
3091         
3092     def allocate_rhs_temps(self, env):
3093         import ExprNodes
3094         if self.lhs.type.is_pyobject:
3095             self.rhs = self.rhs.coerce_to_pyobject(env)
3096         elif self.rhs.type.is_pyobject:
3097             self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3098         if self.lhs.type.is_pyobject:
3099              self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3100              self.result_value.allocate_temps(env)
3101 #        if use_temp:
3102 #            self.rhs = self.rhs.coerce_to_temp(env)
3103         self.rhs.allocate_temps(env)
3104         self.dup.allocate_subexpr_temps(env)
3105         self.dup.allocate_temp(env)
3106     
3107     def allocate_lhs_temps(self, env):
3108         self.lhs.allocate_target_temps(env, self.rhs)
3109 #        self.lhs.release_target_temp(env)
3110         self.dup.release_temp(env)
3111         if self.dup.is_temp:
3112             self.dup.release_subexpr_temps(env)
3113 #        self.rhs.release_temp(env)
3114         if self.lhs.type.is_pyobject:
3115             self.result_value.release_temp(env)
3116
3117     def generate_execution_code(self, code):
3118         import ExprNodes
3119         self.rhs.generate_evaluation_code(code)
3120         self.dup.generate_subexpr_evaluation_code(code)
3121         if isinstance(self.dup, ExprNodes.NewTempExprNode):
3122             # This is because we're manually messing with subexpr nodes
3123             if self.dup.is_temp:
3124                 self.dup.allocate_temp_result(code)
3125         # self.dup.generate_result_code is run only if it is not buffer access
3126         if self.operator == "**":
3127             extra = ", Py_None"
3128         else:
3129             extra = ""
3130         if self.lhs.type.is_pyobject:
3131             if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3132                 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3133             self.dup.generate_result_code(code)
3134             code.putln(
3135                 "%s = %s(%s, %s%s); %s" % (
3136                     self.result_value.result(), 
3137                     self.py_operation_function(), 
3138                     self.dup.py_result(),
3139                     self.rhs.py_result(),
3140                     extra,
3141                     code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3142             code.put_gotref(self.result_value.py_result())
3143             self.result_value.generate_evaluation_code(code) # May be a type check...
3144             self.rhs.generate_disposal_code(code)
3145             self.rhs.free_temps(code)
3146             self.dup.generate_disposal_code(code)
3147             self.dup.free_temps(code)
3148             self.lhs.generate_assignment_code(self.result_value, code)
3149         else: 
3150             c_op = self.operator
3151             if c_op == "//":
3152                 c_op = "/"
3153             elif c_op == "**":
3154                 if self.lhs.type.is_int and self.rhs.type.is_int:
3155                     error(self.pos, "** with two C int types is ambiguous")
3156                 else:
3157                     error(self.pos, "No C inplace power operator")
3158             # have to do assignment directly to avoid side-effects
3159             if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3160                 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3161             else:
3162                 self.dup.generate_result_code(code)
3163                 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3164             self.rhs.generate_disposal_code(code)
3165             self.rhs.free_temps(code)
3166         if self.dup.is_temp:
3167             self.dup.generate_subexpr_disposal_code(code)
3168             self.dup.free_subexpr_temps(code)
3169             
3170     def create_dup_node(self, env): 
3171         import ExprNodes
3172         self.dup = self.lhs
3173         self.dup.analyse_types(env)
3174         if isinstance(self.lhs, ExprNodes.NameNode):
3175             target_lhs = ExprNodes.NameNode(self.dup.pos,
3176                                             name = self.dup.name,
3177                                             is_temp = self.dup.is_temp,
3178                                             entry = self.dup.entry)
3179         elif isinstance(self.lhs, ExprNodes.AttributeNode):
3180             target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3181                                                  obj = ExprNodes.CloneNode(self.lhs.obj),
3182                                                  attribute = self.dup.attribute,
3183                                                  is_temp = self.dup.is_temp)
3184         elif isinstance(self.lhs, ExprNodes.IndexNode):
3185             if self.lhs.index:
3186                 index = ExprNodes.CloneNode(self.lhs.index)
3187             else:
3188                 index = None
3189             if self.lhs.indices:
3190                 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3191             else:
3192                 indices = []
3193             target_lhs = ExprNodes.IndexNode(self.dup.pos,
3194                                              base = ExprNodes.CloneNode(self.dup.base),
3195                                              index = index,
3196                                              indices = indices,
3197                                              is_temp = self.dup.is_temp)
3198         else:
3199             assert False
3200         self.lhs = target_lhs
3201         return self.dup
3202     
3203     def py_operation_function(self):
3204         return self.py_functions[self.operator]
3205
3206     py_functions = {
3207         "|":        "PyNumber_InPlaceOr",
3208         "^":        "PyNumber_InPlaceXor",
3209         "&":        "PyNumber_InPlaceAnd",
3210         "+":        "PyNumber_InPlaceAdd",
3211         "-":        "PyNumber_InPlaceSubtract",
3212         "*":        "PyNumber_InPlaceMultiply",
3213         "/":        "PyNumber_InPlaceDivide",
3214         "%":        "PyNumber_InPlaceRemainder",
3215         "<<":        "PyNumber_InPlaceLshift",
3216         ">>":        "PyNumber_InPlaceRshift",
3217         "**":        "PyNumber_InPlacePower",
3218         "//":        "PyNumber_InPlaceFloorDivide",
3219     }
3220
3221     def annotate(self, code):
3222         self.lhs.annotate(code)
3223         self.rhs.annotate(code)
3224         self.dup.annotate(code)
3225
3226
3227 class PrintStatNode(StatNode):
3228     #  print statement
3229     #
3230     #  arg_tuple         TupleNode
3231     #  append_newline    boolean
3232
3233     child_attrs = ["arg_tuple"]
3234
3235     def analyse_expressions(self, env):
3236         self.arg_tuple.analyse_expressions(env)
3237         self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3238         self.arg_tuple.release_temp(env)
3239         env.use_utility_code(printing_utility_code)
3240         if len(self.arg_tuple.args) == 1 and self.append_newline:
3241             env.use_utility_code(printing_one_utility_code)
3242         self.gil_check(env)
3243
3244     gil_message = "Python print statement"
3245
3246     def generate_execution_code(self, code):
3247         if len(self.arg_tuple.args) == 1 and self.append_newline:
3248             arg = self.arg_tuple.args[0]
3249             arg.generate_evaluation_code(code)
3250             
3251             code.putln(
3252                 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3253                     arg.py_result(),
3254                     code.error_goto(self.pos)))
3255             arg.generate_disposal_code(code)
3256             arg.free_temps(code)
3257         else:
3258             self.arg_tuple.generate_evaluation_code(code)
3259             code.putln(
3260                 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3261                     self.arg_tuple.py_result(),
3262                     self.append_newline,
3263                     code.error_goto(self.pos)))
3264             self.arg_tuple.generate_disposal_code(code)
3265             self.arg_tuple.free_temps(code)
3266
3267     def annotate(self, code):
3268         self.arg_tuple.annotate(code)
3269
3270
3271 class ExecStatNode(StatNode):
3272     #  exec statement
3273     #
3274     #  args     [ExprNode]
3275
3276     child_attrs = ["args"]
3277
3278     def analyse_expressions(self, env):
3279         for i, arg in enumerate(self.args):
3280             arg.analyse_expressions(env)
3281             arg = arg.coerce_to_pyobject(env)
3282             arg.release_temp(env)
3283             self.args[i] = arg
3284         self.temp_result = env.allocate_temp_pyobject()
3285         env.release_temp(self.temp_result)
3286         env.use_utility_code(Builtin.pyexec_utility_code)
3287         self.gil_check(env)
3288
3289     gil_message = "Python exec statement"
3290
3291     def generate_execution_code(self, code):
3292         args = []
3293         for arg in self.args:
3294             arg.generate_evaluation_code(code)
3295             args.append( arg.py_result() )
3296         args = tuple(args + ['0', '0'][:3-len(args)])
3297         code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3298                 (self.temp_result,) + args))
3299         for arg in self.args:
3300             arg.generate_disposal_code(code)
3301             arg.free_temps(code)
3302         code.putln(
3303             code.error_goto_if_null(self.temp_result, self.pos))
3304         code.put_gotref(self.temp_result)
3305         code.put_decref_clear(self.temp_result, py_object_type)
3306
3307     def annotate(self, code):
3308         for arg in self.args:
3309             arg.annotate(code)
3310
3311
3312 class DelStatNode(StatNode):
3313     #  del statement
3314     #
3315     #  args     [ExprNode]
3316     
3317     child_attrs = ["args"]
3318
3319     def analyse_declarations(self, env):
3320         for arg in self.args:
3321             arg.analyse_target_declaration(env)
3322     
3323     def analyse_expressions(self, env):
3324         for arg in self.args:
3325             arg.analyse_target_expression(env, None)
3326             if arg.type.is_pyobject:
3327                 self.gil_check(env)
3328             else:
3329                 error(arg.pos, "Deletion of non-Python object")
3330             #arg.release_target_temp(env)
3331
3332     gil_message = "Deleting Python object"
3333
3334     def generate_execution_code(self, code):
3335         for arg in self.args:
3336             if arg.type.is_pyobject:
3337                 arg.generate_deletion_code(code)
3338             # else error reported earlier
3339
3340     def annotate(self, code):
3341         for arg in self.args:
3342             arg.annotate(code)
3343
3344
3345 class PassStatNode(StatNode):
3346     #  pass statement
3347
3348     child_attrs = []
3349     
3350     def analyse_expressions(self, env):
3351         pass
3352     
3353     def generate_execution_code(self, code):
3354         pass
3355
3356
3357 class BreakStatNode(StatNode):
3358
3359     child_attrs = []
3360
3361     def analyse_expressions(self, env):
3362         pass
3363     
3364     def generate_execution_code(self, code):
3365         if not code.break_label:
3366             error(self.pos, "break statement not inside loop")
3367         else:
3368             code.put_goto(code.break_label)
3369
3370
3371 class ContinueStatNode(StatNode):
3372
3373     child_attrs = []
3374
3375     def analyse_expressions(self, env):
3376         pass
3377     
3378     def generate_execution_code(self, code):
3379         if code.funcstate.in_try_finally:
3380             error(self.pos, "continue statement inside try of try...finally")
3381         elif not code.continue_label:
3382             error(self.pos, "continue statement not inside loop")
3383         else:
3384             code.put_goto(code.continue_label)
3385
3386
3387 class ReturnStatNode(StatNode):
3388     #  return statement
3389     #
3390     #  value         ExprNode or None
3391     #  return_type   PyrexType
3392     #  temps_in_use  [Entry]            Temps in use at time of return
3393     
3394     child_attrs = ["value"]
3395
3396     def analyse_expressions(self, env):
3397         return_type = env.return_type
3398         self.return_type = return_type
3399         self.temps_in_use = env.temps_in_use()
3400         if not return_type:
3401             error(self.pos, "Return not inside a function body")
3402             return
3403         if self.value:
3404             self.value.analyse_types(env)
3405             if return_type.is_void or return_type.is_returncode:
3406                 error(self.value.pos, 
3407                     "Return with value in void function")
3408             else:
3409                 self.value = self.value.coerce_to(env.return_type, env)
3410             self.value.allocate_temps(env)
3411             self.value.release_temp(env)
3412         else:
3413             if (not return_type.is_void
3414                 and not return_type.is_pyobject
3415                 and not return_type.is_returncode):
3416                     error(self.pos, "Return value required")
3417         if return_type.is_pyobject:
3418             self.gil_check(env)
3419
3420     gil_message = "Returning Python object"
3421
3422     def generate_execution_code(self, code):
3423         code.mark_pos(self.pos)
3424         if not self.return_type:
3425             # error reported earlier
3426             return
3427         if self.return_type.is_pyobject:
3428             code.put_xdecref(Naming.retval_cname,
3429                              self.return_type)
3430         if self.value:
3431             self.value.generate_evaluation_code(code)
3432             self.value.make_owned_reference(code)
3433             code.putln(
3434                 "%s = %s;" % (
3435                     Naming.retval_cname,
3436                     self.value.result_as(self.return_type)))
3437             self.value.generate_post_assignment_code(code)
3438             self.value.free_temps(code)
3439         else:
3440             if self.return_type.is_pyobject:
3441                 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3442             elif self.return_type.is_returncode:
3443                 code.putln(
3444                     "%s = %s;" % (
3445                         Naming.retval_cname,
3446                         self.return_type.default_value))
3447         # free temps the old way
3448         for entry in self.temps_in_use:
3449             code.put_var_decref_clear(entry)
3450         # free temps the new way
3451         for cname, type in code.funcstate.temps_holding_reference():
3452             code.put_decref_clear(cname, type)
3453         #code.putln(
3454         #    "goto %s;" %
3455         #        code.return_label)
3456         code.put_goto(code.return_label)
3457         
3458     def annotate(self, code):
3459         if self.value:
3460             self.value.annotate(code)
3461
3462
3463 class RaiseStatNode(StatNode):
3464     #  raise statement
3465     #
3466     #  exc_type    ExprNode or None
3467     #  exc_value   ExprNode or None
3468     #  exc_tb      ExprNode or None
3469     
3470     child_attrs = ["exc_type", "exc_value", "exc_tb"]
3471
3472     def analyse_expressions(self, env):
3473         if self.exc_type:
3474             self.exc_type.analyse_types(env)
3475             self.exc_type = self.exc_type.coerce_to_pyobject(env)
3476             self.exc_type.allocate_temps(env)
3477         if self.exc_value:
3478             self.exc_value.analyse_types(env)
3479             self.exc_value = self.exc_value.coerce_to_pyobject(env)
3480             self.exc_value.allocate_temps(env)
3481         if self.exc_tb:
3482             self.exc_tb.analyse_types(env)
3483             self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3484             self.exc_tb.allocate_temps(env)
3485         if self.exc_type:
3486             self.exc_type.release_temp(env)
3487         if self.exc_value:
3488             self.exc_value.release_temp(env)
3489         if self.exc_tb:
3490             self.exc_tb.release_temp(env)
3491         env.use_utility_code(raise_utility_code)
3492         env.use_utility_code(restore_exception_utility_code)
3493         self.gil_check(env)
3494
3495     gil_message = "Raising exception"
3496
3497     def generate_execution_code(self, code):
3498         if self.exc_type:
3499             self.exc_type.generate_evaluation_code(code)
3500             type_code = self.exc_type.py_result()
3501         else:
3502             type_code = "0"
3503         if self.exc_value:
3504             self.exc_value.generate_evaluation_code(code)
3505             value_code = self.exc_value.py_result()
3506         else:
3507             value_code = "0"
3508         if self.exc_tb:
3509             self.exc_tb.generate_evaluation_code(code)
3510             tb_code = self.exc_tb.py_result()
3511         else:
3512             tb_code = "0"
3513         if self.exc_type or self.exc_value or self.exc_tb:
3514             code.putln(
3515                 "__Pyx_Raise(%s, %s, %s);" % (
3516                     type_code,
3517                     value_code,
3518                     tb_code))
3519         else:
3520             code.putln(
3521                 "__Pyx_ReRaise();")
3522         for obj in (self.exc_type, self.exc_value, self.exc_tb):
3523             if obj:
3524                 obj.generate_disposal_code(code)
3525                 obj.free_temps(code)
3526         code.putln(
3527             code.error_goto(self.pos))
3528
3529     def annotate(self, code):
3530         if self.exc_type:
3531             self.exc_type.annotate(code)
3532         if self.exc_value:
3533             self.exc_value.annotate(code)
3534         if self.exc_tb:
3535             self.exc_tb.annotate(code)
3536
3537
3538 class ReraiseStatNode(StatNode):
3539
3540     child_attrs = []
3541
3542     def analyse_expressions(self, env):
3543         self.gil_check(env)
3544         env.use_utility_code(raise_utility_code)
3545         env.use_utility_code(restore_exception_utility_code)
3546
3547     gil_message = "Raising exception"
3548
3549     def generate_execution_code(self, code):
3550         vars = code.funcstate.exc_vars
3551         if vars:
3552             code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3553             code.putln(code.error_goto(self.pos))
3554         else:
3555             error(self.pos, "Reraise not inside except clause")
3556         
3557
3558 class AssertStatNode(StatNode):
3559     #  assert statement
3560     #
3561     #  cond    ExprNode
3562     #  value   ExprNode or None
3563     
3564     child_attrs = ["cond", "value"]
3565
3566     def analyse_expressions(self, env):
3567         self.cond = self.cond.analyse_boolean_expression(env)
3568         if self.value:
3569             self.value.analyse_types(env)
3570             self.value = self.value.coerce_to_pyobject(env)
3571             self.value.allocate_temps(env)
3572         self.cond.release_temp(env)
3573         if self.value:
3574             self.value.release_temp(env)
3575         self.gil_check(env)
3576         #env.recycle_pending_temps() # TEMPORARY
3577
3578     gil_message = "Raising exception"
3579     
3580     def generate_execution_code(self, code):
3581         code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3582         self.cond.generate_evaluation_code(code)
3583         code.putln(
3584             "if (unlikely(!%s)) {" %
3585                 self.cond.result())
3586         if self.value:
3587             self.value.generate_evaluation_code(code)
3588             code.putln(
3589                 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3590                     self.value.py_result())
3591             self.value.generate_disposal_code(code)
3592             self.value.free_temps(code)
3593         else:
3594             code.putln(
3595                 "PyErr_SetNone(PyExc_AssertionError);")
3596         code.putln(
3597                 code.error_goto(self.pos))
3598         code.putln(
3599             "}")
3600         self.cond.generate_disposal_code(code)
3601         self.cond.free_temps(code)
3602         code.putln("#endif")
3603
3604     def annotate(self, code):
3605         self.cond.annotate(code)
3606         if self.value:
3607             self.value.annotate(code)
3608
3609
3610 class IfStatNode(StatNode):
3611     #  if statement
3612     #
3613     #  if_clauses   [IfClauseNode]
3614     #  else_clause  StatNode or None
3615
3616     child_attrs = ["if_clauses", "else_clause"]
3617     
3618     def analyse_control_flow(self, env):
3619         env.start_branching(self.pos)
3620         for if_clause in self.if_clauses:
3621             if_clause.analyse_control_flow(env)
3622             env.next_branch(if_clause.end_pos())
3623         if self.else_clause:
3624             self.else_clause.analyse_control_flow(env)
3625         env.finish_branching(self.end_pos())
3626
3627     def analyse_declarations(self, env):
3628         for if_clause in self.if_clauses:
3629             if_clause.analyse_declarations(env)
3630         if self.else_clause:
3631             self.else_clause.analyse_declarations(env)
3632     
3633     def analyse_expressions(self, env):
3634         for if_clause in self.if_clauses:
3635             if_clause.analyse_expressions(env)
3636         if self.else_clause:
3637             self.else_clause.analyse_expressions(env)
3638     
3639     def generate_execution_code(self, code):
3640         code.mark_pos(self.pos)
3641         end_label = code.new_label()
3642         for if_clause in self.if_clauses:
3643             if_clause.generate_execution_code(code, end_label)
3644         if self.else_clause:
3645             code.putln("/*else*/ {")
3646             self.else_clause.generate_execution_code(code)
3647             code.putln("}")
3648         code.put_label(end_label)
3649         
3650     def annotate(self, code):
3651         for if_clause in self.if_clauses:
3652             if_clause.annotate(code)
3653         if self.else_clause:
3654             self.else_clause.annotate(code)
3655
3656
3657 class IfClauseNode(Node):
3658     #  if or elif clause in an if statement
3659     #
3660     #  condition   ExprNode
3661     #  body        StatNode
3662     
3663     child_attrs = ["condition", "body"]
3664
3665     def analyse_control_flow(self, env):
3666         self.body.analyse_control_flow(env)
3667         
3668     def analyse_declarations(self, env):
3669         self.condition.analyse_declarations(env)
3670         self.body.analyse_declarations(env)
3671     
3672     def analyse_expressions(self, env):
3673         self.condition = \
3674             self.condition.analyse_temp_boolean_expression(env)
3675         self.condition.release_temp(env)
3676         self.body.analyse_expressions(env)
3677     
3678     def generate_execution_code(self, code, end_label):
3679         self.condition.generate_evaluation_code(code)
3680         code.putln(
3681             "if (%s) {" %
3682                 self.condition.result())
3683         self.condition.generate_disposal_code(code)
3684         self.condition.free_temps(code)
3685         self.body.generate_execution_code(code)
3686         #code.putln(
3687         #    "goto %s;" %
3688         #        end_label)
3689         code.put_goto(end_label)
3690         code.putln("}")
3691
3692     def annotate(self, code):
3693         self.condition.annotate(code)
3694         self.body.annotate(code)
3695         
3696
3697 class SwitchCaseNode(StatNode):
3698     # Generated in the optimization of an if-elif-else node
3699     #
3700     # conditions    [ExprNode]
3701     # body          StatNode
3702     
3703     child_attrs = ['conditions', 'body']
3704     
3705     def generate_execution_code(self, code):
3706         for cond in self.conditions:
3707             code.mark_pos(cond.pos)
3708             code.putln("case %s:" % cond.calculate_result_code())
3709         self.body.generate_execution_code(code)
3710         code.putln("break;")
3711         
3712     def annotate(self, code):
3713         for cond in self.conditions:
3714             cond.annotate(code)
3715         self.body.annotate(code)
3716
3717 class SwitchStatNode(StatNode):
3718     # Generated in the optimization of an if-elif-else node
3719     #
3720     # test          ExprNode
3721     # cases         [SwitchCaseNode]
3722     # else_clause   StatNode or None
3723     
3724     child_attrs = ['test', 'cases', 'else_clause']
3725     
3726     def generate_execution_code(self, code):
3727         code.putln("switch (%s) {" % self.test.calculate_result_code())
3728         for case in self.cases:
3729             case.generate_execution_code(code)
3730         if self.else_clause is not None:
3731             code.putln("default:")
3732             self.else_clause.generate_execution_code(code)
3733             code.putln("break;")
3734         code.putln("}")
3735
3736     def annotate(self, code):
3737         self.test.annotate(code)
3738         for case in self.cases:
3739             case.annotate(code)
3740         if self.else_clause is not None:
3741             self.else_clause.annotate(code)
3742             
3743 class LoopNode(object):
3744     
3745     def analyse_control_flow(self, env):
3746         env.start_branching(self.pos)
3747         self.body.analyse_control_flow(env)
3748         env.next_branch(self.body.end_pos())
3749         if self.else_clause:
3750             self.else_clause.analyse_control_flow(env)
3751         env.finish_branching(self.end_pos())
3752
3753     
3754 class WhileStatNode(LoopNode, StatNode):
3755     #  while statement
3756     #
3757     #  condition    ExprNode
3758     #  body         StatNode
3759     #  else_clause  StatNode
3760
3761     child_attrs = ["condition", "body", "else_clause"]
3762
3763     def analyse_declarations(self, env):
3764         self.body.analyse_declarations(env)
3765         if self.else_clause:
3766             self.else_clause.analyse_declarations(env)
3767     
3768     def analyse_expressions(self, env):
3769         self.condition = \
3770             self.condition.analyse_temp_boolean_expression(env)
3771         self.condition.release_temp(env)
3772         #env.recycle_pending_temps() # TEMPORARY
3773         self.body.analyse_expressions(env)
3774         if self.else_clause:
3775             self.else_clause.analyse_expressions(env)
3776     
3777     def generate_execution_code(self, code):
3778         old_loop_labels = code.new_loop_labels()
3779         code.putln(
3780             "while (1) {")
3781         self.condition.generate_evaluation_code(code)
3782         self.condition.generate_disposal_code(code)
3783         code.putln(
3784             "if (!%s) break;" %
3785                 self.condition.result())
3786         self.condition.free_temps(code)
3787         self.body.generate_execution_code(code)
3788         code.put_label(code.continue_label)
3789         code.putln("}")
3790         break_label = code.break_label
3791         code.set_loop_labels(old_loop_labels)
3792         if self.else_clause:
3793             code.putln("/*else*/ {")
3794             self.else_clause.generate_execution_code(code)
3795             code.putln("}")
3796         code.put_label(break_label)
3797
3798     def annotate(self, code):
3799         self.condition.annotate(code)
3800         self.body.annotate(code)
3801         if self.else_clause:
3802             self.else_clause.annotate(code)
3803
3804
3805 def ForStatNode(pos, **kw):
3806     if 'iterator' in kw:
3807         return ForInStatNode(pos, **kw)
3808     else:
3809         return ForFromStatNode(pos, **kw)
3810
3811 class ForInStatNode(LoopNode, StatNode):
3812     #  for statement
3813     #
3814     #  target        ExprNode
3815     #  iterator      IteratorNode
3816     #  body          StatNode
3817     #  else_clause   StatNode
3818     #  item          NextNode       used internally
3819     
3820     child_attrs = ["target", "iterator", "body", "else_clause"]
3821     item = None
3822     
3823     def analyse_declarations(self, env):
3824         self.target.analyse_target_declaration(env)
3825         self.body.analyse_declarations(env)
3826         if self.else_clause:
3827             self.else_clause.analyse_declarations(env)
3828
3829     def analyse_expressions(self, env):
3830         import ExprNodes
3831         self.target.analyse_target_types(env)
3832         self.iterator.analyse_expressions(env)
3833         self.item = ExprNodes.NextNode(self.iterator, env)
3834         self.item = self.item.coerce_to(self.target.type, env)
3835         self.item.allocate_temps(env)
3836         self.target.allocate_target_temps(env, self.item)
3837         #self.item.release_temp(env)
3838         #self.target.release_target_temp(env)
3839         self.body.analyse_expressions(env)
3840         if self.else_clause:
3841             self.else_clause.analyse_expressions(env)
3842         self.iterator.release_temp(env)
3843
3844     def generate_execution_code(self, code):
3845         old_loop_labels = code.new_loop_labels()
3846         self.iterator.allocate_counter_temp(code)
3847         self.iterator.generate_evaluation_code(code)
3848         code.putln(
3849             "for (;;) {")
3850         self.item.generate_evaluation_code(code)
3851         self.target.generate_assignment_code(self.item, code)
3852         self.body.generate_execution_code(code)
3853         code.put_label(code.continue_label)
3854         code.putln(
3855             "}")
3856         break_label = code.break_label
3857         code.set_loop_labels(old_loop_labels)
3858         if self.else_clause:
3859             code.putln("/*else*/ {")
3860             self.else_clause.generate_execution_code(code)
3861             code.putln("}")
3862         code.put_label(break_label)
3863         self.iterator.release_counter_temp(code)
3864         self.iterator.generate_disposal_code(code)
3865         self.iterator.free_temps(code)
3866
3867     def annotate(self, code):
3868         self.target.annotate(code)
3869         self.iterator.annotate(code)
3870         self.body.annotate(code)
3871         if self.else_clause:
3872             self.else_clause.annotate(code)
3873         self.item.annotate(code)
3874
3875
3876 class ForFromStatNode(LoopNode, StatNode):
3877     #  for name from expr rel name rel expr
3878     #
3879     #  target        NameNode
3880     #  bound1        ExprNode
3881     #  relation1     string
3882     #  relation2     string
3883     #  bound2        ExprNode
3884     #  step          ExprNode or None
3885     #  body          StatNode
3886     #  else_clause   StatNode or None
3887     #
3888     #  Used internally:
3889     #
3890     #  is_py_target       bool
3891     #  loopvar_node       ExprNode (usually a NameNode or temp node)
3892     #  py_loopvar_node    PyTempNode or None
3893     child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3894
3895     is_py_target = False
3896     loopvar_node = None
3897     py_loopvar_node = None
3898
3899     def analyse_declarations(self, env):
3900         self.target.analyse_target_declaration(env)
3901         self.body.analyse_declarations(env)
3902         if self.else_clause:
3903             self.else_clause.analyse_declarations(env)
3904
3905     def analyse_expressions(self, env):
3906         import ExprNodes
3907         self.target.analyse_target_types(env)
3908         self.bound1.analyse_types(env)
3909         self.bound2.analyse_types(env)
3910         if self.target.type.is_numeric:
3911             self.bound1 = self.bound1.coerce_to(self.target.type, env)
3912             self.bound2 = self.bound2.coerce_to(self.target.type, env)
3913         else:
3914             self.bound1 = self.bound1.coerce_to_integer(env)
3915             self.bound2 = self.bound2.coerce_to_integer(env)
3916         if self.step is not None:
3917             if isinstance(self.step, ExprNodes.UnaryMinusNode):
3918                 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3919             self.step.analyse_types(env)
3920             self.step = self.step.coerce_to_integer(env)
3921         if not (self.bound2.is_name or self.bound2.is_literal):
3922             self.bound2 = self.bound2.coerce_to_temp(env)
3923         target_type = self.target.type
3924         if not (target_type.is_pyobject or target_type.is_numeric):
3925             error(self.target.pos,
3926                 "Integer for-loop variable must be of type int or Python object")
3927         #if not (target_type.is_pyobject
3928         #    or target_type.assignable_from(PyrexTypes.c_int_type)):
3929         #        error(self.target.pos,
3930         #            "Cannot assign integer to variable of type '%s'" % target_type)
3931         if target_type.is_numeric:
3932             self.is_py_target = 0
3933             if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3934                 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3935             self.loopvar_node = self.target
3936             self.py_loopvar_node = None
3937         else:
3938             self.is_py_target = 1
3939             c_loopvar_node = ExprNodes.TempNode(self.pos, 
3940                 PyrexTypes.c_long_type, env)
3941             c_loopvar_node.allocate_temps(env)
3942             self.loopvar_node = c_loopvar_node
3943             self.py_loopvar_node = \
3944                 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3945         self.bound1.allocate_temps(env)
3946         self.bound2.allocate_temps(env)
3947         if self.step is not None:
3948             self.step.allocate_temps(env)
3949         if self.is_py_target:
3950             self.py_loopvar_node.allocate_temps(env)
3951             self.target.allocate_target_temps(env, self.py_loopvar_node)
3952             #self.target.release_target_temp(env)
3953             #self.py_loopvar_node.release_temp(env)
3954         self.body.analyse_expressions(env)
3955         if self.is_py_target:
3956             c_loopvar_node.release_temp(env)
3957         if self.else_clause:
3958             self.else_clause.analyse_expressions(env)
3959         self.bound1.release_temp(env)
3960         self.bound2.release_temp(env)
3961         if self.step is not None:
3962             self.step.release_temp(env)
3963             
3964     def generate_execution_code(self, code):
3965         old_loop_labels = code.new_loop_labels()
3966         from_range = getattr(self, "from_range", False)
3967         self.bound1.generate_evaluation_code(code)
3968         self.bound2.generate_evaluation_code(code)
3969         offset, incop = self.relation_table[self.relation1]
3970         if incop == "++":
3971             decop = "--"
3972         else:
3973             decop = "++"
3974         if self.step is not None:
3975             self.step.generate_evaluation_code(code)
3976             step = self.step.result()
3977             incop = "%s=%s" % (incop[0], step)
3978             decop = "%s=%s" % (decop[0], step)
3979         loopvar_name = self.loopvar_node.result()
3980         if from_range:
3981             # Skip the loop entirely (and avoid assigning to the loopvar) if
3982             # the loop is empty:
3983             code.putln("if (%s%s %s %s) {" % (
3984             self.bound1.result(), offset, self.relation2, self.bound2.result()
3985             ))
3986         code.putln(
3987             "for (%s = %s%s; %s %s %s; %s%s) {" % (
3988                 loopvar_name,
3989                 self.bound1.result(), offset,
3990                 loopvar_name, self.relation2, self.bound2.result(),
3991                 loopvar_name, incop))
3992         if self.py_loopvar_node:
3993             self.py_loopvar_node.generate_evaluation_code(code)
3994             self.target.generate_assignment_code(self.py_loopvar_node, code)
3995         self.body.generate_execution_code(code)
3996         code.put_label(code.continue_label)
3997         if from_range:
3998             # Undo last increment to maintain Python semantics:
3999             code.putln("} %s%s;" % (loopvar_name, decop))
4000             # End the outer if statement:
4001             code.putln("} /* end if */")
4002         else:
4003             code.putln("}")
4004         break_label = code.break_label
4005         code.set_loop_labels(old_loop_labels)
4006         if self.else_clause:
4007             code.putln("/*else*/ {")
4008             self.else_clause.generate_execution_code(code)
4009             code.putln("}")
4010         code.put_label(break_label)
4011         self.bound1.generate_disposal_code(code)
4012         self.bound1.free_temps(code)
4013         self.bound2.generate_disposal_code(code)
4014         self.bound2.free_temps(code)
4015         if self.step is not None:
4016             self.step.generate_disposal_code(code)
4017             self.step.free_temps(code)
4018     
4019     relation_table = {
4020         # {relop : (initial offset, increment op)}
4021         '<=': ("",   "++"),
4022         '<' : ("+1", "++"),
4023         '>=': ("",   "--"),
4024         '>' : ("-1", "--")
4025     }
4026     
4027     def annotate(self, code):
4028         self.target.annotate(code)
4029         self.bound1.annotate(code)
4030         self.bound2.annotate(code)
4031         if self.step:
4032             self.bound2.annotate(code)
4033         self.body.annotate(code)
4034         if self.else_clause:
4035             self.else_clause.annotate(code)
4036
4037
4038 class WithStatNode(StatNode):
4039     """
4040     Represents a Python with statement.
4041     
4042     This is only used at parse tree level; and is not present in
4043     analysis or generation phases.
4044     """
4045     #  manager          The with statement manager object
4046     #  target            Node (lhs expression)
4047     #  body             StatNode
4048     child_attrs = ["manager", "target", "body"]
4049
4050 class TryExceptStatNode(StatNode):
4051     #  try .. except statement
4052     #
4053     #  body             StatNode
4054     #  except_clauses   [ExceptClauseNode]
4055     #  else_clause      StatNode or None
4056     #  cleanup_list     [Entry]            old style temps to clean up on error
4057
4058     child_attrs = ["body", "except_clauses", "else_clause"]
4059     
4060     def analyse_control_flow(self, env):
4061         env.start_branching(self.pos)
4062         self.body.analyse_control_flow(env)
4063         successful_try = env.control_flow # grab this for later
4064         env.next_branch(self.body.end_pos())
4065         env.finish_branching(self.body.end_pos())
4066         
4067         env.start_branching(self.except_clauses[0].pos)
4068         for except_clause in self.except_clauses:
4069             except_clause.analyse_control_flow(env)
4070             env.next_branch(except_clause.end_pos())
4071             
4072         # the else cause it executed only when the try clause finishes
4073         env.control_flow.incoming = successful_try
4074         if self.else_clause:
4075             self.else_clause.analyse_control_flow(env)
4076         env.finish_branching(self.end_pos())
4077
4078     def analyse_declarations(self, env):
4079         self.body.analyse_declarations(env)
4080         for except_clause in self.except_clauses:
4081             except_clause.analyse_declarations(env)
4082         if self.else_clause:
4083             self.else_clause.analyse_declarations(env)
4084         self.gil_check(env)
4085         env.use_utility_code(reset_exception_utility_code)
4086     
4087     def analyse_expressions(self, env):
4088         self.body.analyse_expressions(env)
4089         self.cleanup_list = env.free_temp_entries[:]
4090         default_clause_seen = 0
4091         for except_clause in self.except_clauses:
4092             except_clause.analyse_expressions(env)
4093             if default_clause_seen:
4094                 error(except_clause.pos, "default 'except:' must be last")
4095             if not except_clause.pattern:
4096                 default_clause_seen = 1
4097         self.has_default_clause = default_clause_seen
4098         if self.else_clause:
4099             self.else_clause.analyse_expressions(env)
4100         self.gil_check(env)
4101
4102     gil_message = "Try-except statement"
4103
4104     def generate_execution_code(self, code):
4105         old_return_label = code.return_label
4106         old_break_label = code.break_label
4107         old_continue_label = code.continue_label
4108         old_error_label = code.new_error_label()
4109         our_error_label = code.error_label
4110         except_end_label = code.new_label('exception_handled')
4111         except_error_label = code.new_label('except_error')
4112         except_return_label = code.new_label('except_return')
4113         try_return_label = code.new_label('try_return')
4114         try_break_label = code.new_label('try_break')
4115         try_continue_label = code.new_label('try_continue')
4116         try_end_label = code.new_label('try_end')
4117
4118         code.putln("{")
4119         code.putln("PyObject %s;" %
4120                    ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4121         code.putln("__Pyx_ExceptionSave(%s);" %
4122                    ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4123         for var in Naming.exc_save_vars:
4124             code.put_xgotref(var)
4125         code.putln(
4126             "/*try:*/ {")
4127         code.return_label = try_return_label
4128         code.break_label = try_break_label
4129         code.continue_label = try_continue_label
4130         self.body.generate_execution_code(code)
4131         code.putln(
4132             "}")
4133         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4134         code.error_label = except_error_label
4135         code.return_label = except_return_label
4136         if self.else_clause:
4137             code.putln(
4138                 "/*else:*/ {")
4139             self.else_clause.generate_execution_code(code)
4140             code.putln(
4141                 "}")
4142         for var in Naming.exc_save_vars:
4143             code.put_xdecref_clear(var, py_object_type)
4144         code.put_goto(try_end_label)
4145         if code.label_used(try_return_label):
4146             code.put_label(try_return_label)
4147             for var in Naming.exc_save_vars:
4148                 code.put_xdecref_clear(var, py_object_type)
4149             code.put_goto(old_return_label)
4150         code.put_label(our_error_label)
4151         code.put_var_xdecrefs_clear(self.cleanup_list)
4152         for temp_name, type in temps_to_clean_up:
4153             code.put_xdecref_clear(temp_name, type)
4154         for except_clause in self.except_clauses:
4155             except_clause.generate_handling_code(code, except_end_label)
4156
4157         error_label_used = code.label_used(except_error_label)
4158         if error_label_used or not self.has_default_clause:
4159             if error_label_used:
4160                 code.put_label(except_error_label)
4161             for var in Naming.exc_save_vars:
4162                 code.put_xdecref(var, py_object_type)
4163             code.put_goto(old_error_label)
4164             
4165         if code.label_used(try_break_label):
4166             code.put_label(try_break_label)
4167             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4168             code.putln("__Pyx_ExceptionReset(%s);" %
4169                        ', '.join(Naming.exc_save_vars))
4170             code.put_goto(old_break_label)
4171             
4172         if code.label_used(try_continue_label):
4173             code.put_label(try_continue_label)
4174             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4175             code.putln("__Pyx_ExceptionReset(%s);" %
4176                        ', '.join(Naming.exc_save_vars))
4177             code.put_goto(old_continue_label)
4178
4179         if code.label_used(except_return_label):
4180             code.put_label(except_return_label)
4181             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4182             code.putln("__Pyx_ExceptionReset(%s);" %
4183                        ', '.join(Naming.exc_save_vars))
4184             code.put_goto(old_return_label)
4185
4186         if code.label_used(except_end_label):
4187             code.put_label(except_end_label)
4188             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4189             code.putln("__Pyx_ExceptionReset(%s);" %
4190                        ', '.join(Naming.exc_save_vars))
4191         code.put_label(try_end_label)
4192         code.putln("}")
4193
4194         code.return_label = old_return_label
4195         code.break_label = old_break_label
4196         code.continue_label = old_continue_label
4197         code.error_label = old_error_label
4198
4199     def annotate(self, code):
4200         self.body.annotate(code)
4201         for except_node in self.except_clauses:
4202             except_node.annotate(code)
4203         if self.else_clause:
4204             self.else_clause.annotate(code)
4205
4206
4207 class ExceptClauseNode(Node):
4208     #  Part of try ... except statement.
4209     #
4210     #  pattern        ExprNode
4211     #  target         ExprNode or None
4212     #  body           StatNode
4213     #  excinfo_target NameNode or None   optional target for exception info
4214     #  match_flag     string             result of exception match
4215     #  exc_value      ExcValueNode       used internally
4216     #  function_name  string             qualified name of enclosing function
4217     #  exc_vars       (string * 3)       local exception variables
4218
4219     # excinfo_target is never set by the parser, but can be set by a transform
4220     # in order to extract more extensive information about the exception as a
4221     # sys.exc_info()-style tuple into a target variable
4222     
4223     child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4224
4225     exc_value = None
4226     excinfo_target = None
4227
4228     def analyse_declarations(self, env):
4229         if self.target:
4230             self.target.analyse_target_declaration(env)
4231         if self.excinfo_target is not None:
4232             self.excinfo_target.analyse_target_declaration(env)
4233         self.body.analyse_declarations(env)
4234     
4235     def analyse_expressions(self, env):
4236         import ExprNodes
4237         genv = env.global_scope()
4238         self.function_name = env.qualified_name
4239         if self.pattern:
4240             self.pattern.analyse_expressions(env)
4241             self.pattern = self.pattern.coerce_to_pyobject(env)
4242             self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4243             self.pattern.release_temp(env)
4244             env.release_temp(self.match_flag)
4245         self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4246         if self.target:
4247             self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4248             self.exc_value.allocate_temps(env)
4249             self.target.analyse_target_expression(env, self.exc_value)
4250         if self.excinfo_target is not None:
4251             import ExprNodes
4252             self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4253                 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4254                 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4255                 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4256             ])
4257             self.excinfo_tuple.analyse_expressions(env)
4258             self.excinfo_tuple.allocate_temps(env)
4259             self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4260
4261         self.body.analyse_expressions(env)
4262         for var in self.exc_vars:
4263             env.release_temp(var)
4264         env.use_utility_code(get_exception_utility_code)
4265         env.use_utility_code(restore_exception_utility_code)
4266     
4267     def generate_handling_code(self, code, end_label):
4268         code.mark_pos(self.pos)
4269         if self.pattern:
4270             self.pattern.generate_evaluation_code(code)
4271             code.putln(
4272                 "%s = PyErr_ExceptionMatches(%s);" % (
4273                     self.match_flag,
4274                     self.pattern.py_result()))
4275             self.pattern.generate_disposal_code(code)
4276             self.pattern.free_temps(code)
4277             code.putln(
4278                 "if (%s) {" %
4279                     self.match_flag)
4280         else:
4281             code.putln("/*except:*/ {")
4282         code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4283         # We always have to fetch the exception value even if
4284         # there is no target, because this also normalises the 
4285         # exception and stores it in the thread state.
4286         exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
4287         code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4288             code.error_goto(self.pos)))
4289         for x in self.exc_vars:
4290             code.put_gotref(x)
4291         if self.target:
4292             self.exc_value.generate_evaluation_code(code)
4293             self.target.generate_assignment_code(self.exc_value, code)
4294         if self.excinfo_target is not None:
4295             self.excinfo_tuple.generate_evaluation_code(code)
4296             self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4297
4298
4299         old_break_label, old_continue_label = code.break_label, code.continue_label
4300         code.break_label = code.new_label('except_break')
4301         code.continue_label = code.new_label('except_continue')
4302
4303         old_exc_vars = code.funcstate.exc_vars
4304         code.funcstate.exc_vars = self.exc_vars
4305         self.body.generate_execution_code(code)
4306         code.funcstate.exc_vars = old_exc_vars
4307         for var in self.exc_vars:
4308             code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4309         code.put_goto(end_label)
4310         
4311         if code.label_used(code.break_label):
4312             code.put_label(code.break_label)
4313             for var in self.exc_vars:
4314                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4315             code.put_goto(old_break_label)
4316         code.break_label = old_break_label
4317
4318         if code.label_used(code.continue_label):
4319             code.put_label(code.continue_label)
4320             for var in self.exc_vars:
4321                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4322             code.put_goto(old_continue_label)
4323         code.continue_label = old_continue_label
4324         
4325         code.putln(
4326             "}")
4327
4328     def annotate(self, code):
4329         if self.pattern:
4330             self.pattern.annotate(code)
4331         if self.target:
4332             self.target.annotate(code)
4333         self.body.annotate(code)
4334
4335
4336 class TryFinallyStatNode(StatNode):
4337     #  try ... finally statement
4338     #
4339     #  body             StatNode
4340     #  finally_clause   StatNode
4341     #
4342     #  cleanup_list     [Entry]     old_style temps to clean up on error
4343     #
4344     #  The plan is that we funnel all continue, break
4345     #  return and error gotos into the beginning of the
4346     #  finally block, setting a variable to remember which
4347     #  one we're doing. At the end of the finally block, we
4348     #  switch on the variable to figure out where to go.
4349     #  In addition, if we're doing an error, we save the
4350     #  exception on entry to the finally block and restore
4351     #  it on exit.
4352
4353     child_attrs = ["body", "finally_clause"]
4354     
4355     preserve_exception = 1
4356     
4357     disallow_continue_in_try_finally = 0
4358     # There doesn't seem to be any point in disallowing
4359     # continue in the try block, since we have no problem
4360     # handling it.
4361
4362     def create_analysed(pos, env, body, finally_clause):
4363         node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4364         node.cleanup_list = []
4365         return node
4366     create_analysed = staticmethod(create_analysed)
4367     
4368     def analyse_control_flow(self, env):
4369         env.start_branching(self.pos)
4370         self.body.analyse_control_flow(env)
4371         env.next_branch(self.body.end_pos())
4372         env.finish_branching(self.body.end_pos())
4373         self.finally_clause.analyse_control_flow(env)
4374
4375     def analyse_declarations(self, env):
4376         self.body.analyse_declarations(env)
4377         self.finally_clause.analyse_declarations(env)
4378     
4379     def analyse_expressions(self, env):
4380         self.body.analyse_expressions(env)
4381         self.cleanup_list = env.free_temp_entries[:]
4382         self.finally_clause.analyse_expressions(env)
4383         self.gil_check(env)
4384
4385     gil_message = "Try-finally statement"
4386
4387     def generate_execution_code(self, code):
4388         old_error_label = code.error_label
4389         old_labels = code.all_new_labels()
4390         new_labels = code.get_all_labels()
4391         new_error_label = code.error_label
4392         catch_label = code.new_label()
4393         code.putln(
4394             "/*try:*/ {")
4395         if self.disallow_continue_in_try_finally:
4396             was_in_try_finally = code.funcstate.in_try_finally
4397             code.funcstate.in_try_finally = 1
4398         self.body.generate_execution_code(code)
4399         if self.disallow_continue_in_try_finally:
4400             code.funcstate.in_try_finally = was_in_try_finally
4401         code.putln(
4402             "}")
4403         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4404         code.putln(
4405             "/*finally:*/ {")
4406         cases_used = []
4407         error_label_used = 0
4408         for i, new_label in enumerate(new_labels):
4409             if new_label in code.labels_used:
4410                 cases_used.append(i)
4411                 if new_label == new_error_label:
4412                     error_label_used = 1
4413                     error_label_case = i
4414         if cases_used:
4415             code.putln(
4416                     "int __pyx_why;")
4417             if error_label_used and self.preserve_exception:
4418                 code.putln(
4419                     "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4420                 code.putln(
4421                     "int %s;" % Naming.exc_lineno_name)
4422                 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4423                 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4424                 code.putln(exc_var_init_zero)
4425             else:
4426                 exc_var_init_zero = None
4427             code.use_label(catch_label)
4428             code.putln(
4429                     "__pyx_why = 0; goto %s;" % catch_label)
4430             for i in cases_used:
4431                 new_label = new_labels[i]
4432                 #if new_label and new_label != "<try>":
4433                 if new_label == new_error_label and self.preserve_exception:
4434                     self.put_error_catcher(code, 
4435                         new_error_label, i+1, catch_label, temps_to_clean_up)
4436                 else:
4437                     code.put('%s: ' % new_label)
4438                     if exc_var_init_zero:
4439                         code.putln(exc_var_init_zero)
4440                     code.putln("__pyx_why = %s; goto %s;" % (
4441                             i+1,
4442                             catch_label))
4443             code.put_label(catch_label)
4444         code.set_all_labels(old_labels)
4445         if error_label_used:
4446             code.new_error_label()
4447             finally_error_label = code.error_label
4448         self.finally_clause.generate_execution_code(code)
4449         if error_label_used:
4450             if finally_error_label in code.labels_used and self.preserve_exception:
4451                 over_label = code.new_label()
4452                 code.put_goto(over_label);
4453                 code.put_label(finally_error_label)
4454                 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4455                 for var in Naming.exc_vars:
4456                     code.putln("Py_XDECREF(%s);" % var)
4457                 code.putln("}")
4458                 code.put_goto(old_error_label)
4459                 code.put_label(over_label)
4460             code.error_label = old_error_label
4461         if cases_used:
4462             code.putln(
4463                 "switch (__pyx_why) {")
4464             for i in cases_used:
4465                 old_label = old_labels[i]
4466                 if old_label == old_error_label and self.preserve_exception:
4467                     self.put_error_uncatcher(code, i+1, old_error_label)
4468                 else:
4469                     code.use_label(old_label)
4470                     code.putln(
4471                         "case %s: goto %s;" % (
4472                             i+1,
4473                             old_label))
4474             code.putln(
4475                 "}")
4476         code.putln(
4477             "}")
4478
4479     def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4480         code.globalstate.use_utility_code(restore_exception_utility_code)
4481         code.putln(
4482             "%s: {" %
4483                 error_label)
4484         code.putln(
4485                 "__pyx_why = %s;" %
4486                     i)
4487         code.put_var_xdecrefs_clear(self.cleanup_list)
4488         for temp_name, type in temps_to_clean_up:
4489             code.put_xdecref_clear(temp_name, type)
4490         code.putln(
4491                 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4492                     Naming.exc_vars)
4493         code.putln(
4494                 "%s = %s;" % (
4495                     Naming.exc_lineno_name, Naming.lineno_cname))
4496         #code.putln(
4497         #        "goto %s;" %
4498         #            catch_label)
4499         code.put_goto(catch_label)
4500         code.putln(
4501             "}")
4502             
4503     def put_error_uncatcher(self, code, i, error_label):
4504         code.globalstate.use_utility_code(restore_exception_utility_code)
4505         code.putln(
4506             "case %s: {" %
4507                 i)
4508         code.putln(
4509                 "__Pyx_ErrRestore(%s, %s, %s);" %
4510                     Naming.exc_vars)
4511         code.putln(
4512                 "%s = %s;" % (
4513                     Naming.lineno_cname, Naming.exc_lineno_name))
4514         for var in Naming.exc_vars:
4515             code.putln(
4516                 "%s = 0;" %
4517                     var)
4518         code.put_goto(error_label)
4519         code.putln(
4520             "}")
4521
4522     def annotate(self, code):
4523         self.body.annotate(code)
4524         self.finally_clause.annotate(code)
4525
4526
4527 class GILStatNode(TryFinallyStatNode):
4528     #  'with gil' or 'with nogil' statement
4529     #
4530     #   state   string   'gil' or 'nogil'
4531         
4532     child_attrs = []
4533     
4534     preserve_exception = 0
4535
4536     def __init__(self, pos, state, body):
4537         self.state = state
4538         TryFinallyStatNode.__init__(self, pos,
4539             body = body,
4540             finally_clause = GILExitNode(pos, state = state))
4541
4542     def analyse_expressions(self, env):
4543         env.use_utility_code(py23_init_threads_utility_code)
4544         was_nogil = env.nogil
4545         env.nogil = 1
4546         TryFinallyStatNode.analyse_expressions(self, env)
4547         env.nogil = was_nogil
4548
4549     def gil_check(self, env):
4550         pass
4551
4552     def generate_execution_code(self, code):
4553         code.putln("/*with %s:*/ {" % self.state)
4554         if self.state == 'gil':
4555             code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
4556         else:
4557             code.putln("PyThreadState *_save;")
4558             code.putln("Py_UNBLOCK_THREADS")
4559         TryFinallyStatNode.generate_execution_code(self, code)
4560         code.putln("}")
4561
4562
4563 class GILExitNode(StatNode):
4564     #  Used as the 'finally' block in a GILStatNode
4565     #
4566     #  state   string   'gil' or 'nogil'
4567
4568     child_attrs = []
4569
4570     def analyse_expressions(self, env):
4571         pass
4572
4573     def generate_execution_code(self, code):
4574         if self.state == 'gil':
4575             code.putln("PyGILState_Release();")
4576         else:
4577             code.putln("Py_BLOCK_THREADS")
4578
4579
4580 class CImportStatNode(StatNode):
4581     #  cimport statement
4582     #
4583     #  module_name   string           Qualified name of module being imported
4584     #  as_name       string or None   Name specified in "as" clause, if any
4585
4586     child_attrs = []
4587     
4588     def analyse_declarations(self, env):
4589         if not env.is_module_scope:
4590             error(self.pos, "cimport only allowed at module level")
4591             return
4592         module_scope = env.find_module(self.module_name, self.pos)
4593         if "." in self.module_name:
4594             names = [EncodedString(name) for name in self.module_name.split(".")]
4595             top_name = names[0]
4596             top_module_scope = env.context.find_submodule(top_name)
4597             module_scope = top_module_scope
4598             for name in names[1:]:
4599                 submodule_scope = module_scope.find_submodule(name)
4600                 module_scope.declare_module(name, submodule_scope, self.pos)
4601                 module_scope = submodule_scope
4602             if self.as_name:
4603                 env.declare_module(self.as_name, module_scope, self.pos)
4604             else:
4605                 env.declare_module(top_name, top_module_scope, self.pos)
4606         else:
4607             name = self.as_name or self.module_name
4608             env.declare_module(name, module_scope, self.pos)
4609
4610     def analyse_expressions(self, env):
4611         pass
4612     
4613     def generate_execution_code(self, code):
4614         pass
4615     
4616
4617 class FromCImportStatNode(StatNode):
4618     #  from ... cimport statement
4619     #
4620     #  module_name     string                        Qualified name of module
4621     #  imported_names  [(pos, name, as_name, kind)]  Names to be imported
4622     
4623     child_attrs = []
4624
4625     def analyse_declarations(self, env):
4626         if not env.is_module_scope:
4627             error(self.pos, "cimport only allowed at module level")
4628             return
4629         module_scope = env.find_module(self.module_name, self.pos)
4630         env.add_imported_module(module_scope)
4631         for pos, name, as_name, kind in self.imported_names:
4632             if name == "*":
4633                 for local_name, entry in module_scope.entries.items():
4634                     env.add_imported_entry(local_name, entry, pos)
4635             else:
4636                 entry = module_scope.lookup(name)
4637                 if entry:
4638                     if kind and not self.declaration_matches(entry, kind):
4639                         entry.redeclared(pos)
4640                 else:
4641                     if kind == 'struct' or kind == 'union':
4642                         entry = module_scope.declare_struct_or_union(name,
4643                             kind = kind, scope = None, typedef_flag = 0, pos = pos)
4644                     elif kind == 'class':
4645                         entry = module_scope.declare_c_class(name, pos = pos,
4646                             module_name = self.module_name)
4647                     else:
4648                         error(pos, "Name '%s' not declared in module '%s'"
4649                             % (name, self.module_name))
4650                         
4651                 if entry:
4652                     local_name = as_name or name
4653                     env.add_imported_entry(local_name, entry, pos)
4654     
4655     def declaration_matches(self, entry, kind):
4656         if not entry.is_type:
4657             return 0
4658         type = entry.type
4659         if kind == 'class':
4660             if not type.is_extension_type:
4661                 return 0
4662         else:
4663             if not type.is_struct_or_union:
4664                 return 0
4665             if kind != type.kind:
4666                 return 0
4667         return 1
4668
4669     def analyse_expressions(self, env):
4670         pass
4671     
4672     def generate_execution_code(self, code):
4673         pass
4674
4675
4676 class FromImportStatNode(StatNode):
4677     #  from ... import statement
4678     #
4679     #  module           ImportNode
4680     #  items            [(string, NameNode)]
4681     #  interned_items   [(string, NameNode, ExprNode)]
4682     #  item             PyTempNode            used internally
4683     #  import_star      boolean               used internally
4684
4685     child_attrs = ["module"]
4686     import_star = 0
4687     
4688     def analyse_declarations(self, env):
4689         for name, target in self.items:
4690             if name == "*":
4691                 if not env.is_module_scope:
4692                     error(self.pos, "import * only allowed at module level")
4693                     return
4694                 env.has_import_star = 1
4695                 self.import_star = 1
4696             else:
4697                 target.analyse_target_declaration(env)
4698     
4699     def analyse_expressions(self, env):
4700         import ExprNodes
4701         self.module.analyse_expressions(env)
4702         self.item = ExprNodes.PyTempNode(self.pos, env)
4703         self.item.allocate_temp(env)
4704         self.interned_items = []
4705         for name, target in self.items:
4706             if name == '*':
4707                 for _, entry in env.entries.items():
4708                     if not entry.is_type and entry.type.is_extension_type:
4709                         env.use_utility_code(ExprNodes.type_test_utility_code)
4710                         break
4711             else:
4712                 entry =  env.lookup(target.name)
4713                 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4714                     continue # already cimported
4715                 target.analyse_target_expression(env, None)
4716                 if target.type is py_object_type:
4717                     coerced_item = None
4718                 else:
4719                     coerced_item = self.item.coerce_to(target.type, env)
4720                 self.interned_items.append(
4721                     (env.intern_identifier(name), target, coerced_item))
4722                 #target.release_target_temp(env) # was release_temp ?!?
4723         self.module.release_temp(env)
4724         self.item.release_temp(env)
4725     
4726     def generate_execution_code(self, code):
4727         self.module.generate_evaluation_code(code)
4728         if self.import_star:
4729             code.putln(
4730                 'if (%s(%s) < 0) %s;' % (
4731                     Naming.import_star,
4732                     self.module.py_result(),
4733                     code.error_goto(self.pos)))
4734         for cname, target, coerced_item in self.interned_items:
4735             code.putln(
4736                 '%s = PyObject_GetAttr(%s, %s); %s' % (
4737                     self.item.result(), 
4738                     self.module.py_result(),
4739                     cname,
4740                     code.error_goto_if_null(self.item.result(), self.pos)))
4741             code.put_gotref(self.item.py_result())
4742             if coerced_item is None:
4743                 target.generate_assignment_code(self.item, code)
4744             else:
4745                 coerced_item.allocate_temp_result(code)
4746                 coerced_item.generate_result_code(code)
4747                 target.generate_assignment_code(coerced_item, code)
4748                 if self.item.result() != coerced_item.result():
4749                     code.put_decref_clear(self.item.result(), self.item.type)
4750         self.module.generate_disposal_code(code)
4751         self.module.free_temps(code)
4752
4753
4754
4755 #------------------------------------------------------------------------------------
4756 #
4757 #  Runtime support code
4758 #
4759 #------------------------------------------------------------------------------------
4760
4761 utility_function_predeclarations = \
4762 """
4763 #ifdef __GNUC__
4764 #define INLINE __inline__
4765 #elif _WIN32
4766 #define INLINE __inline
4767 #else
4768 #define INLINE 
4769 #endif
4770
4771 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4772
4773 """ + """
4774
4775 static int %(skip_dispatch_cname)s = 0;
4776
4777 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4778
4779 if Options.gcc_branch_hints:
4780     branch_prediction_macros = \
4781     """
4782 #ifdef __GNUC__
4783 /* Test for GCC > 2.95 */
4784 #if __GNUC__ > 2 || \
4785               (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) 
4786 #define likely(x)   __builtin_expect(!!(x), 1)
4787 #define unlikely(x) __builtin_expect(!!(x), 0)
4788 #else /* __GNUC__ > 2 ... */
4789 #define likely(x)   (x)
4790 #define unlikely(x) (x)
4791 #endif /* __GNUC__ > 2 ... */
4792 #else /* __GNUC__ */
4793 #define likely(x)   (x)
4794 #define unlikely(x) (x)
4795 #endif /* __GNUC__ */
4796     """
4797 else:
4798     branch_prediction_macros = \
4799     """
4800 #define likely(x)   (x)
4801 #define unlikely(x) (x)
4802     """
4803
4804 #get_name_predeclaration = \
4805 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4806
4807 #get_name_interned_predeclaration = \
4808 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4809
4810 #------------------------------------------------------------------------------------
4811
4812 printing_utility_code = UtilityCode(
4813 proto = """
4814 static int __Pyx_Print(PyObject *, int); /*proto*/
4815 #if PY_MAJOR_VERSION >= 3
4816 static PyObject* %s = 0;
4817 static PyObject* %s = 0;
4818 #endif
4819 """ % (Naming.print_function, Naming.print_function_kwargs),
4820 impl = r"""
4821 #if PY_MAJOR_VERSION < 3
4822 static PyObject *__Pyx_GetStdout(void) {
4823     PyObject *f = PySys_GetObject((char *)"stdout");
4824     if (!f) {
4825         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4826     }
4827     return f;
4828 }
4829
4830 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4831     PyObject *f;
4832     PyObject* v;
4833     int i;
4834
4835     if (!(f = __Pyx_GetStdout()))
4836         return -1;
4837     for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4838         if (PyFile_SoftSpace(f, 1)) {
4839             if (PyFile_WriteString(" ", f) < 0)
4840                 return -1;
4841         }
4842         v = PyTuple_GET_ITEM(arg_tuple, i);
4843         if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4844             return -1;
4845         if (PyString_Check(v)) {
4846             char *s = PyString_AsString(v);
4847             Py_ssize_t len = PyString_Size(v);
4848             if (len > 0 &&
4849                 isspace(Py_CHARMASK(s[len-1])) &&
4850                 s[len-1] != ' ')
4851                     PyFile_SoftSpace(f, 0);
4852         }
4853     }
4854     if (newline) {
4855         if (PyFile_WriteString("\n", f) < 0)
4856             return -1;
4857         PyFile_SoftSpace(f, 0);
4858     }
4859     return 0;
4860 }
4861
4862 #else /* Python 3 has a print function */
4863
4864 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4865     PyObject* kwargs = 0;
4866     PyObject* result = 0;
4867     PyObject* end_string;
4868     if (!%(PRINT_FUNCTION)s) {
4869         %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4870         if (!%(PRINT_FUNCTION)s)
4871             return -1;
4872     }
4873     if (!newline) {
4874         if (!%(PRINT_KWARGS)s) {
4875             %(PRINT_KWARGS)s = PyDict_New();
4876             if (!%(PRINT_KWARGS)s)
4877                 return -1;
4878             end_string = PyUnicode_FromStringAndSize(" ", 1);
4879             if (!end_string)
4880                 return -1;
4881             if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4882                 Py_DECREF(end_string);
4883                 return -1;
4884             }
4885             Py_DECREF(end_string);
4886         }
4887         kwargs = %(PRINT_KWARGS)s;
4888     }
4889     result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4890     if (!result)
4891         return -1;
4892     Py_DECREF(result);
4893     return 0;
4894 }
4895
4896 #endif
4897 """ % {'BUILTINS'       : Naming.builtins_cname,
4898        'PRINT_FUNCTION' : Naming.print_function,
4899        'PRINT_KWARGS'   : Naming.print_function_kwargs}
4900 )
4901
4902
4903 printing_one_utility_code = UtilityCode(
4904 proto = """
4905 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4906 """,
4907 impl = r"""
4908 #if PY_MAJOR_VERSION < 3
4909
4910 static int __Pyx_PrintOne(PyObject *o) {
4911     PyObject *f;
4912     if (!(f = __Pyx_GetStdout()))
4913         return -1;
4914     if (PyFile_SoftSpace(f, 0)) {
4915         if (PyFile_WriteString(" ", f) < 0)
4916             return -1;
4917     }
4918     if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4919         return -1;
4920     if (PyFile_WriteString("\n", f) < 0)
4921         return -1;
4922     return 0;
4923     /* the line below is just to avoid compiler
4924      * compiler warnings about unused functions */
4925     return __Pyx_Print(NULL, 0);
4926 }
4927
4928 #else /* Python 3 has a print function */
4929
4930 static int __Pyx_PrintOne(PyObject *o) {
4931     int res;
4932     PyObject* arg_tuple = PyTuple_New(1);
4933     if (unlikely(!arg_tuple))
4934         return -1;
4935     Py_INCREF(o);
4936     PyTuple_SET_ITEM(arg_tuple, 0, o);
4937     res = __Pyx_Print(arg_tuple, 1);
4938     Py_DECREF(arg_tuple);
4939     return res;
4940 }
4941
4942 #endif
4943 """)
4944
4945
4946
4947 #------------------------------------------------------------------------------------
4948
4949 # The following function is based on do_raise() from ceval.c.
4950
4951 raise_utility_code = UtilityCode(
4952 proto = """
4953 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4954 """,
4955 impl = """
4956 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4957     Py_XINCREF(type);
4958     Py_XINCREF(value);
4959     Py_XINCREF(tb);
4960     /* First, check the traceback argument, replacing None with NULL. */
4961     if (tb == Py_None) {
4962         Py_DECREF(tb);
4963         tb = 0;
4964     }
4965     else if (tb != NULL && !PyTraceBack_Check(tb)) {
4966         PyErr_SetString(PyExc_TypeError,
4967             "raise: arg 3 must be a traceback or None");
4968         goto raise_error;
4969     }
4970     /* Next, replace a missing value with None */
4971     if (value == NULL) {
4972         value = Py_None;
4973         Py_INCREF(value);
4974     }
4975     #if PY_VERSION_HEX < 0x02050000
4976     if (!PyClass_Check(type))
4977     #else
4978     if (!PyType_Check(type))
4979     #endif
4980     {
4981         /* Raising an instance.  The value should be a dummy. */
4982         if (value != Py_None) {
4983             PyErr_SetString(PyExc_TypeError,
4984                 "instance exception may not have a separate value");
4985             goto raise_error;
4986         }
4987         /* Normalize to raise <class>, <instance> */
4988         Py_DECREF(value);
4989         value = type;
4990         #if PY_VERSION_HEX < 0x02050000
4991             if (PyInstance_Check(type)) {
4992                 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4993                 Py_INCREF(type);
4994             }
4995             else {
4996                 type = 0;
4997                 PyErr_SetString(PyExc_TypeError,
4998                     "raise: exception must be an old-style class or instance");
4999                 goto raise_error;
5000             }
5001         #else
5002             type = (PyObject*) Py_TYPE(type);
5003             Py_INCREF(type);
5004             if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5005                 PyErr_SetString(PyExc_TypeError,
5006                     "raise: exception class must be a subclass of BaseException");
5007                 goto raise_error;
5008             }
5009         #endif
5010     }
5011     __Pyx_ErrRestore(type, value, tb);
5012     return;
5013 raise_error:
5014     Py_XDECREF(value);
5015     Py_XDECREF(type);
5016     Py_XDECREF(tb);
5017     return;
5018 }
5019 """)
5020
5021 #------------------------------------------------------------------------------------
5022
5023 reraise_utility_code = UtilityCode(
5024 proto = """
5025 static void __Pyx_ReRaise(void); /*proto*/
5026 """,
5027 impl = """
5028 static void __Pyx_ReRaise(void) {
5029     PyThreadState *tstate = PyThreadState_GET();
5030     PyObject* tmp_type = tstate->curexc_type;
5031     PyObject* tmp_value = tstate->curexc_value;
5032     PyObject* tmp_tb = tstate->curexc_traceback;
5033     tstate->curexc_type = tstate->exc_type;
5034     tstate->curexc_value = tstate->exc_value;
5035     tstate->curexc_traceback = tstate->exc_traceback;
5036     tstate->exc_type = 0;
5037     tstate->exc_value = 0;
5038     tstate->exc_traceback = 0;
5039     Py_XDECREF(tmp_type);
5040     Py_XDECREF(tmp_value);
5041     Py_XDECREF(tmp_tb);
5042 }
5043 """)
5044
5045 #------------------------------------------------------------------------------------
5046
5047 arg_type_test_utility_code = UtilityCode(
5048 proto = """
5049 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5050     const char *name, int exact); /*proto*/
5051 """,
5052 impl = """
5053 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5054     const char *name, int exact)
5055 {
5056     if (!type) {
5057         PyErr_Format(PyExc_SystemError, "Missing type object");
5058         return 0;
5059     }
5060     if (none_allowed && obj == Py_None) return 1;
5061     else if (exact) {
5062         if (Py_TYPE(obj) == type) return 1;
5063     }
5064     else {
5065         if (PyObject_TypeCheck(obj, type)) return 1;
5066     }
5067     PyErr_Format(PyExc_TypeError,
5068         "Argument '%s' has incorrect type (expected %s, got %s)",
5069         name, type->tp_name, Py_TYPE(obj)->tp_name);
5070     return 0;
5071 }
5072 """)
5073
5074 #------------------------------------------------------------------------------------
5075 #
5076 #  __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5077 #  many or too few positional arguments were found.  This handles
5078 #  Py_ssize_t formatting correctly.
5079
5080 raise_argtuple_invalid_utility_code = UtilityCode(
5081 proto = """
5082 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5083     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5084 """,
5085 impl = """
5086 static void __Pyx_RaiseArgtupleInvalid(
5087     const char* func_name,
5088     int exact,
5089     Py_ssize_t num_min,
5090     Py_ssize_t num_max,
5091     Py_ssize_t num_found)
5092 {
5093     Py_ssize_t num_expected;
5094     const char *number, *more_or_less;
5095
5096     if (num_found < num_min) {
5097         num_expected = num_min;
5098         more_or_less = "at least";
5099     } else {
5100         num_expected = num_max;
5101         more_or_less = "at most";
5102     }
5103     if (exact) {
5104         more_or_less = "exactly";
5105     }
5106     number = (num_expected == 1) ? "" : "s";
5107     PyErr_Format(PyExc_TypeError,
5108         #if PY_VERSION_HEX < 0x02050000
5109             "%s() takes %s %d positional argument%s (%d given)",
5110         #else
5111             "%s() takes %s %zd positional argument%s (%zd given)",
5112         #endif
5113         func_name, more_or_less, num_expected, number, num_found);
5114 }
5115 """)
5116
5117 raise_keyword_required_utility_code = UtilityCode(
5118 proto = """
5119 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5120 """,
5121 impl = """
5122 static INLINE void __Pyx_RaiseKeywordRequired(
5123     const char* func_name,
5124     PyObject* kw_name)
5125 {
5126     PyErr_Format(PyExc_TypeError,
5127         #if PY_MAJOR_VERSION >= 3
5128         "%s() needs keyword-only argument %U", func_name, kw_name);
5129         #else
5130         "%s() needs keyword-only argument %s", func_name,
5131         PyString_AS_STRING(kw_name));
5132         #endif
5133 }
5134 """)
5135
5136 raise_double_keywords_utility_code = UtilityCode(
5137 proto = """
5138 static void __Pyx_RaiseDoubleKeywordsError(
5139     const char* func_name, PyObject* kw_name); /*proto*/
5140 """,
5141 impl = """
5142 static void __Pyx_RaiseDoubleKeywordsError(
5143     const char* func_name,
5144     PyObject* kw_name)
5145 {
5146     PyErr_Format(PyExc_TypeError,
5147         #if PY_MAJOR_VERSION >= 3
5148         "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5149         #else
5150         "%s() got multiple values for keyword argument '%s'", func_name,
5151         PyString_AS_STRING(kw_name));
5152         #endif
5153 }
5154 """)
5155
5156 #------------------------------------------------------------------------------------
5157 #
5158 #  __Pyx_CheckKeywordStrings raises an error if non-string keywords
5159 #  were passed to a function, or if any keywords were passed to a
5160 #  function that does not accept them.
5161
5162 keyword_string_check_utility_code = UtilityCode(
5163 proto = """
5164 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5165     const char* function_name, int kw_allowed); /*proto*/
5166 """,
5167 impl = """
5168 static INLINE int __Pyx_CheckKeywordStrings(
5169     PyObject *kwdict,
5170     const char* function_name,
5171     int kw_allowed)
5172 {
5173     PyObject* key = 0;
5174     Py_ssize_t pos = 0;
5175     while (PyDict_Next(kwdict, &pos, &key, 0)) {
5176         #if PY_MAJOR_VERSION < 3
5177         if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5178         #else
5179         if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5180         #endif
5181             goto invalid_keyword_type;
5182     }
5183     if ((!kw_allowed) && unlikely(key))
5184         goto invalid_keyword;
5185     return 1;
5186 invalid_keyword_type:
5187     PyErr_Format(PyExc_TypeError,
5188         "%s() keywords must be strings", function_name);
5189     return 0;
5190 invalid_keyword:
5191     PyErr_Format(PyExc_TypeError,
5192     #if PY_MAJOR_VERSION < 3
5193         "%s() got an unexpected keyword argument '%s'",
5194         function_name, PyString_AsString(key));
5195     #else
5196         "%s() got an unexpected keyword argument '%U'",
5197         function_name, key);
5198     #endif
5199     return 0;
5200 }
5201 """)
5202
5203 #------------------------------------------------------------------------------------
5204 #
5205 #  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5206 #  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
5207 #  keywords will raise an invalid keyword error.
5208 #
5209 #  Three kinds of errors are checked: 1) non-string keywords, 2)
5210 #  unexpected keywords and 3) overlap with positional arguments.
5211 #
5212 #  If num_posargs is greater 0, it denotes the number of positional
5213 #  arguments that were passed and that must therefore not appear
5214 #  amongst the keywords as well.
5215 #
5216 #  This method does not check for required keyword arguments.
5217 #
5218
5219 parse_keywords_utility_code = UtilityCode(
5220 proto = """
5221 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5222     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5223     const char* function_name); /*proto*/
5224 """,
5225 impl = """
5226 static int __Pyx_ParseOptionalKeywords(
5227     PyObject *kwds,
5228     PyObject **argnames[],
5229     PyObject *kwds2,
5230     PyObject *values[],
5231     Py_ssize_t num_pos_args,
5232     const char* function_name)
5233 {
5234     PyObject *key = 0, *value = 0;
5235     Py_ssize_t pos = 0;
5236     PyObject*** name;
5237     PyObject*** first_kw_arg = argnames + num_pos_args;
5238
5239     while (PyDict_Next(kwds, &pos, &key, &value)) {
5240         name = first_kw_arg;
5241         while (*name && (**name != key)) name++;
5242         if (*name) {
5243             values[name-argnames] = value;
5244         } else {
5245             #if PY_MAJOR_VERSION < 3
5246             if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5247             #else
5248             if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5249             #endif
5250                 goto invalid_keyword_type;
5251             } else {
5252                 for (name = first_kw_arg; *name; name++) {
5253                     #if PY_MAJOR_VERSION >= 3
5254                     if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5255                         PyUnicode_Compare(**name, key) == 0) break;
5256                     #else
5257                     if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5258                         _PyString_Eq(**name, key)) break;
5259                     #endif
5260                 }
5261                 if (*name) {
5262                     values[name-argnames] = value;
5263                 } else {
5264                     /* unexpected keyword found */
5265                     for (name=argnames; name != first_kw_arg; name++) {
5266                         if (**name == key) goto arg_passed_twice;
5267                         #if PY_MAJOR_VERSION >= 3
5268                         if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5269                             PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5270                         #else
5271                         if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5272                             _PyString_Eq(**name, key)) goto arg_passed_twice;
5273                         #endif
5274                     }
5275                     if (kwds2) {
5276                         if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5277                     } else {
5278                         goto invalid_keyword;
5279                     }
5280                 }
5281             }
5282         }
5283     }
5284     return 0;
5285 arg_passed_twice:
5286     __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5287     goto bad;
5288 invalid_keyword_type:
5289     PyErr_Format(PyExc_TypeError,
5290         "%s() keywords must be strings", function_name);
5291     goto bad;
5292 invalid_keyword:
5293     PyErr_Format(PyExc_TypeError,
5294     #if PY_MAJOR_VERSION < 3
5295         "%s() got an unexpected keyword argument '%s'",
5296         function_name, PyString_AsString(key));
5297     #else
5298         "%s() got an unexpected keyword argument '%U'",
5299         function_name, key);
5300     #endif
5301 bad:
5302     return -1;
5303 }
5304 """)
5305
5306 #------------------------------------------------------------------------------------
5307
5308 unraisable_exception_utility_code = UtilityCode(
5309 proto = """
5310 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5311 """,
5312 impl = """
5313 static void __Pyx_WriteUnraisable(const char *name) {
5314     PyObject *old_exc, *old_val, *old_tb;
5315     PyObject *ctx;
5316     __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5317     #if PY_MAJOR_VERSION < 3
5318     ctx = PyString_FromString(name);
5319     #else
5320     ctx = PyUnicode_FromString(name);
5321     #endif
5322     __Pyx_ErrRestore(old_exc, old_val, old_tb);
5323     if (!ctx) {
5324         PyErr_WriteUnraisable(Py_None);
5325     } else {
5326         PyErr_WriteUnraisable(ctx);
5327         Py_DECREF(ctx);
5328     }
5329 }
5330 """)
5331
5332 #------------------------------------------------------------------------------------
5333
5334 traceback_utility_code = UtilityCode(
5335 proto = """
5336 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5337 """,
5338 impl = """
5339 #include "compile.h"
5340 #include "frameobject.h"
5341 #include "traceback.h"
5342
5343 static void __Pyx_AddTraceback(const char *funcname) {
5344     PyObject *py_srcfile = 0;
5345     PyObject *py_funcname = 0;
5346     PyObject *py_globals = 0;
5347     PyObject *empty_string = 0;
5348     PyCodeObject *py_code = 0;
5349     PyFrameObject *py_frame = 0;
5350
5351     #if PY_MAJOR_VERSION < 3
5352     py_srcfile = PyString_FromString(%(FILENAME)s);
5353     #else
5354     py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5355     #endif
5356     if (!py_srcfile) goto bad;
5357     if (%(CLINENO)s) {
5358         #if PY_MAJOR_VERSION < 3
5359         py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5360         #else
5361         py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5362         #endif
5363     }
5364     else {
5365         #if PY_MAJOR_VERSION < 3
5366         py_funcname = PyString_FromString(funcname);
5367         #else
5368         py_funcname = PyUnicode_FromString(funcname);
5369         #endif
5370     }
5371     if (!py_funcname) goto bad;
5372     py_globals = PyModule_GetDict(%(GLOBALS)s);
5373     if (!py_globals) goto bad;
5374     #if PY_MAJOR_VERSION < 3
5375     empty_string = PyString_FromStringAndSize("", 0);
5376     #else
5377     empty_string = PyBytes_FromStringAndSize("", 0);
5378     #endif
5379     if (!empty_string) goto bad;
5380     py_code = PyCode_New(
5381         0,            /*int argcount,*/
5382         #if PY_MAJOR_VERSION >= 3
5383         0,            /*int kwonlyargcount,*/
5384         #endif
5385         0,            /*int nlocals,*/
5386         0,            /*int stacksize,*/
5387         0,            /*int flags,*/
5388         empty_string, /*PyObject *code,*/
5389         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
5390         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
5391         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
5392         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
5393         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
5394         py_srcfile,   /*PyObject *filename,*/
5395         py_funcname,  /*PyObject *name,*/
5396         %(LINENO)s,   /*int firstlineno,*/
5397         empty_string  /*PyObject *lnotab*/
5398     );
5399     if (!py_code) goto bad;
5400     py_frame = PyFrame_New(
5401         PyThreadState_GET(), /*PyThreadState *tstate,*/
5402         py_code,             /*PyCodeObject *code,*/
5403         py_globals,          /*PyObject *globals,*/
5404         0                    /*PyObject *locals*/
5405     );
5406     if (!py_frame) goto bad;
5407     py_frame->f_lineno = %(LINENO)s;
5408     PyTraceBack_Here(py_frame);
5409 bad:
5410     Py_XDECREF(py_srcfile);
5411     Py_XDECREF(py_funcname);
5412     Py_XDECREF(empty_string);
5413     Py_XDECREF(py_code);
5414     Py_XDECREF(py_frame);
5415 }
5416 """ % {
5417     'FILENAME': Naming.filename_cname,
5418     'LINENO':  Naming.lineno_cname,
5419     'CFILENAME': Naming.cfilenm_cname,
5420     'CLINENO':  Naming.clineno_cname,
5421     'GLOBALS': Naming.module_cname,
5422     'EMPTY_TUPLE' : Naming.empty_tuple,
5423 })
5424
5425 restore_exception_utility_code = UtilityCode(
5426 proto = """
5427 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5428 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5429 """,
5430 impl = """
5431 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5432     PyObject *tmp_type, *tmp_value, *tmp_tb;
5433     PyThreadState *tstate = PyThreadState_GET();
5434
5435 #if PY_MAJOR_VERSION >= 3
5436     /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5437     if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5438         tmp_type = tstate->exc_type;
5439         tmp_value = tstate->exc_value;
5440         tmp_tb = tstate->exc_traceback;
5441         PyErr_NormalizeException(&type, &value, &tb);
5442         PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5443         tstate->exc_type = 0;
5444         tstate->exc_value = 0;
5445         tstate->exc_traceback = 0;
5446         PyException_SetContext(value, tmp_value);
5447         Py_DECREF(tmp_type);
5448         Py_XDECREF(tmp_tb);
5449     }
5450 #endif
5451
5452     tmp_type = tstate->curexc_type;
5453     tmp_value = tstate->curexc_value;
5454     tmp_tb = tstate->curexc_traceback;
5455     tstate->curexc_type = type;
5456     tstate->curexc_value = value;
5457     tstate->curexc_traceback = tb;
5458     Py_XDECREF(tmp_type);
5459     Py_XDECREF(tmp_value);
5460     Py_XDECREF(tmp_tb);
5461 }
5462
5463 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5464     PyThreadState *tstate = PyThreadState_GET();
5465     *type = tstate->curexc_type;
5466     *value = tstate->curexc_value;
5467     *tb = tstate->curexc_traceback;
5468
5469     tstate->curexc_type = 0;
5470     tstate->curexc_value = 0;
5471     tstate->curexc_traceback = 0;
5472 }
5473
5474 """)
5475
5476 #------------------------------------------------------------------------------------
5477
5478 set_vtable_utility_code = UtilityCode(
5479 proto = """
5480 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5481 """,
5482 impl = """
5483 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5484     PyObject *pycobj = 0;
5485     int result;
5486     
5487     pycobj = PyCObject_FromVoidPtr(vtable, 0);
5488     if (!pycobj)
5489         goto bad;
5490     if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5491         goto bad;
5492     result = 0;
5493     goto done;
5494
5495 bad:
5496     result = -1;
5497 done:
5498     Py_XDECREF(pycobj);
5499     return result;
5500 }
5501 """)
5502
5503 #------------------------------------------------------------------------------------
5504
5505 get_vtable_utility_code = UtilityCode(
5506 proto = """
5507 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5508 """,
5509 impl = r"""
5510 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5511     int result;
5512     PyObject *pycobj;
5513
5514     pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5515     if (!pycobj)
5516         goto bad;
5517     *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5518     if (!*(void **)vtabptr)
5519         goto bad;
5520     result = 0;
5521     goto done;
5522
5523 bad:
5524     result = -1;
5525 done:
5526     Py_XDECREF(pycobj);
5527     return result;
5528 }
5529 """)
5530
5531 #------------------------------------------------------------------------------------
5532
5533 init_string_tab_utility_code = UtilityCode(
5534 proto = """
5535 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5536 """,
5537 impl = """
5538 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5539     while (t->p) {
5540         #if PY_MAJOR_VERSION < 3
5541         if (t->is_unicode && (!t->is_identifier)) {
5542             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5543         } else if (t->intern) {
5544             *t->p = PyString_InternFromString(t->s);
5545         } else {
5546             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5547         }
5548         #else  /* Python 3+ has unicode identifiers */
5549         if (t->is_identifier || (t->is_unicode && t->intern)) {
5550             *t->p = PyUnicode_InternFromString(t->s);
5551         } else if (t->is_unicode) {
5552             *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5553         } else {
5554             *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5555         }
5556         #endif
5557         if (!*t->p)
5558             return -1;
5559         ++t;
5560     }
5561     return 0;
5562 }
5563 """)
5564
5565 #------------------------------------------------------------------------------------
5566
5567 get_exception_utility_code = UtilityCode(
5568 proto = """
5569 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5570 """,
5571 impl = """
5572 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5573     PyObject *tmp_type, *tmp_value, *tmp_tb;
5574     PyThreadState *tstate = PyThreadState_GET();
5575     __Pyx_ErrFetch(type, value, tb);
5576     PyErr_NormalizeException(type, value, tb);
5577     if (PyErr_Occurred())
5578         goto bad;
5579     Py_INCREF(*type);
5580     Py_INCREF(*value);
5581     Py_INCREF(*tb);
5582     tmp_type = tstate->exc_type;
5583     tmp_value = tstate->exc_value;
5584     tmp_tb = tstate->exc_traceback;
5585     tstate->exc_type = *type;
5586     tstate->exc_value = *value;
5587     tstate->exc_traceback = *tb;
5588     /* Make sure tstate is in a consistent state when we XDECREF
5589     these objects (XDECREF may run arbitrary code). */
5590     Py_XDECREF(tmp_type);
5591     Py_XDECREF(tmp_value);
5592     Py_XDECREF(tmp_tb);
5593     return 0;
5594 bad:
5595     Py_XDECREF(*type);
5596     Py_XDECREF(*value);
5597     Py_XDECREF(*tb);
5598     return -1;
5599 }
5600
5601 """)
5602
5603 #------------------------------------------------------------------------------------
5604
5605 reset_exception_utility_code = UtilityCode(
5606 proto = """
5607 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5608 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5609 """,
5610 impl = """
5611 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5612     PyThreadState *tstate = PyThreadState_GET();
5613     *type = tstate->exc_type;
5614     *value = tstate->exc_value;
5615     *tb = tstate->exc_traceback;
5616     Py_XINCREF(*type);
5617     Py_XINCREF(*value);
5618     Py_XINCREF(*tb);
5619 }
5620
5621 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5622     PyObject *tmp_type, *tmp_value, *tmp_tb;
5623     PyThreadState *tstate = PyThreadState_GET();
5624     tmp_type = tstate->exc_type;
5625     tmp_value = tstate->exc_value;
5626     tmp_tb = tstate->exc_traceback;
5627     tstate->exc_type = type;
5628     tstate->exc_value = value;
5629     tstate->exc_traceback = tb;
5630     Py_XDECREF(tmp_type);
5631     Py_XDECREF(tmp_value);
5632     Py_XDECREF(tmp_tb);
5633 }
5634 """)
5635
5636 #------------------------------------------------------------------------------------
5637
5638 py23_init_threads_utility_code = UtilityCode(
5639 proto="""
5640 #ifndef __PYX_FORCE_INIT_THREADS
5641 #if PY_VERSION_HEX < 0x02040200
5642 #define __PYX_FORCE_INIT_THREADS 1
5643 #else
5644 #define __PYX_FORCE_INIT_THREADS 0
5645 #endif
5646 #endif
5647 """)
5648
5649 #------------------------------------------------------------------------------------