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