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