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