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