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