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