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