prevent duplicated calls to analyse_default_values() for cpdef functions
[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     #  is_py_target       bool
3845     #  loopvar_node       ExprNode (usually a NameNode or temp node)
3846     #  py_loopvar_node    PyTempNode or None
3847     child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3848
3849     is_py_target = False
3850     loopvar_node = None
3851     py_loopvar_node = None
3852
3853     def analyse_declarations(self, env):
3854         self.target.analyse_target_declaration(env)
3855         self.body.analyse_declarations(env)
3856         if self.else_clause:
3857             self.else_clause.analyse_declarations(env)
3858
3859     def analyse_expressions(self, env):
3860         import ExprNodes
3861         self.target.analyse_target_types(env)
3862         self.bound1.analyse_types(env)
3863         self.bound2.analyse_types(env)
3864         if self.target.type.is_numeric:
3865             self.bound1 = self.bound1.coerce_to(self.target.type, env)
3866             self.bound2 = self.bound2.coerce_to(self.target.type, env)
3867         else:
3868             self.bound1 = self.bound1.coerce_to_integer(env)
3869             self.bound2 = self.bound2.coerce_to_integer(env)
3870         if self.step is not None:
3871             if isinstance(self.step, ExprNodes.UnaryMinusNode):
3872                 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3873             self.step.analyse_types(env)
3874             self.step = self.step.coerce_to_integer(env)
3875         if not (self.bound2.is_name or self.bound2.is_literal):
3876             self.bound2 = self.bound2.coerce_to_temp(env)
3877         target_type = self.target.type
3878         if not (target_type.is_pyobject or target_type.is_numeric):
3879             error(self.target.pos,
3880                 "Integer for-loop variable must be of type int or Python object")
3881         #if not (target_type.is_pyobject
3882         #    or target_type.assignable_from(PyrexTypes.c_int_type)):
3883         #        error(self.target.pos,
3884         #            "Cannot assign integer to variable of type '%s'" % target_type)
3885         if target_type.is_numeric:
3886             self.is_py_target = 0
3887             if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3888                 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3889             self.loopvar_node = self.target
3890             self.py_loopvar_node = None
3891         else:
3892             self.is_py_target = 1
3893             c_loopvar_node = ExprNodes.TempNode(self.pos, 
3894                 PyrexTypes.c_long_type, env)
3895             c_loopvar_node.allocate_temps(env)
3896             self.loopvar_node = c_loopvar_node
3897             self.py_loopvar_node = \
3898                 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3899         self.bound1.allocate_temps(env)
3900         self.bound2.allocate_temps(env)
3901         if self.step is not None:
3902             self.step.allocate_temps(env)
3903         if self.is_py_target:
3904             self.py_loopvar_node.allocate_temps(env)
3905             self.target.allocate_target_temps(env, self.py_loopvar_node)
3906             #self.target.release_target_temp(env)
3907             #self.py_loopvar_node.release_temp(env)
3908         self.body.analyse_expressions(env)
3909         if self.is_py_target:
3910             c_loopvar_node.release_temp(env)
3911         if self.else_clause:
3912             self.else_clause.analyse_expressions(env)
3913         self.bound1.release_temp(env)
3914         self.bound2.release_temp(env)
3915         if self.step is not None:
3916             self.step.release_temp(env)
3917             
3918     def generate_execution_code(self, code):
3919         old_loop_labels = code.new_loop_labels()
3920         from_range = getattr(self, "from_range", False)
3921         self.bound1.generate_evaluation_code(code)
3922         self.bound2.generate_evaluation_code(code)
3923         offset, incop = self.relation_table[self.relation1]
3924         if incop == "++":
3925             decop = "--"
3926         else:
3927             decop = "++"
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             decop = "%s=%s" % (decop[0], step)
3933         loopvar_name = self.loopvar_node.result()
3934         if from_range:
3935             range_bound = code.funcstate.allocate_temp(self.bound2.type, manage_ref=False)
3936             code.putln("%s = %s;" % (range_bound, self.bound2.result()))
3937             # Skip the loop entirely (and avoid assigning to the loopvar) if
3938             # the loop is empty:
3939             code.putln("if (%s%s %s %s) {" % (
3940                 self.bound1.result(), offset, self.relation2, range_bound
3941                 ))
3942         else:
3943             range_bound = self.bound2.result()
3944         code.putln(
3945             "for (%s = %s%s; %s %s %s; %s%s) {" % (
3946                 loopvar_name,
3947                 self.bound1.result(), offset,
3948                 loopvar_name, self.relation2, range_bound,
3949                 loopvar_name, incop))
3950         if self.py_loopvar_node:
3951             self.py_loopvar_node.generate_evaluation_code(code)
3952             self.target.generate_assignment_code(self.py_loopvar_node, code)
3953         self.body.generate_execution_code(code)
3954         code.put_label(code.continue_label)
3955         if from_range:
3956             # Undo last increment to maintain Python semantics:
3957             code.putln("} %s%s;" % (loopvar_name, decop))
3958             # End the outer if statement:
3959             code.putln("} /* end if */")
3960             code.funcstate.release_temp(range_bound)
3961         else:
3962             code.putln("}")
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     
3978     relation_table = {
3979         # {relop : (initial offset, increment op)}
3980         '<=': ("",   "++"),
3981         '<' : ("+1", "++"),
3982         '>=': ("",   "--"),
3983         '>' : ("-1", "--")
3984     }
3985     
3986     def annotate(self, code):
3987         self.target.annotate(code)
3988         self.bound1.annotate(code)
3989         self.bound2.annotate(code)
3990         if self.step:
3991             self.bound2.annotate(code)
3992         self.body.annotate(code)
3993         if self.else_clause:
3994             self.else_clause.annotate(code)
3995
3996
3997 class WithStatNode(StatNode):
3998     """
3999     Represents a Python with statement.
4000     
4001     This is only used at parse tree level; and is not present in
4002     analysis or generation phases.
4003     """
4004     #  manager          The with statement manager object
4005     #  target            Node (lhs expression)
4006     #  body             StatNode
4007     child_attrs = ["manager", "target", "body"]
4008
4009 class TryExceptStatNode(StatNode):
4010     #  try .. except statement
4011     #
4012     #  body             StatNode
4013     #  except_clauses   [ExceptClauseNode]
4014     #  else_clause      StatNode or None
4015     #  cleanup_list     [Entry]            old style temps to clean up on error
4016
4017     child_attrs = ["body", "except_clauses", "else_clause"]
4018     
4019     def analyse_control_flow(self, env):
4020         env.start_branching(self.pos)
4021         self.body.analyse_control_flow(env)
4022         successful_try = env.control_flow # grab this for later
4023         env.next_branch(self.body.end_pos())
4024         env.finish_branching(self.body.end_pos())
4025         
4026         env.start_branching(self.except_clauses[0].pos)
4027         for except_clause in self.except_clauses:
4028             except_clause.analyse_control_flow(env)
4029             env.next_branch(except_clause.end_pos())
4030             
4031         # the else cause it executed only when the try clause finishes
4032         env.control_flow.incoming = successful_try
4033         if self.else_clause:
4034             self.else_clause.analyse_control_flow(env)
4035         env.finish_branching(self.end_pos())
4036
4037     def analyse_declarations(self, env):
4038         self.body.analyse_declarations(env)
4039         for except_clause in self.except_clauses:
4040             except_clause.analyse_declarations(env)
4041         if self.else_clause:
4042             self.else_clause.analyse_declarations(env)
4043         env.use_utility_code(reset_exception_utility_code)
4044
4045     def analyse_expressions(self, env):
4046         self.body.analyse_expressions(env)
4047         self.cleanup_list = env.free_temp_entries[:]
4048         default_clause_seen = 0
4049         for except_clause in self.except_clauses:
4050             except_clause.analyse_expressions(env)
4051             if default_clause_seen:
4052                 error(except_clause.pos, "default 'except:' must be last")
4053             if not except_clause.pattern:
4054                 default_clause_seen = 1
4055         self.has_default_clause = default_clause_seen
4056         if self.else_clause:
4057             self.else_clause.analyse_expressions(env)
4058
4059     gil_check = StatNode._gil_check
4060     gil_message = "Try-except statement"
4061
4062     def generate_execution_code(self, code):
4063         old_return_label = code.return_label
4064         old_break_label = code.break_label
4065         old_continue_label = code.continue_label
4066         old_error_label = code.new_error_label()
4067         our_error_label = code.error_label
4068         except_end_label = code.new_label('exception_handled')
4069         except_error_label = code.new_label('except_error')
4070         except_return_label = code.new_label('except_return')
4071         try_return_label = code.new_label('try_return')
4072         try_break_label = code.new_label('try_break')
4073         try_continue_label = code.new_label('try_continue')
4074         try_end_label = code.new_label('try_end')
4075
4076         code.putln("{")
4077         code.putln("PyObject %s;" %
4078                    ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4079         code.putln("__Pyx_ExceptionSave(%s);" %
4080                    ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4081         for var in Naming.exc_save_vars:
4082             code.put_xgotref(var)
4083         code.putln(
4084             "/*try:*/ {")
4085         code.return_label = try_return_label
4086         code.break_label = try_break_label
4087         code.continue_label = try_continue_label
4088         self.body.generate_execution_code(code)
4089         code.putln(
4090             "}")
4091         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4092         code.error_label = except_error_label
4093         code.return_label = except_return_label
4094         if self.else_clause:
4095             code.putln(
4096                 "/*else:*/ {")
4097             self.else_clause.generate_execution_code(code)
4098             code.putln(
4099                 "}")
4100         for var in Naming.exc_save_vars:
4101             code.put_xdecref_clear(var, py_object_type)
4102         code.put_goto(try_end_label)
4103         if code.label_used(try_return_label):
4104             code.put_label(try_return_label)
4105             for var in Naming.exc_save_vars:
4106                 code.put_xdecref_clear(var, py_object_type)
4107             code.put_goto(old_return_label)
4108         code.put_label(our_error_label)
4109         code.put_var_xdecrefs_clear(self.cleanup_list)
4110         for temp_name, type in temps_to_clean_up:
4111             code.put_xdecref_clear(temp_name, type)
4112         for except_clause in self.except_clauses:
4113             except_clause.generate_handling_code(code, except_end_label)
4114
4115         error_label_used = code.label_used(except_error_label)
4116         if error_label_used or not self.has_default_clause:
4117             if error_label_used:
4118                 code.put_label(except_error_label)
4119             for var in Naming.exc_save_vars:
4120                 code.put_xdecref(var, py_object_type)
4121             code.put_goto(old_error_label)
4122             
4123         if code.label_used(try_break_label):
4124             code.put_label(try_break_label)
4125             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4126             code.putln("__Pyx_ExceptionReset(%s);" %
4127                        ', '.join(Naming.exc_save_vars))
4128             code.put_goto(old_break_label)
4129             
4130         if code.label_used(try_continue_label):
4131             code.put_label(try_continue_label)
4132             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4133             code.putln("__Pyx_ExceptionReset(%s);" %
4134                        ', '.join(Naming.exc_save_vars))
4135             code.put_goto(old_continue_label)
4136
4137         if code.label_used(except_return_label):
4138             code.put_label(except_return_label)
4139             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4140             code.putln("__Pyx_ExceptionReset(%s);" %
4141                        ', '.join(Naming.exc_save_vars))
4142             code.put_goto(old_return_label)
4143
4144         if code.label_used(except_end_label):
4145             code.put_label(except_end_label)
4146             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4147             code.putln("__Pyx_ExceptionReset(%s);" %
4148                        ', '.join(Naming.exc_save_vars))
4149         code.put_label(try_end_label)
4150         code.putln("}")
4151
4152         code.return_label = old_return_label
4153         code.break_label = old_break_label
4154         code.continue_label = old_continue_label
4155         code.error_label = old_error_label
4156
4157     def annotate(self, code):
4158         self.body.annotate(code)
4159         for except_node in self.except_clauses:
4160             except_node.annotate(code)
4161         if self.else_clause:
4162             self.else_clause.annotate(code)
4163
4164
4165 class ExceptClauseNode(Node):
4166     #  Part of try ... except statement.
4167     #
4168     #  pattern        ExprNode
4169     #  target         ExprNode or None
4170     #  body           StatNode
4171     #  excinfo_target NameNode or None   optional target for exception info
4172     #  match_flag     string             result of exception match
4173     #  exc_value      ExcValueNode       used internally
4174     #  function_name  string             qualified name of enclosing function
4175     #  exc_vars       (string * 3)       local exception variables
4176
4177     # excinfo_target is never set by the parser, but can be set by a transform
4178     # in order to extract more extensive information about the exception as a
4179     # sys.exc_info()-style tuple into a target variable
4180     
4181     child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4182
4183     exc_value = None
4184     excinfo_target = None
4185
4186     def analyse_declarations(self, env):
4187         if self.target:
4188             self.target.analyse_target_declaration(env)
4189         if self.excinfo_target is not None:
4190             self.excinfo_target.analyse_target_declaration(env)
4191         self.body.analyse_declarations(env)
4192     
4193     def analyse_expressions(self, env):
4194         import ExprNodes
4195         genv = env.global_scope()
4196         self.function_name = env.qualified_name
4197         if self.pattern:
4198             self.pattern.analyse_expressions(env)
4199             self.pattern = self.pattern.coerce_to_pyobject(env)
4200             self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4201             self.pattern.release_temp(env)
4202             env.release_temp(self.match_flag)
4203         self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4204         if self.target:
4205             self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4206             self.exc_value.allocate_temps(env)
4207             self.target.analyse_target_expression(env, self.exc_value)
4208         if self.excinfo_target is not None:
4209             import ExprNodes
4210             self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4211                 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4212                 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4213                 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4214             ])
4215             self.excinfo_tuple.analyse_expressions(env)
4216             self.excinfo_tuple.allocate_temps(env)
4217             self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4218
4219         self.body.analyse_expressions(env)
4220         for var in self.exc_vars:
4221             env.release_temp(var)
4222         env.use_utility_code(get_exception_utility_code)
4223         env.use_utility_code(restore_exception_utility_code)
4224     
4225     def generate_handling_code(self, code, end_label):
4226         code.mark_pos(self.pos)
4227         if self.pattern:
4228             self.pattern.generate_evaluation_code(code)
4229             code.putln(
4230                 "%s = PyErr_ExceptionMatches(%s);" % (
4231                     self.match_flag,
4232                     self.pattern.py_result()))
4233             self.pattern.generate_disposal_code(code)
4234             self.pattern.free_temps(code)
4235             code.putln(
4236                 "if (%s) {" %
4237                     self.match_flag)
4238         else:
4239             code.putln("/*except:*/ {")
4240         code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4241         # We always have to fetch the exception value even if
4242         # there is no target, because this also normalises the 
4243         # exception and stores it in the thread state.
4244         exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
4245         code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4246             code.error_goto(self.pos)))
4247         for x in self.exc_vars:
4248             code.put_gotref(x)
4249         if self.target:
4250             self.exc_value.generate_evaluation_code(code)
4251             self.target.generate_assignment_code(self.exc_value, code)
4252         if self.excinfo_target is not None:
4253             self.excinfo_tuple.generate_evaluation_code(code)
4254             self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4255
4256
4257         old_break_label, old_continue_label = code.break_label, code.continue_label
4258         code.break_label = code.new_label('except_break')
4259         code.continue_label = code.new_label('except_continue')
4260
4261         old_exc_vars = code.funcstate.exc_vars
4262         code.funcstate.exc_vars = self.exc_vars
4263         self.body.generate_execution_code(code)
4264         code.funcstate.exc_vars = old_exc_vars
4265         for var in self.exc_vars:
4266             code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4267         code.put_goto(end_label)
4268         
4269         if code.label_used(code.break_label):
4270             code.put_label(code.break_label)
4271             for var in self.exc_vars:
4272                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4273             code.put_goto(old_break_label)
4274         code.break_label = old_break_label
4275
4276         if code.label_used(code.continue_label):
4277             code.put_label(code.continue_label)
4278             for var in self.exc_vars:
4279                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4280             code.put_goto(old_continue_label)
4281         code.continue_label = old_continue_label
4282         
4283         code.putln(
4284             "}")
4285
4286     def annotate(self, code):
4287         if self.pattern:
4288             self.pattern.annotate(code)
4289         if self.target:
4290             self.target.annotate(code)
4291         self.body.annotate(code)
4292
4293
4294 class TryFinallyStatNode(StatNode):
4295     #  try ... finally statement
4296     #
4297     #  body             StatNode
4298     #  finally_clause   StatNode
4299     #
4300     #  cleanup_list     [Entry]     old_style temps to clean up on error
4301     #
4302     #  The plan is that we funnel all continue, break
4303     #  return and error gotos into the beginning of the
4304     #  finally block, setting a variable to remember which
4305     #  one we're doing. At the end of the finally block, we
4306     #  switch on the variable to figure out where to go.
4307     #  In addition, if we're doing an error, we save the
4308     #  exception on entry to the finally block and restore
4309     #  it on exit.
4310
4311     child_attrs = ["body", "finally_clause"]
4312     
4313     preserve_exception = 1
4314     
4315     disallow_continue_in_try_finally = 0
4316     # There doesn't seem to be any point in disallowing
4317     # continue in the try block, since we have no problem
4318     # handling it.
4319
4320     def create_analysed(pos, env, body, finally_clause):
4321         node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4322         node.cleanup_list = []
4323         return node
4324     create_analysed = staticmethod(create_analysed)
4325     
4326     def analyse_control_flow(self, env):
4327         env.start_branching(self.pos)
4328         self.body.analyse_control_flow(env)
4329         env.next_branch(self.body.end_pos())
4330         env.finish_branching(self.body.end_pos())
4331         self.finally_clause.analyse_control_flow(env)
4332
4333     def analyse_declarations(self, env):
4334         self.body.analyse_declarations(env)
4335         self.finally_clause.analyse_declarations(env)
4336     
4337     def analyse_expressions(self, env):
4338         self.body.analyse_expressions(env)
4339         self.cleanup_list = env.free_temp_entries[:]
4340         self.finally_clause.analyse_expressions(env)
4341
4342     gil_check = StatNode._gil_check
4343     gil_message = "Try-finally statement"
4344
4345     def generate_execution_code(self, code):
4346         old_error_label = code.error_label
4347         old_labels = code.all_new_labels()
4348         new_labels = code.get_all_labels()
4349         new_error_label = code.error_label
4350         catch_label = code.new_label()
4351         code.putln(
4352             "/*try:*/ {")
4353         if self.disallow_continue_in_try_finally:
4354             was_in_try_finally = code.funcstate.in_try_finally
4355             code.funcstate.in_try_finally = 1
4356         self.body.generate_execution_code(code)
4357         if self.disallow_continue_in_try_finally:
4358             code.funcstate.in_try_finally = was_in_try_finally
4359         code.putln(
4360             "}")
4361         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4362         code.putln(
4363             "/*finally:*/ {")
4364         cases_used = []
4365         error_label_used = 0
4366         for i, new_label in enumerate(new_labels):
4367             if new_label in code.labels_used:
4368                 cases_used.append(i)
4369                 if new_label == new_error_label:
4370                     error_label_used = 1
4371                     error_label_case = i
4372         if cases_used:
4373             code.putln(
4374                     "int __pyx_why;")
4375             if error_label_used and self.preserve_exception:
4376                 code.putln(
4377                     "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4378                 code.putln(
4379                     "int %s;" % Naming.exc_lineno_name)
4380                 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4381                 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4382                 code.putln(exc_var_init_zero)
4383             else:
4384                 exc_var_init_zero = None
4385             code.use_label(catch_label)
4386             code.putln(
4387                     "__pyx_why = 0; goto %s;" % catch_label)
4388             for i in cases_used:
4389                 new_label = new_labels[i]
4390                 #if new_label and new_label != "<try>":
4391                 if new_label == new_error_label and self.preserve_exception:
4392                     self.put_error_catcher(code, 
4393                         new_error_label, i+1, catch_label, temps_to_clean_up)
4394                 else:
4395                     code.put('%s: ' % new_label)
4396                     if exc_var_init_zero:
4397                         code.putln(exc_var_init_zero)
4398                     code.putln("__pyx_why = %s; goto %s;" % (
4399                             i+1,
4400                             catch_label))
4401             code.put_label(catch_label)
4402         code.set_all_labels(old_labels)
4403         if error_label_used:
4404             code.new_error_label()
4405             finally_error_label = code.error_label
4406         self.finally_clause.generate_execution_code(code)
4407         if error_label_used:
4408             if finally_error_label in code.labels_used and self.preserve_exception:
4409                 over_label = code.new_label()
4410                 code.put_goto(over_label);
4411                 code.put_label(finally_error_label)
4412                 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4413                 for var in Naming.exc_vars:
4414                     code.putln("Py_XDECREF(%s);" % var)
4415                 code.putln("}")
4416                 code.put_goto(old_error_label)
4417                 code.put_label(over_label)
4418             code.error_label = old_error_label
4419         if cases_used:
4420             code.putln(
4421                 "switch (__pyx_why) {")
4422             for i in cases_used:
4423                 old_label = old_labels[i]
4424                 if old_label == old_error_label and self.preserve_exception:
4425                     self.put_error_uncatcher(code, i+1, old_error_label)
4426                 else:
4427                     code.use_label(old_label)
4428                     code.putln(
4429                         "case %s: goto %s;" % (
4430                             i+1,
4431                             old_label))
4432             code.putln(
4433                 "}")
4434         code.putln(
4435             "}")
4436
4437     def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4438         code.globalstate.use_utility_code(restore_exception_utility_code)
4439         code.putln(
4440             "%s: {" %
4441                 error_label)
4442         code.putln(
4443                 "__pyx_why = %s;" %
4444                     i)
4445         code.put_var_xdecrefs_clear(self.cleanup_list)
4446         for temp_name, type in temps_to_clean_up:
4447             code.put_xdecref_clear(temp_name, type)
4448         code.putln(
4449                 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4450                     Naming.exc_vars)
4451         code.putln(
4452                 "%s = %s;" % (
4453                     Naming.exc_lineno_name, Naming.lineno_cname))
4454         #code.putln(
4455         #        "goto %s;" %
4456         #            catch_label)
4457         code.put_goto(catch_label)
4458         code.putln(
4459             "}")
4460             
4461     def put_error_uncatcher(self, code, i, error_label):
4462         code.globalstate.use_utility_code(restore_exception_utility_code)
4463         code.putln(
4464             "case %s: {" %
4465                 i)
4466         code.putln(
4467                 "__Pyx_ErrRestore(%s, %s, %s);" %
4468                     Naming.exc_vars)
4469         code.putln(
4470                 "%s = %s;" % (
4471                     Naming.lineno_cname, Naming.exc_lineno_name))
4472         for var in Naming.exc_vars:
4473             code.putln(
4474                 "%s = 0;" %
4475                     var)
4476         code.put_goto(error_label)
4477         code.putln(
4478             "}")
4479
4480     def annotate(self, code):
4481         self.body.annotate(code)
4482         self.finally_clause.annotate(code)
4483
4484
4485 class GILStatNode(TryFinallyStatNode):
4486     #  'with gil' or 'with nogil' statement
4487     #
4488     #   state   string   'gil' or 'nogil'
4489
4490 #    child_attrs = []
4491     
4492     preserve_exception = 0
4493
4494     def __init__(self, pos, state, body):
4495         self.state = state
4496         TryFinallyStatNode.__init__(self, pos,
4497             body = body,
4498             finally_clause = GILExitNode(pos, state = state))
4499
4500     def analyse_expressions(self, env):
4501         env.use_utility_code(force_init_threads_utility_code)
4502         was_nogil = env.nogil
4503         env.nogil = 1
4504         TryFinallyStatNode.analyse_expressions(self, env)
4505         env.nogil = was_nogil
4506
4507     def gil_check(self, env):
4508         pass
4509
4510     def generate_execution_code(self, code):
4511         code.mark_pos(self.pos)
4512         if self.state == 'gil':
4513             code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4514         else:
4515             code.putln("{ PyThreadState *_save;")
4516             code.putln("Py_UNBLOCK_THREADS")
4517         TryFinallyStatNode.generate_execution_code(self, code)
4518         code.putln("}")
4519
4520
4521 class GILExitNode(StatNode):
4522     #  Used as the 'finally' block in a GILStatNode
4523     #
4524     #  state   string   'gil' or 'nogil'
4525
4526     child_attrs = []
4527
4528     def analyse_expressions(self, env):
4529         pass
4530
4531     def generate_execution_code(self, code):
4532         if self.state == 'gil':
4533             code.putln("PyGILState_Release();")
4534         else:
4535             code.putln("Py_BLOCK_THREADS")
4536
4537
4538 class CImportStatNode(StatNode):
4539     #  cimport statement
4540     #
4541     #  module_name   string           Qualified name of module being imported
4542     #  as_name       string or None   Name specified in "as" clause, if any
4543
4544     child_attrs = []
4545     
4546     def analyse_declarations(self, env):
4547         if not env.is_module_scope:
4548             error(self.pos, "cimport only allowed at module level")
4549             return
4550         module_scope = env.find_module(self.module_name, self.pos)
4551         if "." in self.module_name:
4552             names = [EncodedString(name) for name in self.module_name.split(".")]
4553             top_name = names[0]
4554             top_module_scope = env.context.find_submodule(top_name)
4555             module_scope = top_module_scope
4556             for name in names[1:]:
4557                 submodule_scope = module_scope.find_submodule(name)
4558                 module_scope.declare_module(name, submodule_scope, self.pos)
4559                 module_scope = submodule_scope
4560             if self.as_name:
4561                 env.declare_module(self.as_name, module_scope, self.pos)
4562             else:
4563                 env.declare_module(top_name, top_module_scope, self.pos)
4564         else:
4565             name = self.as_name or self.module_name
4566             env.declare_module(name, module_scope, self.pos)
4567
4568     def analyse_expressions(self, env):
4569         pass
4570     
4571     def generate_execution_code(self, code):
4572         pass
4573     
4574
4575 class FromCImportStatNode(StatNode):
4576     #  from ... cimport statement
4577     #
4578     #  module_name     string                        Qualified name of module
4579     #  imported_names  [(pos, name, as_name, kind)]  Names to be imported
4580     
4581     child_attrs = []
4582
4583     def analyse_declarations(self, env):
4584         if not env.is_module_scope:
4585             error(self.pos, "cimport only allowed at module level")
4586             return
4587         module_scope = env.find_module(self.module_name, self.pos)
4588         env.add_imported_module(module_scope)
4589         for pos, name, as_name, kind in self.imported_names:
4590             if name == "*":
4591                 for local_name, entry in module_scope.entries.items():
4592                     env.add_imported_entry(local_name, entry, pos)
4593             else:
4594                 entry = module_scope.lookup(name)
4595                 if entry:
4596                     if kind and not self.declaration_matches(entry, kind):
4597                         entry.redeclared(pos)
4598                 else:
4599                     if kind == 'struct' or kind == 'union':
4600                         entry = module_scope.declare_struct_or_union(name,
4601                             kind = kind, scope = None, typedef_flag = 0, pos = pos)
4602                     elif kind == 'class':
4603                         entry = module_scope.declare_c_class(name, pos = pos,
4604                             module_name = self.module_name)
4605                     else:
4606                         error(pos, "Name '%s' not declared in module '%s'"
4607                             % (name, self.module_name))
4608                         
4609                 if entry:
4610                     local_name = as_name or name
4611                     env.add_imported_entry(local_name, entry, pos)
4612     
4613     def declaration_matches(self, entry, kind):
4614         if not entry.is_type:
4615             return 0
4616         type = entry.type
4617         if kind == 'class':
4618             if not type.is_extension_type:
4619                 return 0
4620         else:
4621             if not type.is_struct_or_union:
4622                 return 0
4623             if kind != type.kind:
4624                 return 0
4625         return 1
4626
4627     def analyse_expressions(self, env):
4628         pass
4629     
4630     def generate_execution_code(self, code):
4631         pass
4632
4633
4634 class FromImportStatNode(StatNode):
4635     #  from ... import statement
4636     #
4637     #  module           ImportNode
4638     #  items            [(string, NameNode)]
4639     #  interned_items   [(string, NameNode, ExprNode)]
4640     #  item             PyTempNode            used internally
4641     #  import_star      boolean               used internally
4642
4643     child_attrs = ["module"]
4644     import_star = 0
4645     
4646     def analyse_declarations(self, env):
4647         for name, target in self.items:
4648             if name == "*":
4649                 if not env.is_module_scope:
4650                     error(self.pos, "import * only allowed at module level")
4651                     return
4652                 env.has_import_star = 1
4653                 self.import_star = 1
4654             else:
4655                 target.analyse_target_declaration(env)
4656     
4657     def analyse_expressions(self, env):
4658         import ExprNodes
4659         self.module.analyse_expressions(env)
4660         self.item = ExprNodes.PyTempNode(self.pos, env)
4661         self.item.allocate_temp(env)
4662         self.interned_items = []
4663         for name, target in self.items:
4664             if name == '*':
4665                 for _, entry in env.entries.items():
4666                     if not entry.is_type and entry.type.is_extension_type:
4667                         env.use_utility_code(ExprNodes.type_test_utility_code)
4668                         break
4669             else:
4670                 entry =  env.lookup(target.name)
4671                 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4672                     continue # already cimported
4673                 target.analyse_target_expression(env, None)
4674                 if target.type is py_object_type:
4675                     coerced_item = None
4676                 else:
4677                     coerced_item = self.item.coerce_to(target.type, env)
4678                 self.interned_items.append(
4679                     (name, target, coerced_item))
4680                 #target.release_target_temp(env) # was release_temp ?!?
4681         self.module.release_temp(env)
4682         self.item.release_temp(env)
4683     
4684     def generate_execution_code(self, code):
4685         self.module.generate_evaluation_code(code)
4686         if self.import_star:
4687             code.putln(
4688                 'if (%s(%s) < 0) %s;' % (
4689                     Naming.import_star,
4690                     self.module.py_result(),
4691                     code.error_goto(self.pos)))
4692         for name, target, coerced_item in self.interned_items:
4693             cname = code.intern_identifier(name)
4694             code.putln(
4695                 '%s = PyObject_GetAttr(%s, %s); %s' % (
4696                     self.item.result(), 
4697                     self.module.py_result(),
4698                     cname,
4699                     code.error_goto_if_null(self.item.result(), self.pos)))
4700             code.put_gotref(self.item.py_result())
4701             if coerced_item is None:
4702                 target.generate_assignment_code(self.item, code)
4703             else:
4704                 coerced_item.allocate_temp_result(code)
4705                 coerced_item.generate_result_code(code)
4706                 target.generate_assignment_code(coerced_item, code)
4707                 if self.item.result() != coerced_item.result():
4708                     code.put_decref_clear(self.item.result(), self.item.type)
4709         self.module.generate_disposal_code(code)
4710         self.module.free_temps(code)
4711
4712
4713
4714 #------------------------------------------------------------------------------------
4715 #
4716 #  Runtime support code
4717 #
4718 #------------------------------------------------------------------------------------
4719
4720 utility_function_predeclarations = \
4721 """
4722 #ifdef __GNUC__
4723 #define INLINE __inline__
4724 #elif _WIN32
4725 #define INLINE __inline
4726 #else
4727 #define INLINE 
4728 #endif
4729
4730 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4731
4732 """ + """
4733
4734 static int %(skip_dispatch_cname)s = 0;
4735
4736 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4737
4738 if Options.gcc_branch_hints:
4739     branch_prediction_macros = \
4740     """
4741 #ifdef __GNUC__
4742 /* Test for GCC > 2.95 */
4743 #if __GNUC__ > 2 || \
4744               (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) 
4745 #define likely(x)   __builtin_expect(!!(x), 1)
4746 #define unlikely(x) __builtin_expect(!!(x), 0)
4747 #else /* __GNUC__ > 2 ... */
4748 #define likely(x)   (x)
4749 #define unlikely(x) (x)
4750 #endif /* __GNUC__ > 2 ... */
4751 #else /* __GNUC__ */
4752 #define likely(x)   (x)
4753 #define unlikely(x) (x)
4754 #endif /* __GNUC__ */
4755     """
4756 else:
4757     branch_prediction_macros = \
4758     """
4759 #define likely(x)   (x)
4760 #define unlikely(x) (x)
4761     """
4762
4763 #get_name_predeclaration = \
4764 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4765
4766 #get_name_interned_predeclaration = \
4767 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4768
4769 #------------------------------------------------------------------------------------
4770
4771 printing_utility_code = UtilityCode(
4772 proto = """
4773 static int __Pyx_Print(PyObject *, int); /*proto*/
4774 #if PY_MAJOR_VERSION >= 3
4775 static PyObject* %s = 0;
4776 static PyObject* %s = 0;
4777 #endif
4778 """ % (Naming.print_function, Naming.print_function_kwargs),
4779 impl = r"""
4780 #if PY_MAJOR_VERSION < 3
4781 static PyObject *__Pyx_GetStdout(void) {
4782     PyObject *f = PySys_GetObject((char *)"stdout");
4783     if (!f) {
4784         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4785     }
4786     return f;
4787 }
4788
4789 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4790     PyObject *f;
4791     PyObject* v;
4792     int i;
4793
4794     if (!(f = __Pyx_GetStdout()))
4795         return -1;
4796     for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4797         if (PyFile_SoftSpace(f, 1)) {
4798             if (PyFile_WriteString(" ", f) < 0)
4799                 return -1;
4800         }
4801         v = PyTuple_GET_ITEM(arg_tuple, i);
4802         if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4803             return -1;
4804         if (PyString_Check(v)) {
4805             char *s = PyString_AsString(v);
4806             Py_ssize_t len = PyString_Size(v);
4807             if (len > 0 &&
4808                 isspace(Py_CHARMASK(s[len-1])) &&
4809                 s[len-1] != ' ')
4810                     PyFile_SoftSpace(f, 0);
4811         }
4812     }
4813     if (newline) {
4814         if (PyFile_WriteString("\n", f) < 0)
4815             return -1;
4816         PyFile_SoftSpace(f, 0);
4817     }
4818     return 0;
4819 }
4820
4821 #else /* Python 3 has a print function */
4822
4823 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4824     PyObject* kwargs = 0;
4825     PyObject* result = 0;
4826     PyObject* end_string;
4827     if (!%(PRINT_FUNCTION)s) {
4828         %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4829         if (!%(PRINT_FUNCTION)s)
4830             return -1;
4831     }
4832     if (!newline) {
4833         if (!%(PRINT_KWARGS)s) {
4834             %(PRINT_KWARGS)s = PyDict_New();
4835             if (!%(PRINT_KWARGS)s)
4836                 return -1;
4837             end_string = PyUnicode_FromStringAndSize(" ", 1);
4838             if (!end_string)
4839                 return -1;
4840             if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4841                 Py_DECREF(end_string);
4842                 return -1;
4843             }
4844             Py_DECREF(end_string);
4845         }
4846         kwargs = %(PRINT_KWARGS)s;
4847     }
4848     result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4849     if (!result)
4850         return -1;
4851     Py_DECREF(result);
4852     return 0;
4853 }
4854
4855 #endif
4856 """ % {'BUILTINS'       : Naming.builtins_cname,
4857        'PRINT_FUNCTION' : Naming.print_function,
4858        'PRINT_KWARGS'   : Naming.print_function_kwargs}
4859 )
4860
4861
4862 printing_one_utility_code = UtilityCode(
4863 proto = """
4864 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4865 """,
4866 impl = r"""
4867 #if PY_MAJOR_VERSION < 3
4868
4869 static int __Pyx_PrintOne(PyObject *o) {
4870     PyObject *f;
4871     if (!(f = __Pyx_GetStdout()))
4872         return -1;
4873     if (PyFile_SoftSpace(f, 0)) {
4874         if (PyFile_WriteString(" ", f) < 0)
4875             return -1;
4876     }
4877     if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4878         return -1;
4879     if (PyFile_WriteString("\n", f) < 0)
4880         return -1;
4881     return 0;
4882     /* the line below is just to avoid compiler
4883      * compiler warnings about unused functions */
4884     return __Pyx_Print(NULL, 0);
4885 }
4886
4887 #else /* Python 3 has a print function */
4888
4889 static int __Pyx_PrintOne(PyObject *o) {
4890     int res;
4891     PyObject* arg_tuple = PyTuple_New(1);
4892     if (unlikely(!arg_tuple))
4893         return -1;
4894     Py_INCREF(o);
4895     PyTuple_SET_ITEM(arg_tuple, 0, o);
4896     res = __Pyx_Print(arg_tuple, 1);
4897     Py_DECREF(arg_tuple);
4898     return res;
4899 }
4900
4901 #endif
4902 """)
4903
4904
4905
4906 #------------------------------------------------------------------------------------
4907
4908 # The following function is based on do_raise() from ceval.c.
4909
4910 raise_utility_code = UtilityCode(
4911 proto = """
4912 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4913 """,
4914 impl = """
4915 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4916     Py_XINCREF(type);
4917     Py_XINCREF(value);
4918     Py_XINCREF(tb);
4919     /* First, check the traceback argument, replacing None with NULL. */
4920     if (tb == Py_None) {
4921         Py_DECREF(tb);
4922         tb = 0;
4923     }
4924     else if (tb != NULL && !PyTraceBack_Check(tb)) {
4925         PyErr_SetString(PyExc_TypeError,
4926             "raise: arg 3 must be a traceback or None");
4927         goto raise_error;
4928     }
4929     /* Next, replace a missing value with None */
4930     if (value == NULL) {
4931         value = Py_None;
4932         Py_INCREF(value);
4933     }
4934     #if PY_VERSION_HEX < 0x02050000
4935     if (!PyClass_Check(type))
4936     #else
4937     if (!PyType_Check(type))
4938     #endif
4939     {
4940         /* Raising an instance.  The value should be a dummy. */
4941         if (value != Py_None) {
4942             PyErr_SetString(PyExc_TypeError,
4943                 "instance exception may not have a separate value");
4944             goto raise_error;
4945         }
4946         /* Normalize to raise <class>, <instance> */
4947         Py_DECREF(value);
4948         value = type;
4949         #if PY_VERSION_HEX < 0x02050000
4950             if (PyInstance_Check(type)) {
4951                 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4952                 Py_INCREF(type);
4953             }
4954             else {
4955                 type = 0;
4956                 PyErr_SetString(PyExc_TypeError,
4957                     "raise: exception must be an old-style class or instance");
4958                 goto raise_error;
4959             }
4960         #else
4961             type = (PyObject*) Py_TYPE(type);
4962             Py_INCREF(type);
4963             if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4964                 PyErr_SetString(PyExc_TypeError,
4965                     "raise: exception class must be a subclass of BaseException");
4966                 goto raise_error;
4967             }
4968         #endif
4969     }
4970     __Pyx_ErrRestore(type, value, tb);
4971     return;
4972 raise_error:
4973     Py_XDECREF(value);
4974     Py_XDECREF(type);
4975     Py_XDECREF(tb);
4976     return;
4977 }
4978 """)
4979
4980 #------------------------------------------------------------------------------------
4981
4982 reraise_utility_code = UtilityCode(
4983 proto = """
4984 static void __Pyx_ReRaise(void); /*proto*/
4985 """,
4986 impl = """
4987 static void __Pyx_ReRaise(void) {
4988     PyThreadState *tstate = PyThreadState_GET();
4989     PyObject* tmp_type = tstate->curexc_type;
4990     PyObject* tmp_value = tstate->curexc_value;
4991     PyObject* tmp_tb = tstate->curexc_traceback;
4992     tstate->curexc_type = tstate->exc_type;
4993     tstate->curexc_value = tstate->exc_value;
4994     tstate->curexc_traceback = tstate->exc_traceback;
4995     tstate->exc_type = 0;
4996     tstate->exc_value = 0;
4997     tstate->exc_traceback = 0;
4998     Py_XDECREF(tmp_type);
4999     Py_XDECREF(tmp_value);
5000     Py_XDECREF(tmp_tb);
5001 }
5002 """)
5003
5004 #------------------------------------------------------------------------------------
5005
5006 arg_type_test_utility_code = UtilityCode(
5007 proto = """
5008 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5009     const char *name, int exact); /*proto*/
5010 """,
5011 impl = """
5012 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5013     const char *name, int exact)
5014 {
5015     if (!type) {
5016         PyErr_Format(PyExc_SystemError, "Missing type object");
5017         return 0;
5018     }
5019     if (none_allowed && obj == Py_None) return 1;
5020     else if (exact) {
5021         if (Py_TYPE(obj) == type) return 1;
5022     }
5023     else {
5024         if (PyObject_TypeCheck(obj, type)) return 1;
5025     }
5026     PyErr_Format(PyExc_TypeError,
5027         "Argument '%s' has incorrect type (expected %s, got %s)",
5028         name, type->tp_name, Py_TYPE(obj)->tp_name);
5029     return 0;
5030 }
5031 """)
5032
5033 #------------------------------------------------------------------------------------
5034 #
5035 #  __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5036 #  many or too few positional arguments were found.  This handles
5037 #  Py_ssize_t formatting correctly.
5038
5039 raise_argtuple_invalid_utility_code = UtilityCode(
5040 proto = """
5041 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5042     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5043 """,
5044 impl = """
5045 static void __Pyx_RaiseArgtupleInvalid(
5046     const char* func_name,
5047     int exact,
5048     Py_ssize_t num_min,
5049     Py_ssize_t num_max,
5050     Py_ssize_t num_found)
5051 {
5052     Py_ssize_t num_expected;
5053     const char *number, *more_or_less;
5054
5055     if (num_found < num_min) {
5056         num_expected = num_min;
5057         more_or_less = "at least";
5058     } else {
5059         num_expected = num_max;
5060         more_or_less = "at most";
5061     }
5062     if (exact) {
5063         more_or_less = "exactly";
5064     }
5065     number = (num_expected == 1) ? "" : "s";
5066     PyErr_Format(PyExc_TypeError,
5067         #if PY_VERSION_HEX < 0x02050000
5068             "%s() takes %s %d positional argument%s (%d given)",
5069         #else
5070             "%s() takes %s %zd positional argument%s (%zd given)",
5071         #endif
5072         func_name, more_or_less, num_expected, number, num_found);
5073 }
5074 """)
5075
5076 raise_keyword_required_utility_code = UtilityCode(
5077 proto = """
5078 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5079 """,
5080 impl = """
5081 static INLINE void __Pyx_RaiseKeywordRequired(
5082     const char* func_name,
5083     PyObject* kw_name)
5084 {
5085     PyErr_Format(PyExc_TypeError,
5086         #if PY_MAJOR_VERSION >= 3
5087         "%s() needs keyword-only argument %U", func_name, kw_name);
5088         #else
5089         "%s() needs keyword-only argument %s", func_name,
5090         PyString_AS_STRING(kw_name));
5091         #endif
5092 }
5093 """)
5094
5095 raise_double_keywords_utility_code = UtilityCode(
5096 proto = """
5097 static void __Pyx_RaiseDoubleKeywordsError(
5098     const char* func_name, PyObject* kw_name); /*proto*/
5099 """,
5100 impl = """
5101 static void __Pyx_RaiseDoubleKeywordsError(
5102     const char* func_name,
5103     PyObject* kw_name)
5104 {
5105     PyErr_Format(PyExc_TypeError,
5106         #if PY_MAJOR_VERSION >= 3
5107         "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5108         #else
5109         "%s() got multiple values for keyword argument '%s'", func_name,
5110         PyString_AS_STRING(kw_name));
5111         #endif
5112 }
5113 """)
5114
5115 #------------------------------------------------------------------------------------
5116 #
5117 #  __Pyx_CheckKeywordStrings raises an error if non-string keywords
5118 #  were passed to a function, or if any keywords were passed to a
5119 #  function that does not accept them.
5120
5121 keyword_string_check_utility_code = UtilityCode(
5122 proto = """
5123 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5124     const char* function_name, int kw_allowed); /*proto*/
5125 """,
5126 impl = """
5127 static INLINE int __Pyx_CheckKeywordStrings(
5128     PyObject *kwdict,
5129     const char* function_name,
5130     int kw_allowed)
5131 {
5132     PyObject* key = 0;
5133     Py_ssize_t pos = 0;
5134     while (PyDict_Next(kwdict, &pos, &key, 0)) {
5135         #if PY_MAJOR_VERSION < 3
5136         if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5137         #else
5138         if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5139         #endif
5140             goto invalid_keyword_type;
5141     }
5142     if ((!kw_allowed) && unlikely(key))
5143         goto invalid_keyword;
5144     return 1;
5145 invalid_keyword_type:
5146     PyErr_Format(PyExc_TypeError,
5147         "%s() keywords must be strings", function_name);
5148     return 0;
5149 invalid_keyword:
5150     PyErr_Format(PyExc_TypeError,
5151     #if PY_MAJOR_VERSION < 3
5152         "%s() got an unexpected keyword argument '%s'",
5153         function_name, PyString_AsString(key));
5154     #else
5155         "%s() got an unexpected keyword argument '%U'",
5156         function_name, key);
5157     #endif
5158     return 0;
5159 }
5160 """)
5161
5162 #------------------------------------------------------------------------------------
5163 #
5164 #  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5165 #  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
5166 #  keywords will raise an invalid keyword error.
5167 #
5168 #  Three kinds of errors are checked: 1) non-string keywords, 2)
5169 #  unexpected keywords and 3) overlap with positional arguments.
5170 #
5171 #  If num_posargs is greater 0, it denotes the number of positional
5172 #  arguments that were passed and that must therefore not appear
5173 #  amongst the keywords as well.
5174 #
5175 #  This method does not check for required keyword arguments.
5176 #
5177
5178 parse_keywords_utility_code = UtilityCode(
5179 proto = """
5180 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5181     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5182     const char* function_name); /*proto*/
5183 """,
5184 impl = """
5185 static int __Pyx_ParseOptionalKeywords(
5186     PyObject *kwds,
5187     PyObject **argnames[],
5188     PyObject *kwds2,
5189     PyObject *values[],
5190     Py_ssize_t num_pos_args,
5191     const char* function_name)
5192 {
5193     PyObject *key = 0, *value = 0;
5194     Py_ssize_t pos = 0;
5195     PyObject*** name;
5196     PyObject*** first_kw_arg = argnames + num_pos_args;
5197
5198     while (PyDict_Next(kwds, &pos, &key, &value)) {
5199         name = first_kw_arg;
5200         while (*name && (**name != key)) name++;
5201         if (*name) {
5202             values[name-argnames] = value;
5203         } else {
5204             #if PY_MAJOR_VERSION < 3
5205             if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5206             #else
5207             if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5208             #endif
5209                 goto invalid_keyword_type;
5210             } else {
5211                 for (name = first_kw_arg; *name; name++) {
5212                     #if PY_MAJOR_VERSION >= 3
5213                     if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5214                         PyUnicode_Compare(**name, key) == 0) break;
5215                     #else
5216                     if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5217                         _PyString_Eq(**name, key)) break;
5218                     #endif
5219                 }
5220                 if (*name) {
5221                     values[name-argnames] = value;
5222                 } else {
5223                     /* unexpected keyword found */
5224                     for (name=argnames; name != first_kw_arg; name++) {
5225                         if (**name == key) goto arg_passed_twice;
5226                         #if PY_MAJOR_VERSION >= 3
5227                         if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5228                             PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5229                         #else
5230                         if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5231                             _PyString_Eq(**name, key)) goto arg_passed_twice;
5232                         #endif
5233                     }
5234                     if (kwds2) {
5235                         if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5236                     } else {
5237                         goto invalid_keyword;
5238                     }
5239                 }
5240             }
5241         }
5242     }
5243     return 0;
5244 arg_passed_twice:
5245     __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5246     goto bad;
5247 invalid_keyword_type:
5248     PyErr_Format(PyExc_TypeError,
5249         "%s() keywords must be strings", function_name);
5250     goto bad;
5251 invalid_keyword:
5252     PyErr_Format(PyExc_TypeError,
5253     #if PY_MAJOR_VERSION < 3
5254         "%s() got an unexpected keyword argument '%s'",
5255         function_name, PyString_AsString(key));
5256     #else
5257         "%s() got an unexpected keyword argument '%U'",
5258         function_name, key);
5259     #endif
5260 bad:
5261     return -1;
5262 }
5263 """)
5264
5265 #------------------------------------------------------------------------------------
5266
5267 unraisable_exception_utility_code = UtilityCode(
5268 proto = """
5269 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5270 """,
5271 impl = """
5272 static void __Pyx_WriteUnraisable(const char *name) {
5273     PyObject *old_exc, *old_val, *old_tb;
5274     PyObject *ctx;
5275     __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5276     #if PY_MAJOR_VERSION < 3
5277     ctx = PyString_FromString(name);
5278     #else
5279     ctx = PyUnicode_FromString(name);
5280     #endif
5281     __Pyx_ErrRestore(old_exc, old_val, old_tb);
5282     if (!ctx) {
5283         PyErr_WriteUnraisable(Py_None);
5284     } else {
5285         PyErr_WriteUnraisable(ctx);
5286         Py_DECREF(ctx);
5287     }
5288 }
5289 """)
5290
5291 #------------------------------------------------------------------------------------
5292
5293 traceback_utility_code = UtilityCode(
5294 proto = """
5295 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5296 """,
5297 impl = """
5298 #include "compile.h"
5299 #include "frameobject.h"
5300 #include "traceback.h"
5301
5302 static void __Pyx_AddTraceback(const char *funcname) {
5303     PyObject *py_srcfile = 0;
5304     PyObject *py_funcname = 0;
5305     PyObject *py_globals = 0;
5306     PyObject *empty_string = 0;
5307     PyCodeObject *py_code = 0;
5308     PyFrameObject *py_frame = 0;
5309
5310     #if PY_MAJOR_VERSION < 3
5311     py_srcfile = PyString_FromString(%(FILENAME)s);
5312     #else
5313     py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5314     #endif
5315     if (!py_srcfile) goto bad;
5316     if (%(CLINENO)s) {
5317         #if PY_MAJOR_VERSION < 3
5318         py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5319         #else
5320         py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5321         #endif
5322     }
5323     else {
5324         #if PY_MAJOR_VERSION < 3
5325         py_funcname = PyString_FromString(funcname);
5326         #else
5327         py_funcname = PyUnicode_FromString(funcname);
5328         #endif
5329     }
5330     if (!py_funcname) goto bad;
5331     py_globals = PyModule_GetDict(%(GLOBALS)s);
5332     if (!py_globals) goto bad;
5333     #if PY_MAJOR_VERSION < 3
5334     empty_string = PyString_FromStringAndSize("", 0);
5335     #else
5336     empty_string = PyBytes_FromStringAndSize("", 0);
5337     #endif
5338     if (!empty_string) goto bad;
5339     py_code = PyCode_New(
5340         0,            /*int argcount,*/
5341         #if PY_MAJOR_VERSION >= 3
5342         0,            /*int kwonlyargcount,*/
5343         #endif
5344         0,            /*int nlocals,*/
5345         0,            /*int stacksize,*/
5346         0,            /*int flags,*/
5347         empty_string, /*PyObject *code,*/
5348         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
5349         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
5350         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
5351         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
5352         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
5353         py_srcfile,   /*PyObject *filename,*/
5354         py_funcname,  /*PyObject *name,*/
5355         %(LINENO)s,   /*int firstlineno,*/
5356         empty_string  /*PyObject *lnotab*/
5357     );
5358     if (!py_code) goto bad;
5359     py_frame = PyFrame_New(
5360         PyThreadState_GET(), /*PyThreadState *tstate,*/
5361         py_code,             /*PyCodeObject *code,*/
5362         py_globals,          /*PyObject *globals,*/
5363         0                    /*PyObject *locals*/
5364     );
5365     if (!py_frame) goto bad;
5366     py_frame->f_lineno = %(LINENO)s;
5367     PyTraceBack_Here(py_frame);
5368 bad:
5369     Py_XDECREF(py_srcfile);
5370     Py_XDECREF(py_funcname);
5371     Py_XDECREF(empty_string);
5372     Py_XDECREF(py_code);
5373     Py_XDECREF(py_frame);
5374 }
5375 """ % {
5376     'FILENAME': Naming.filename_cname,
5377     'LINENO':  Naming.lineno_cname,
5378     'CFILENAME': Naming.cfilenm_cname,
5379     'CLINENO':  Naming.clineno_cname,
5380     'GLOBALS': Naming.module_cname,
5381     'EMPTY_TUPLE' : Naming.empty_tuple,
5382 })
5383
5384 restore_exception_utility_code = UtilityCode(
5385 proto = """
5386 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5387 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5388 """,
5389 impl = """
5390 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5391     PyObject *tmp_type, *tmp_value, *tmp_tb;
5392     PyThreadState *tstate = PyThreadState_GET();
5393
5394 #if PY_MAJOR_VERSION >= 3
5395     /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5396     if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5397         tmp_type = tstate->exc_type;
5398         tmp_value = tstate->exc_value;
5399         tmp_tb = tstate->exc_traceback;
5400         PyErr_NormalizeException(&type, &value, &tb);
5401         PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5402         tstate->exc_type = 0;
5403         tstate->exc_value = 0;
5404         tstate->exc_traceback = 0;
5405         PyException_SetContext(value, tmp_value);
5406         Py_DECREF(tmp_type);
5407         Py_XDECREF(tmp_tb);
5408     }
5409 #endif
5410
5411     tmp_type = tstate->curexc_type;
5412     tmp_value = tstate->curexc_value;
5413     tmp_tb = tstate->curexc_traceback;
5414     tstate->curexc_type = type;
5415     tstate->curexc_value = value;
5416     tstate->curexc_traceback = tb;
5417     Py_XDECREF(tmp_type);
5418     Py_XDECREF(tmp_value);
5419     Py_XDECREF(tmp_tb);
5420 }
5421
5422 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5423     PyThreadState *tstate = PyThreadState_GET();
5424     *type = tstate->curexc_type;
5425     *value = tstate->curexc_value;
5426     *tb = tstate->curexc_traceback;
5427
5428     tstate->curexc_type = 0;
5429     tstate->curexc_value = 0;
5430     tstate->curexc_traceback = 0;
5431 }
5432
5433 """)
5434
5435 #------------------------------------------------------------------------------------
5436
5437 set_vtable_utility_code = UtilityCode(
5438 proto = """
5439 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5440 """,
5441 impl = """
5442 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5443     PyObject *pycobj = 0;
5444     int result;
5445     
5446     pycobj = PyCObject_FromVoidPtr(vtable, 0);
5447     if (!pycobj)
5448         goto bad;
5449     if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5450         goto bad;
5451     result = 0;
5452     goto done;
5453
5454 bad:
5455     result = -1;
5456 done:
5457     Py_XDECREF(pycobj);
5458     return result;
5459 }
5460 """)
5461
5462 #------------------------------------------------------------------------------------
5463
5464 get_vtable_utility_code = UtilityCode(
5465 proto = """
5466 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5467 """,
5468 impl = r"""
5469 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5470     int result;
5471     PyObject *pycobj;
5472
5473     pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5474     if (!pycobj)
5475         goto bad;
5476     *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5477     if (!*(void **)vtabptr)
5478         goto bad;
5479     result = 0;
5480     goto done;
5481
5482 bad:
5483     result = -1;
5484 done:
5485     Py_XDECREF(pycobj);
5486     return result;
5487 }
5488 """)
5489
5490 #------------------------------------------------------------------------------------
5491
5492 init_string_tab_utility_code = UtilityCode(
5493 proto = """
5494 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5495 """,
5496 impl = """
5497 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5498     while (t->p) {
5499         #if PY_MAJOR_VERSION < 3
5500         if (t->is_unicode && (!t->is_identifier)) {
5501             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5502         } else if (t->intern) {
5503             *t->p = PyString_InternFromString(t->s);
5504         } else {
5505             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5506         }
5507         #else  /* Python 3+ has unicode identifiers */
5508         if (t->is_identifier || (t->is_unicode && t->intern)) {
5509             *t->p = PyUnicode_InternFromString(t->s);
5510         } else if (t->is_unicode) {
5511             *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5512         } else {
5513             *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5514         }
5515         #endif
5516         if (!*t->p)
5517             return -1;
5518         ++t;
5519     }
5520     return 0;
5521 }
5522 """)
5523
5524 #------------------------------------------------------------------------------------
5525
5526 get_exception_utility_code = UtilityCode(
5527 proto = """
5528 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5529 """,
5530 impl = """
5531 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5532     PyObject *tmp_type, *tmp_value, *tmp_tb;
5533     PyThreadState *tstate = PyThreadState_GET();
5534     __Pyx_ErrFetch(type, value, tb);
5535     PyErr_NormalizeException(type, value, tb);
5536     if (PyErr_Occurred())
5537         goto bad;
5538     Py_INCREF(*type);
5539     Py_INCREF(*value);
5540     Py_INCREF(*tb);
5541     tmp_type = tstate->exc_type;
5542     tmp_value = tstate->exc_value;
5543     tmp_tb = tstate->exc_traceback;
5544     tstate->exc_type = *type;
5545     tstate->exc_value = *value;
5546     tstate->exc_traceback = *tb;
5547     /* Make sure tstate is in a consistent state when we XDECREF
5548     these objects (XDECREF may run arbitrary code). */
5549     Py_XDECREF(tmp_type);
5550     Py_XDECREF(tmp_value);
5551     Py_XDECREF(tmp_tb);
5552     return 0;
5553 bad:
5554     Py_XDECREF(*type);
5555     Py_XDECREF(*value);
5556     Py_XDECREF(*tb);
5557     return -1;
5558 }
5559
5560 """)
5561
5562 #------------------------------------------------------------------------------------
5563
5564 reset_exception_utility_code = UtilityCode(
5565 proto = """
5566 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5567 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5568 """,
5569 impl = """
5570 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5571     PyThreadState *tstate = PyThreadState_GET();
5572     *type = tstate->exc_type;
5573     *value = tstate->exc_value;
5574     *tb = tstate->exc_traceback;
5575     Py_XINCREF(*type);
5576     Py_XINCREF(*value);
5577     Py_XINCREF(*tb);
5578 }
5579
5580 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5581     PyObject *tmp_type, *tmp_value, *tmp_tb;
5582     PyThreadState *tstate = PyThreadState_GET();
5583     tmp_type = tstate->exc_type;
5584     tmp_value = tstate->exc_value;
5585     tmp_tb = tstate->exc_traceback;
5586     tstate->exc_type = type;
5587     tstate->exc_value = value;
5588     tstate->exc_traceback = tb;
5589     Py_XDECREF(tmp_type);
5590     Py_XDECREF(tmp_value);
5591     Py_XDECREF(tmp_tb);
5592 }
5593 """)
5594
5595 #------------------------------------------------------------------------------------
5596
5597 force_init_threads_utility_code = UtilityCode(
5598 proto="""
5599 #ifndef __PYX_FORCE_INIT_THREADS
5600 #if PY_VERSION_HEX < 0x02040200
5601 #define __PYX_FORCE_INIT_THREADS 1
5602 #else
5603 #define __PYX_FORCE_INIT_THREADS 0
5604 #endif
5605 #endif
5606 """)
5607
5608 #------------------------------------------------------------------------------------