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