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