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