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