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