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