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