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     #
2481     #  The following subnodes are constructed internally:
2482     #
2483     #  dict     DictNode   Class dictionary
2484     #  classobj ClassNode  Class object
2485     #  target   NameNode   Variable to assign class object to
2486
2487     child_attrs = ["body", "dict", "classobj", "target"]
2488     
2489     def __init__(self, pos, name, bases, doc, body):
2490         StatNode.__init__(self, pos)
2491         self.name = name
2492         self.doc = doc
2493         self.body = body
2494         import ExprNodes
2495         self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2496         if self.doc and Options.docstrings:
2497             doc = embed_position(self.pos, self.doc)
2498             doc_node = ExprNodes.StringNode(pos, value = doc)
2499         else:
2500             doc_node = None
2501         self.classobj = ExprNodes.ClassNode(pos, name = name,
2502             bases = bases, dict = self.dict, doc = doc_node)
2503         self.target = ExprNodes.NameNode(pos, name = name)
2504         
2505     def as_cclass(self):
2506         """
2507         Return this node as if it were declared as an extension class
2508         """
2509         bases = self.classobj.bases.args
2510         if len(bases) == 0:
2511             base_class_name = None
2512             base_class_module = None
2513         elif len(bases) == 1:
2514             base = bases[0]
2515             path = []
2516             from ExprNodes import AttributeNode, NameNode
2517             while isinstance(base, AttributeNode):
2518                 path.insert(0, base.attribute)
2519                 base = base.obj
2520             if isinstance(base, NameNode):
2521                 path.insert(0, base.name)
2522                 base_class_name = path[-1]
2523                 if len(path) > 1:
2524                     base_class_module = u'.'.join(path[:-1])
2525                 else:
2526                     base_class_module = None
2527             else:
2528                 error(self.classobj.bases.args.pos, "Invalid base class")
2529         else:
2530             error(self.classobj.bases.args.pos, "C class may only have one base class")
2531             return None
2532         
2533         return CClassDefNode(self.pos, 
2534                              visibility = 'private',
2535                              module_name = None,
2536                              class_name = self.name,
2537                              base_class_module = base_class_module,
2538                              base_class_name = base_class_name,
2539                              body = self.body,
2540                              in_pxd = False,
2541                              doc = self.doc)
2542         
2543     def create_scope(self, env):
2544         genv = env
2545         while env.is_py_class_scope or env.is_c_class_scope:
2546             env = env.outer_scope
2547         cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2548         return cenv
2549     
2550     def analyse_declarations(self, env):
2551         self.target.analyse_target_declaration(env)
2552         cenv = self.create_scope(env)
2553         cenv.directives = env.directives
2554         cenv.class_obj_cname = self.target.entry.cname
2555         self.body.analyse_declarations(cenv)
2556     
2557     def analyse_expressions(self, env):
2558         self.dict.analyse_expressions(env)
2559         self.classobj.analyse_expressions(env)
2560         genv = env.global_scope()
2561         cenv = self.scope
2562         self.body.analyse_expressions(cenv)
2563         self.target.analyse_target_expression(env, self.classobj)
2564     
2565     def generate_function_definitions(self, env, code):
2566         self.body.generate_function_definitions(self.scope, code)
2567     
2568     def generate_execution_code(self, code):
2569         code.pyclass_stack.append(self)
2570         cenv = self.scope
2571         self.dict.generate_evaluation_code(code)
2572         self.classobj.generate_evaluation_code(code)
2573         cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2574         self.body.generate_execution_code(code)
2575         self.target.generate_assignment_code(self.classobj, code)
2576         self.dict.generate_disposal_code(code)
2577         self.dict.free_temps(code)
2578         code.pyclass_stack.pop()
2579
2580
2581 class CClassDefNode(ClassDefNode):
2582     #  An extension type definition.
2583     #
2584     #  visibility         'private' or 'public' or 'extern'
2585     #  typedef_flag       boolean
2586     #  api                boolean
2587     #  module_name        string or None    For import of extern type objects
2588     #  class_name         string            Unqualified name of class
2589     #  as_name            string or None    Name to declare as in this scope
2590     #  base_class_module  string or None    Module containing the base class
2591     #  base_class_name    string or None    Name of the base class
2592     #  objstruct_name     string or None    Specified C name of object struct
2593     #  typeobj_name       string or None    Specified C name of type object
2594     #  in_pxd             boolean           Is in a .pxd file
2595     #  doc                string or None
2596     #  body               StatNode or None
2597     #  entry              Symtab.Entry
2598     #  base_type          PyExtensionType or None
2599     #  buffer_defaults_node DictNode or None Declares defaults for a buffer
2600     #  buffer_defaults_pos
2601
2602     child_attrs = ["body"]
2603     buffer_defaults_node = None
2604     buffer_defaults_pos = None
2605     typedef_flag = False
2606     api = False
2607     objstruct_name = None
2608     typeobj_name = None
2609
2610     def analyse_declarations(self, env):
2611         #print "CClassDefNode.analyse_declarations:", self.class_name
2612         #print "...visibility =", self.visibility
2613         #print "...module_name =", self.module_name
2614
2615         import Buffer
2616         if self.buffer_defaults_node:
2617             buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2618                                                             env, [], self.buffer_defaults_node,
2619                                                             need_complete=False)
2620         else:
2621             buffer_defaults = None
2622
2623         if env.in_cinclude and not self.objstruct_name:
2624             error(self.pos, "Object struct name specification required for "
2625                 "C class defined in 'extern from' block")
2626         self.base_type = None
2627         # Now that module imports are cached, we need to 
2628         # import the modules for extern classes. 
2629         if self.module_name:
2630             self.module = None
2631             for module in env.cimported_modules:
2632                 if module.name == self.module_name:
2633                     self.module = module
2634             if self.module is None:
2635                 self.module = ModuleScope(self.module_name, None, env.context)
2636                 self.module.has_extern_class = 1
2637                 env.add_imported_module(self.module)
2638
2639         if self.base_class_name:
2640             if self.base_class_module:
2641                 base_class_scope = env.find_module(self.base_class_module, self.pos)
2642             else:
2643                 base_class_scope = env
2644             if self.base_class_name == 'object':
2645                 # extension classes are special and don't need to inherit from object
2646                 if base_class_scope is None or base_class_scope.lookup('object') is None:
2647                     self.base_class_name = None
2648                     self.base_class_module = None
2649                     base_class_scope = None
2650             if base_class_scope:
2651                 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2652                 if base_class_entry:
2653                     if not base_class_entry.is_type:
2654                         error(self.pos, "'%s' is not a type name" % self.base_class_name)
2655                     elif not base_class_entry.type.is_extension_type:
2656                         error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2657                     elif not base_class_entry.type.is_complete():
2658                         error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2659                     else:
2660                         self.base_type = base_class_entry.type
2661         has_body = self.body is not None
2662         if self.module_name and self.visibility != 'extern':
2663             module_path = self.module_name.split(".")
2664             home_scope = env.find_imported_module(module_path, self.pos)
2665             if not home_scope:
2666                 return
2667         else:
2668             home_scope = env
2669
2670         if self.visibility == 'extern':
2671             if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2672                 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2673
2674         self.entry = home_scope.declare_c_class(
2675             name = self.class_name, 
2676             pos = self.pos,
2677             defining = has_body and self.in_pxd,
2678             implementing = has_body and not self.in_pxd,
2679             module_name = self.module_name,
2680             base_type = self.base_type,
2681             objstruct_cname = self.objstruct_name,
2682             typeobj_cname = self.typeobj_name,
2683             visibility = self.visibility,
2684             typedef_flag = self.typedef_flag,
2685             api = self.api,
2686             buffer_defaults = buffer_defaults)
2687         if home_scope is not env and self.visibility == 'extern':
2688             env.add_imported_entry(self.class_name, self.entry, pos)
2689         scope = self.entry.type.scope
2690         if scope is not None:
2691             scope.directives = env.directives
2692
2693         if self.doc and Options.docstrings:
2694             scope.doc = embed_position(self.pos, self.doc)
2695             
2696         if has_body:
2697             self.body.analyse_declarations(scope)
2698             if self.in_pxd:
2699                 scope.defined = 1
2700             else:
2701                 scope.implemented = 1
2702         env.allocate_vtable_names(self.entry)
2703         
2704     def analyse_expressions(self, env):
2705         if self.body:
2706             scope = self.entry.type.scope
2707             self.body.analyse_expressions(scope)
2708     
2709     def generate_function_definitions(self, env, code):
2710         if self.body:
2711             self.body.generate_function_definitions(
2712                 self.entry.type.scope, code)
2713     
2714     def generate_execution_code(self, code):
2715         # This is needed to generate evaluation code for
2716         # default values of method arguments.
2717         if self.body:
2718             self.body.generate_execution_code(code)
2719             
2720     def annotate(self, code):
2721         if self.body:
2722             self.body.annotate(code)
2723
2724
2725 class PropertyNode(StatNode):
2726     #  Definition of a property in an extension type.
2727     #
2728     #  name   string
2729     #  doc    EncodedString or None    Doc string
2730     #  body   StatListNode
2731     
2732     child_attrs = ["body"]
2733
2734     def analyse_declarations(self, env):
2735         entry = env.declare_property(self.name, self.doc, self.pos)
2736         if entry:
2737             entry.scope.directives = env.directives
2738             self.body.analyse_declarations(entry.scope)
2739
2740     def analyse_expressions(self, env):
2741         self.body.analyse_expressions(env)
2742     
2743     def generate_function_definitions(self, env, code):
2744         self.body.generate_function_definitions(env, code)
2745
2746     def generate_execution_code(self, code):
2747         pass
2748
2749     def annotate(self, code):
2750         self.body.annotate(code)
2751
2752
2753 class GlobalNode(StatNode):
2754     # Global variable declaration.
2755     #
2756     # names    [string]
2757     
2758     child_attrs = []
2759
2760     def analyse_declarations(self, env):
2761         for name in self.names:
2762             env.declare_global(name, self.pos)
2763
2764     def analyse_expressions(self, env):
2765         pass
2766     
2767     def generate_execution_code(self, code):
2768         pass
2769
2770
2771 class ExprStatNode(StatNode):
2772     #  Expression used as a statement.
2773     #
2774     #  expr   ExprNode
2775
2776     child_attrs = ["expr"]
2777     
2778     def analyse_declarations(self, env):
2779         import ExprNodes
2780         if isinstance(self.expr, ExprNodes.GeneralCallNode):
2781             func = self.expr.function.as_cython_attribute()
2782             if func == u'declare':
2783                 args, kwds = self.expr.explicit_args_kwds()
2784                 if len(args):
2785                     error(self.expr.pos, "Variable names must be specified.")
2786                 for var, type_node in kwds.key_value_pairs:
2787                     type = type_node.analyse_as_type(env)
2788                     if type is None:
2789                         error(type_node.pos, "Unknown type")
2790                     else:
2791                         env.declare_var(var.value, type, var.pos, is_cdef = True)
2792                 self.__class__ = PassStatNode
2793     
2794     def analyse_expressions(self, env):
2795         self.expr.analyse_expressions(env)
2796     
2797     def generate_execution_code(self, code):
2798         self.expr.generate_evaluation_code(code)
2799         if not self.expr.is_temp and self.expr.result():
2800             code.putln("%s;" % self.expr.result())
2801         self.expr.generate_disposal_code(code)
2802         self.expr.free_temps(code)
2803
2804     def annotate(self, code):
2805         self.expr.annotate(code)
2806
2807
2808 class AssignmentNode(StatNode):
2809     #  Abstract base class for assignment nodes.
2810     #
2811     #  The analyse_expressions and generate_execution_code
2812     #  phases of assignments are split into two sub-phases
2813     #  each, to enable all the right hand sides of a
2814     #  parallel assignment to be evaluated before assigning
2815     #  to any of the left hand sides.
2816
2817     def analyse_expressions(self, env):
2818         self.analyse_types(env)
2819
2820 #       def analyse_expressions(self, env):
2821 #           self.analyse_expressions_1(env)
2822 #           self.analyse_expressions_2(env)
2823
2824     def generate_execution_code(self, code):
2825         self.generate_rhs_evaluation_code(code)
2826         self.generate_assignment_code(code)
2827         
2828
2829 class SingleAssignmentNode(AssignmentNode):
2830     #  The simplest case:
2831     #
2832     #    a = b
2833     #
2834     #  lhs      ExprNode      Left hand side
2835     #  rhs      ExprNode      Right hand side
2836     #  first    bool          Is this guaranteed the first assignment to lhs?
2837     
2838     child_attrs = ["lhs", "rhs"]
2839     first = False
2840     declaration_only = False
2841
2842     def analyse_declarations(self, env):
2843         import ExprNodes
2844         
2845         # handle declarations of the form x = cython.foo()
2846         if isinstance(self.rhs, ExprNodes.CallNode):
2847             func_name = self.rhs.function.as_cython_attribute()
2848             if func_name:
2849                 args, kwds = self.rhs.explicit_args_kwds()
2850                 
2851                 if func_name in ['declare', 'typedef']:
2852                     if len(args) > 2 or kwds is not None:
2853                         error(rhs.pos, "Can only declare one type at a time.")
2854                         return
2855                     type = args[0].analyse_as_type(env)
2856                     if type is None:
2857                         error(args[0].pos, "Unknown type")
2858                         return
2859                     lhs = self.lhs
2860                     if func_name == 'declare':
2861                         if isinstance(lhs, ExprNodes.NameNode):
2862                             vars = [(lhs.name, lhs.pos)]
2863                         elif isinstance(lhs, ExprNodes.TupleNode):
2864                             vars = [(var.name, var.pos) for var in lhs.args]
2865                         else:
2866                             error(lhs.pos, "Invalid declaration")
2867                             return
2868                         for var, pos in vars:
2869                             env.declare_var(var, type, pos, is_cdef = True)
2870                         if len(args) == 2:
2871                             # we have a value
2872                             self.rhs = args[1]
2873                         else:
2874                             self.declaration_only = True
2875                     else:
2876                         self.declaration_only = True
2877                         if not isinstance(lhs, ExprNodes.NameNode):
2878                             error(lhs.pos, "Invalid declaration.")
2879                         env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2880                     
2881                 elif func_name in ['struct', 'union']:
2882                     self.declaration_only = True
2883                     if len(args) > 0 or kwds is None:
2884                         error(rhs.pos, "Struct or union members must be given by name.")
2885                         return
2886                     members = []
2887                     for member, type_node in kwds.key_value_pairs:
2888                         type = type_node.analyse_as_type(env)
2889                         if type is None:
2890                             error(type_node.pos, "Unknown type")
2891                         else:
2892                             members.append((member.value, type, member.pos))
2893                     if len(members) < len(kwds.key_value_pairs):
2894                         return
2895                     if not isinstance(self.lhs, ExprNodes.NameNode):
2896                         error(self.lhs.pos, "Invalid declaration.")
2897                     name = self.lhs.name
2898                     scope = StructOrUnionScope(name)
2899                     env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2900                     for member, type, pos in members:
2901                         scope.declare_var(member, type, pos)
2902                     
2903         if self.declaration_only:
2904             return
2905         else:
2906             self.lhs.analyse_target_declaration(env)
2907     
2908     def analyse_types(self, env, use_temp = 0):
2909         self.rhs.analyse_types(env)
2910         self.lhs.analyse_target_types(env)
2911         self.lhs.gil_assignment_check(env)
2912         self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2913         if use_temp:
2914             self.rhs = self.rhs.coerce_to_temp(env)
2915     
2916     def generate_rhs_evaluation_code(self, code):
2917         self.rhs.generate_evaluation_code(code)
2918     
2919     def generate_assignment_code(self, code):
2920         self.lhs.generate_assignment_code(self.rhs, code)
2921
2922     def annotate(self, code):
2923         self.lhs.annotate(code)
2924         self.rhs.annotate(code)
2925
2926
2927 class CascadedAssignmentNode(AssignmentNode):
2928     #  An assignment with multiple left hand sides:
2929     #
2930     #    a = b = c
2931     #
2932     #  lhs_list   [ExprNode]   Left hand sides
2933     #  rhs        ExprNode     Right hand sides
2934     #
2935     #  Used internally:
2936     #
2937     #  coerced_rhs_list   [ExprNode]   RHS coerced to type of each LHS
2938     
2939     child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2940     coerced_rhs_list = None
2941
2942     def analyse_declarations(self, env):
2943         for lhs in self.lhs_list:
2944             lhs.analyse_target_declaration(env)
2945     
2946     def analyse_types(self, env, use_temp = 0):
2947         self.rhs.analyse_types(env)
2948         if use_temp:
2949             self.rhs = self.rhs.coerce_to_temp(env)
2950         else:
2951             self.rhs = self.rhs.coerce_to_simple(env)
2952         from ExprNodes import CloneNode
2953         self.coerced_rhs_list = []
2954         for lhs in self.lhs_list:
2955             lhs.analyse_target_types(env)
2956             lhs.gil_assignment_check(env)
2957             rhs = CloneNode(self.rhs)
2958             rhs = rhs.coerce_to(lhs.type, env)
2959             self.coerced_rhs_list.append(rhs)
2960
2961     def generate_rhs_evaluation_code(self, code):
2962         self.rhs.generate_evaluation_code(code)
2963     
2964     def generate_assignment_code(self, code):
2965         for i in range(len(self.lhs_list)):
2966             lhs = self.lhs_list[i]
2967             rhs = self.coerced_rhs_list[i]
2968             rhs.generate_evaluation_code(code)
2969             lhs.generate_assignment_code(rhs, code)
2970             # Assignment has disposed of the cloned RHS
2971         self.rhs.generate_disposal_code(code)
2972         self.rhs.free_temps(code)
2973
2974     def annotate(self, code):
2975         for i in range(len(self.lhs_list)):
2976             lhs = self.lhs_list[i].annotate(code)
2977             rhs = self.coerced_rhs_list[i].annotate(code)
2978         self.rhs.annotate(code)
2979         
2980
2981 class ParallelAssignmentNode(AssignmentNode):
2982     #  A combined packing/unpacking assignment:
2983     #
2984     #    a, b, c =  d, e, f
2985     #
2986     #  This has been rearranged by the parser into
2987     #
2988     #    a = d ; b = e ; c = f
2989     #
2990     #  but we must evaluate all the right hand sides
2991     #  before assigning to any of the left hand sides.
2992     #
2993     #  stats     [AssignmentNode]   The constituent assignments
2994     
2995     child_attrs = ["stats"]
2996
2997     def analyse_declarations(self, env):
2998         for stat in self.stats:
2999             stat.analyse_declarations(env)
3000     
3001     def analyse_expressions(self, env):
3002         for stat in self.stats:
3003             stat.analyse_types(env, use_temp = 1)
3004
3005 #    def analyse_expressions(self, env):
3006 #        for stat in self.stats:
3007 #            stat.analyse_expressions_1(env, use_temp = 1)
3008 #        for stat in self.stats:
3009 #            stat.analyse_expressions_2(env)
3010     
3011     def generate_execution_code(self, code):
3012         for stat in self.stats:
3013             stat.generate_rhs_evaluation_code(code)
3014         for stat in self.stats:
3015             stat.generate_assignment_code(code)
3016
3017     def annotate(self, code):
3018         for stat in self.stats:
3019             stat.annotate(code)
3020
3021
3022 class InPlaceAssignmentNode(AssignmentNode):
3023     #  An in place arithmatic operand:
3024     #
3025     #    a += b
3026     #    a -= b
3027     #    ...
3028     #
3029     #  lhs      ExprNode      Left hand side
3030     #  rhs      ExprNode      Right hand side
3031     #  op       char          one of "+-*/%^&|"
3032     #  dup     (ExprNode)     copy of lhs used for operation (auto-generated)
3033     #
3034     #  This code is a bit tricky because in order to obey Python 
3035     #  semantics the sub-expressions (e.g. indices) of the lhs must 
3036     #  not be evaluated twice. So we must re-use the values calculated 
3037     #  in evaluation phase for the assignment phase as well. 
3038     #  Fortunately, the type of the lhs node is fairly constrained 
3039     #  (it must be a NameNode, AttributeNode, or IndexNode).     
3040     
3041     child_attrs = ["lhs", "rhs"]
3042     dup = None
3043
3044     def analyse_declarations(self, env):
3045         self.lhs.analyse_target_declaration(env)
3046         
3047     def analyse_types(self, env):
3048         self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3049         self.rhs.analyse_types(env)
3050         self.lhs.analyse_target_types(env)
3051         if Options.incref_local_binop and self.dup.type.is_pyobject:
3052             self.dup = self.dup.coerce_to_temp(env)
3053         import ExprNodes
3054         if self.lhs.type.is_pyobject:
3055             self.rhs = self.rhs.coerce_to_pyobject(env)
3056         elif self.rhs.type.is_pyobject:
3057             self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3058         if self.lhs.type.is_pyobject:
3059             self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3060             self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3061         
3062     def generate_execution_code(self, code):
3063         import ExprNodes
3064         self.rhs.generate_evaluation_code(code)
3065         self.dup.generate_subexpr_evaluation_code(code)
3066         if self.dup.is_temp:
3067             self.dup.allocate_temp_result(code)
3068         # self.dup.generate_result_code is run only if it is not buffer access
3069         if self.operator == "**":
3070             extra = ", Py_None"
3071         else:
3072             extra = ""
3073         if self.lhs.type.is_pyobject:
3074             if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3075                 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3076             self.dup.generate_result_code(code)
3077             self.result_value_temp.allocate(code)
3078             code.putln(
3079                 "%s = %s(%s, %s%s); %s" % (
3080                     self.result_value.result(), 
3081                     self.py_operation_function(), 
3082                     self.dup.py_result(),
3083                     self.rhs.py_result(),
3084                     extra,
3085                     code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3086             code.put_gotref(self.result_value.py_result())
3087             self.result_value.generate_evaluation_code(code) # May be a type check...
3088             self.rhs.generate_disposal_code(code)
3089             self.rhs.free_temps(code)
3090             self.dup.generate_disposal_code(code)
3091             self.dup.free_temps(code)
3092             self.lhs.generate_assignment_code(self.result_value, code)
3093             self.result_value_temp.release(code)
3094         else: 
3095             c_op = self.operator
3096             if c_op == "//":
3097                 c_op = "/"
3098             elif c_op == "**":
3099                 error(self.pos, "No C inplace power operator")
3100             elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3101                 error(self.pos, "Inplace operators not implemented for complex types.")
3102                 
3103             # have to do assignment directly to avoid side-effects
3104             if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3105                 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3106             else:
3107                 self.dup.generate_result_code(code)
3108                 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3109             self.rhs.generate_disposal_code(code)
3110             self.rhs.free_temps(code)
3111         if self.dup.is_temp:
3112             self.dup.generate_subexpr_disposal_code(code)
3113             self.dup.free_subexpr_temps(code)
3114             
3115     def create_dup_node(self, env): 
3116         import ExprNodes
3117         self.dup = self.lhs
3118         self.dup.analyse_types(env)
3119         if isinstance(self.lhs, ExprNodes.NameNode):
3120             target_lhs = ExprNodes.NameNode(self.dup.pos,
3121                                             name = self.dup.name,
3122                                             is_temp = self.dup.is_temp,
3123                                             entry = self.dup.entry)
3124         elif isinstance(self.lhs, ExprNodes.AttributeNode):
3125             target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3126                                                  obj = ExprNodes.CloneNode(self.lhs.obj),
3127                                                  attribute = self.dup.attribute,
3128                                                  is_temp = self.dup.is_temp)
3129         elif isinstance(self.lhs, ExprNodes.IndexNode):
3130             if self.lhs.index:
3131                 index = ExprNodes.CloneNode(self.lhs.index)
3132             else:
3133                 index = None
3134             if self.lhs.indices:
3135                 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3136             else:
3137                 indices = []
3138             target_lhs = ExprNodes.IndexNode(self.dup.pos,
3139                                              base = ExprNodes.CloneNode(self.dup.base),
3140                                              index = index,
3141                                              indices = indices,
3142                                              is_temp = self.dup.is_temp)
3143         else:
3144             assert False
3145         self.lhs = target_lhs
3146         return self.dup
3147     
3148     def py_operation_function(self):
3149         return self.py_functions[self.operator]
3150
3151     py_functions = {
3152         "|":        "PyNumber_InPlaceOr",
3153         "^":        "PyNumber_InPlaceXor",
3154         "&":        "PyNumber_InPlaceAnd",
3155         "+":        "PyNumber_InPlaceAdd",
3156         "-":        "PyNumber_InPlaceSubtract",
3157         "*":        "PyNumber_InPlaceMultiply",
3158         "/":        "PyNumber_InPlaceDivide",
3159         "%":        "PyNumber_InPlaceRemainder",
3160         "<<":        "PyNumber_InPlaceLshift",
3161         ">>":        "PyNumber_InPlaceRshift",
3162         "**":        "PyNumber_InPlacePower",
3163         "//":        "PyNumber_InPlaceFloorDivide",
3164     }
3165
3166     def annotate(self, code):
3167         self.lhs.annotate(code)
3168         self.rhs.annotate(code)
3169         self.dup.annotate(code)
3170
3171
3172 class PrintStatNode(StatNode):
3173     #  print statement
3174     #
3175     #  arg_tuple         TupleNode
3176     #  append_newline    boolean
3177
3178     child_attrs = ["arg_tuple"]
3179
3180     def analyse_expressions(self, env):
3181         self.arg_tuple.analyse_expressions(env)
3182         self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3183         env.use_utility_code(printing_utility_code)
3184         if len(self.arg_tuple.args) == 1 and self.append_newline:
3185             env.use_utility_code(printing_one_utility_code)
3186
3187     gil_check = StatNode._gil_check
3188     gil_message = "Python print statement"
3189
3190     def generate_execution_code(self, code):
3191         if len(self.arg_tuple.args) == 1 and self.append_newline:
3192             arg = self.arg_tuple.args[0]
3193             arg.generate_evaluation_code(code)
3194             
3195             code.putln(
3196                 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3197                     arg.py_result(),
3198                     code.error_goto(self.pos)))
3199             arg.generate_disposal_code(code)
3200             arg.free_temps(code)
3201         else:
3202             self.arg_tuple.generate_evaluation_code(code)
3203             code.putln(
3204                 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3205                     self.arg_tuple.py_result(),
3206                     self.append_newline,
3207                     code.error_goto(self.pos)))
3208             self.arg_tuple.generate_disposal_code(code)
3209             self.arg_tuple.free_temps(code)
3210
3211     def annotate(self, code):
3212         self.arg_tuple.annotate(code)
3213
3214
3215 class ExecStatNode(StatNode):
3216     #  exec statement
3217     #
3218     #  args     [ExprNode]
3219
3220     child_attrs = ["args"]
3221
3222     def analyse_expressions(self, env):
3223         for i, arg in enumerate(self.args):
3224             arg.analyse_expressions(env)
3225             arg = arg.coerce_to_pyobject(env)
3226             self.args[i] = arg
3227         env.use_utility_code(Builtin.pyexec_utility_code)
3228
3229     gil_check = StatNode._gil_check
3230     gil_message = "Python exec statement"
3231
3232     def generate_execution_code(self, code):
3233         args = []
3234         for arg in self.args:
3235             arg.generate_evaluation_code(code)
3236             args.append( arg.py_result() )
3237         args = tuple(args + ['0', '0'][:3-len(args)])
3238         temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3239         code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3240                 (temp_result,) + args))
3241         for arg in self.args:
3242             arg.generate_disposal_code(code)
3243             arg.free_temps(code)
3244         code.putln(
3245             code.error_goto_if_null(temp_result, self.pos))
3246         code.put_gotref(temp_result)
3247         code.put_decref_clear(temp_result, py_object_type)
3248         code.funcstate.release_temp(temp_result)
3249
3250     def annotate(self, code):
3251         for arg in self.args:
3252             arg.annotate(code)
3253
3254
3255 class DelStatNode(StatNode):
3256     #  del statement
3257     #
3258     #  args     [ExprNode]
3259     
3260     child_attrs = ["args"]
3261
3262     def analyse_declarations(self, env):
3263         for arg in self.args:
3264             arg.analyse_target_declaration(env)
3265     
3266     def analyse_expressions(self, env):
3267         for arg in self.args:
3268             arg.analyse_target_expression(env, None)
3269             if not arg.type.is_pyobject:
3270                 error(arg.pos, "Deletion of non-Python object")
3271             #arg.release_target_temp(env)
3272
3273     def gil_check(self, env):
3274         for arg in self.args:
3275             if arg.type.is_pyobject:
3276                 self._gil_check(env)
3277
3278     gil_message = "Deleting Python object"
3279
3280     def generate_execution_code(self, code):
3281         for arg in self.args:
3282             if arg.type.is_pyobject:
3283                 arg.generate_deletion_code(code)
3284             # else error reported earlier
3285
3286     def annotate(self, code):
3287         for arg in self.args:
3288             arg.annotate(code)
3289
3290
3291 class PassStatNode(StatNode):
3292     #  pass statement
3293
3294     child_attrs = []
3295     
3296     def analyse_expressions(self, env):
3297         pass
3298     
3299     def generate_execution_code(self, code):
3300         pass
3301
3302
3303 class BreakStatNode(StatNode):
3304
3305     child_attrs = []
3306
3307     def analyse_expressions(self, env):
3308         pass
3309     
3310     def generate_execution_code(self, code):
3311         if not code.break_label:
3312             error(self.pos, "break statement not inside loop")
3313         else:
3314             code.put_goto(code.break_label)
3315
3316
3317 class ContinueStatNode(StatNode):
3318
3319     child_attrs = []
3320
3321     def analyse_expressions(self, env):
3322         pass
3323     
3324     def generate_execution_code(self, code):
3325         if code.funcstate.in_try_finally:
3326             error(self.pos, "continue statement inside try of try...finally")
3327         elif not code.continue_label:
3328             error(self.pos, "continue statement not inside loop")
3329         else:
3330             code.put_goto(code.continue_label)
3331
3332
3333 class ReturnStatNode(StatNode):
3334     #  return statement
3335     #
3336     #  value         ExprNode or None
3337     #  return_type   PyrexType
3338     
3339     child_attrs = ["value"]
3340
3341     def analyse_expressions(self, env):
3342         return_type = env.return_type
3343         self.return_type = return_type
3344         if not return_type:
3345             error(self.pos, "Return not inside a function body")
3346             return
3347         if self.value:
3348             self.value.analyse_types(env)
3349             if return_type.is_void or return_type.is_returncode:
3350                 error(self.value.pos, 
3351                     "Return with value in void function")
3352             else:
3353                 self.value = self.value.coerce_to(env.return_type, env)
3354         else:
3355             if (not return_type.is_void
3356                 and not return_type.is_pyobject
3357                 and not return_type.is_returncode):
3358                     error(self.pos, "Return value required")
3359
3360     def gil_check(self, env):
3361         if self.return_type.is_pyobject:
3362             self._gil_check(env)
3363
3364     gil_message = "Returning Python object"
3365
3366     def generate_execution_code(self, code):
3367         code.mark_pos(self.pos)
3368         if not self.return_type:
3369             # error reported earlier
3370             return
3371         if self.return_type.is_pyobject:
3372             code.put_xdecref(Naming.retval_cname,
3373                              self.return_type)
3374         if self.value:
3375             self.value.generate_evaluation_code(code)
3376             self.value.make_owned_reference(code)
3377             code.putln(
3378                 "%s = %s;" % (
3379                     Naming.retval_cname,
3380                     self.value.result_as(self.return_type)))
3381             self.value.generate_post_assignment_code(code)
3382             self.value.free_temps(code)
3383         else:
3384             if self.return_type.is_pyobject:
3385                 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3386             elif self.return_type.is_returncode:
3387                 code.putln(
3388                     "%s = %s;" % (
3389                         Naming.retval_cname,
3390                         self.return_type.default_value))
3391         for cname, type in code.funcstate.temps_holding_reference():
3392             code.put_decref_clear(cname, type)
3393         code.put_goto(code.return_label)
3394         
3395     def annotate(self, code):
3396         if self.value:
3397             self.value.annotate(code)
3398
3399
3400 class RaiseStatNode(StatNode):
3401     #  raise statement
3402     #
3403     #  exc_type    ExprNode or None
3404     #  exc_value   ExprNode or None
3405     #  exc_tb      ExprNode or None
3406     
3407     child_attrs = ["exc_type", "exc_value", "exc_tb"]
3408
3409     def analyse_expressions(self, env):
3410         if self.exc_type:
3411             self.exc_type.analyse_types(env)
3412             self.exc_type = self.exc_type.coerce_to_pyobject(env)
3413         if self.exc_value:
3414             self.exc_value.analyse_types(env)
3415             self.exc_value = self.exc_value.coerce_to_pyobject(env)
3416         if self.exc_tb:
3417             self.exc_tb.analyse_types(env)
3418             self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3419         env.use_utility_code(raise_utility_code)
3420         env.use_utility_code(restore_exception_utility_code)
3421
3422     gil_check = StatNode._gil_check
3423     gil_message = "Raising exception"
3424
3425     def generate_execution_code(self, code):
3426         if self.exc_type:
3427             self.exc_type.generate_evaluation_code(code)
3428             type_code = self.exc_type.py_result()
3429         else:
3430             type_code = "0"
3431         if self.exc_value:
3432             self.exc_value.generate_evaluation_code(code)
3433             value_code = self.exc_value.py_result()
3434         else:
3435             value_code = "0"
3436         if self.exc_tb:
3437             self.exc_tb.generate_evaluation_code(code)
3438             tb_code = self.exc_tb.py_result()
3439         else:
3440             tb_code = "0"
3441         if self.exc_type or self.exc_value or self.exc_tb:
3442             code.putln(
3443                 "__Pyx_Raise(%s, %s, %s);" % (
3444                     type_code,
3445                     value_code,
3446                     tb_code))
3447         else:
3448             code.putln(
3449                 "__Pyx_ReRaise();")
3450         for obj in (self.exc_type, self.exc_value, self.exc_tb):
3451             if obj:
3452                 obj.generate_disposal_code(code)
3453                 obj.free_temps(code)
3454         code.putln(
3455             code.error_goto(self.pos))
3456
3457     def annotate(self, code):
3458         if self.exc_type:
3459             self.exc_type.annotate(code)
3460         if self.exc_value:
3461             self.exc_value.annotate(code)
3462         if self.exc_tb:
3463             self.exc_tb.annotate(code)
3464
3465
3466 class ReraiseStatNode(StatNode):
3467
3468     child_attrs = []
3469
3470     def analyse_expressions(self, env):
3471         env.use_utility_code(raise_utility_code)
3472         env.use_utility_code(restore_exception_utility_code)
3473
3474     gil_check = StatNode._gil_check
3475     gil_message = "Raising exception"
3476
3477     def generate_execution_code(self, code):
3478         vars = code.funcstate.exc_vars
3479         if vars:
3480             code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3481             code.putln(code.error_goto(self.pos))
3482         else:
3483             error(self.pos, "Reraise not inside except clause")
3484         
3485
3486 class AssertStatNode(StatNode):
3487     #  assert statement
3488     #
3489     #  cond    ExprNode
3490     #  value   ExprNode or None
3491     
3492     child_attrs = ["cond", "value"]
3493
3494     def analyse_expressions(self, env):
3495         self.cond = self.cond.analyse_boolean_expression(env)
3496         if self.value:
3497             self.value.analyse_types(env)
3498             self.value = self.value.coerce_to_pyobject(env)
3499
3500     gil_check = StatNode._gil_check
3501     gil_message = "Raising exception"
3502     
3503     def generate_execution_code(self, code):
3504         code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3505         self.cond.generate_evaluation_code(code)
3506         code.putln(
3507             "if (unlikely(!%s)) {" %
3508                 self.cond.result())
3509         if self.value:
3510             self.value.generate_evaluation_code(code)
3511             code.putln(
3512                 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3513                     self.value.py_result())
3514             self.value.generate_disposal_code(code)
3515             self.value.free_temps(code)
3516         else:
3517             code.putln(
3518                 "PyErr_SetNone(PyExc_AssertionError);")
3519         code.putln(
3520                 code.error_goto(self.pos))
3521         code.putln(
3522             "}")
3523         self.cond.generate_disposal_code(code)
3524         self.cond.free_temps(code)
3525         code.putln("#endif")
3526
3527     def annotate(self, code):
3528         self.cond.annotate(code)
3529         if self.value:
3530             self.value.annotate(code)
3531
3532
3533 class IfStatNode(StatNode):
3534     #  if statement
3535     #
3536     #  if_clauses   [IfClauseNode]
3537     #  else_clause  StatNode or None
3538
3539     child_attrs = ["if_clauses", "else_clause"]
3540     
3541     def analyse_control_flow(self, env):
3542         env.start_branching(self.pos)
3543         for if_clause in self.if_clauses:
3544             if_clause.analyse_control_flow(env)
3545             env.next_branch(if_clause.end_pos())
3546         if self.else_clause:
3547             self.else_clause.analyse_control_flow(env)
3548         env.finish_branching(self.end_pos())
3549
3550     def analyse_declarations(self, env):
3551         for if_clause in self.if_clauses:
3552             if_clause.analyse_declarations(env)
3553         if self.else_clause:
3554             self.else_clause.analyse_declarations(env)
3555     
3556     def analyse_expressions(self, env):
3557         for if_clause in self.if_clauses:
3558             if_clause.analyse_expressions(env)
3559         if self.else_clause:
3560             self.else_clause.analyse_expressions(env)
3561     
3562     def generate_execution_code(self, code):
3563         code.mark_pos(self.pos)
3564         end_label = code.new_label()
3565         for if_clause in self.if_clauses:
3566             if_clause.generate_execution_code(code, end_label)
3567         if self.else_clause:
3568             code.putln("/*else*/ {")
3569             self.else_clause.generate_execution_code(code)
3570             code.putln("}")
3571         code.put_label(end_label)
3572         
3573     def annotate(self, code):
3574         for if_clause in self.if_clauses:
3575             if_clause.annotate(code)
3576         if self.else_clause:
3577             self.else_clause.annotate(code)
3578
3579
3580 class IfClauseNode(Node):
3581     #  if or elif clause in an if statement
3582     #
3583     #  condition   ExprNode
3584     #  body        StatNode
3585     
3586     child_attrs = ["condition", "body"]
3587
3588     def analyse_control_flow(self, env):
3589         self.body.analyse_control_flow(env)
3590         
3591     def analyse_declarations(self, env):
3592         self.condition.analyse_declarations(env)
3593         self.body.analyse_declarations(env)
3594     
3595     def analyse_expressions(self, env):
3596         self.condition = \
3597             self.condition.analyse_temp_boolean_expression(env)
3598         self.body.analyse_expressions(env)
3599     
3600     def generate_execution_code(self, code, end_label):
3601         self.condition.generate_evaluation_code(code)
3602         code.putln(
3603             "if (%s) {" %
3604                 self.condition.result())
3605         self.condition.generate_disposal_code(code)
3606         self.condition.free_temps(code)
3607         self.body.generate_execution_code(code)
3608         #code.putln(
3609         #    "goto %s;" %
3610         #        end_label)
3611         code.put_goto(end_label)
3612         code.putln("}")
3613
3614     def annotate(self, code):
3615         self.condition.annotate(code)
3616         self.body.annotate(code)
3617         
3618
3619 class SwitchCaseNode(StatNode):
3620     # Generated in the optimization of an if-elif-else node
3621     #
3622     # conditions    [ExprNode]
3623     # body          StatNode
3624     
3625     child_attrs = ['conditions', 'body']
3626
3627     def generate_execution_code(self, code):
3628         for cond in self.conditions:
3629             code.mark_pos(cond.pos)
3630             cond.generate_evaluation_code(code)
3631             code.putln("case %s:" % cond.result())
3632         self.body.generate_execution_code(code)
3633         code.putln("break;")
3634         
3635     def annotate(self, code):
3636         for cond in self.conditions:
3637             cond.annotate(code)
3638         self.body.annotate(code)
3639
3640 class SwitchStatNode(StatNode):
3641     # Generated in the optimization of an if-elif-else node
3642     #
3643     # test          ExprNode
3644     # cases         [SwitchCaseNode]
3645     # else_clause   StatNode or None
3646     
3647     child_attrs = ['test', 'cases', 'else_clause']
3648     
3649     def generate_execution_code(self, code):
3650         code.putln("switch (%s) {" % self.test.result())
3651         for case in self.cases:
3652             case.generate_execution_code(code)
3653         if self.else_clause is not None:
3654             code.putln("default:")
3655             self.else_clause.generate_execution_code(code)
3656             code.putln("break;")
3657         code.putln("}")
3658
3659     def annotate(self, code):
3660         self.test.annotate(code)
3661         for case in self.cases:
3662             case.annotate(code)
3663         if self.else_clause is not None:
3664             self.else_clause.annotate(code)
3665             
3666 class LoopNode(object):
3667     
3668     def analyse_control_flow(self, env):
3669         env.start_branching(self.pos)
3670         self.body.analyse_control_flow(env)
3671         env.next_branch(self.body.end_pos())
3672         if self.else_clause:
3673             self.else_clause.analyse_control_flow(env)
3674         env.finish_branching(self.end_pos())
3675
3676     
3677 class WhileStatNode(LoopNode, StatNode):
3678     #  while statement
3679     #
3680     #  condition    ExprNode
3681     #  body         StatNode
3682     #  else_clause  StatNode
3683
3684     child_attrs = ["condition", "body", "else_clause"]
3685
3686     def analyse_declarations(self, env):
3687         self.body.analyse_declarations(env)
3688         if self.else_clause:
3689             self.else_clause.analyse_declarations(env)
3690     
3691     def analyse_expressions(self, env):
3692         self.condition = \
3693             self.condition.analyse_temp_boolean_expression(env)
3694         self.body.analyse_expressions(env)
3695         if self.else_clause:
3696             self.else_clause.analyse_expressions(env)
3697     
3698     def generate_execution_code(self, code):
3699         old_loop_labels = code.new_loop_labels()
3700         code.putln(
3701             "while (1) {")
3702         self.condition.generate_evaluation_code(code)
3703         self.condition.generate_disposal_code(code)
3704         code.putln(
3705             "if (!%s) break;" %
3706                 self.condition.result())
3707         self.condition.free_temps(code)
3708         self.body.generate_execution_code(code)
3709         code.put_label(code.continue_label)
3710         code.putln("}")
3711         break_label = code.break_label
3712         code.set_loop_labels(old_loop_labels)
3713         if self.else_clause:
3714             code.putln("/*else*/ {")
3715             self.else_clause.generate_execution_code(code)
3716             code.putln("}")
3717         code.put_label(break_label)
3718
3719     def annotate(self, code):
3720         self.condition.annotate(code)
3721         self.body.annotate(code)
3722         if self.else_clause:
3723             self.else_clause.annotate(code)
3724
3725
3726 def ForStatNode(pos, **kw):
3727     if 'iterator' in kw:
3728         return ForInStatNode(pos, **kw)
3729     else:
3730         return ForFromStatNode(pos, **kw)
3731
3732 class ForInStatNode(LoopNode, StatNode):
3733     #  for statement
3734     #
3735     #  target        ExprNode
3736     #  iterator      IteratorNode
3737     #  body          StatNode
3738     #  else_clause   StatNode
3739     #  item          NextNode       used internally
3740     
3741     child_attrs = ["target", "iterator", "body", "else_clause"]
3742     item = None
3743     
3744     def analyse_declarations(self, env):
3745         self.target.analyse_target_declaration(env)
3746         self.body.analyse_declarations(env)
3747         if self.else_clause:
3748             self.else_clause.analyse_declarations(env)
3749
3750     def analyse_expressions(self, env):
3751         import ExprNodes
3752         self.target.analyse_target_types(env)
3753         self.iterator.analyse_expressions(env)
3754         self.item = ExprNodes.NextNode(self.iterator, env)
3755         self.item = self.item.coerce_to(self.target.type, env)
3756         self.body.analyse_expressions(env)
3757         if self.else_clause:
3758             self.else_clause.analyse_expressions(env)
3759
3760     def generate_execution_code(self, code):
3761         old_loop_labels = code.new_loop_labels()
3762         self.iterator.allocate_counter_temp(code)
3763         self.iterator.generate_evaluation_code(code)
3764         code.putln(
3765             "for (;;) {")
3766         self.item.generate_evaluation_code(code)
3767         self.target.generate_assignment_code(self.item, code)
3768         self.body.generate_execution_code(code)
3769         code.put_label(code.continue_label)
3770         code.putln(
3771             "}")
3772         break_label = code.break_label
3773         code.set_loop_labels(old_loop_labels)
3774         if self.else_clause:
3775             code.putln("/*else*/ {")
3776             self.else_clause.generate_execution_code(code)
3777             code.putln("}")
3778         code.put_label(break_label)
3779         self.iterator.release_counter_temp(code)
3780         self.iterator.generate_disposal_code(code)
3781         self.iterator.free_temps(code)
3782
3783     def annotate(self, code):
3784         self.target.annotate(code)
3785         self.iterator.annotate(code)
3786         self.body.annotate(code)
3787         if self.else_clause:
3788             self.else_clause.annotate(code)
3789         self.item.annotate(code)
3790
3791
3792 class ForFromStatNode(LoopNode, StatNode):
3793     #  for name from expr rel name rel expr
3794     #
3795     #  target        NameNode
3796     #  bound1        ExprNode
3797     #  relation1     string
3798     #  relation2     string
3799     #  bound2        ExprNode
3800     #  step          ExprNode or None
3801     #  body          StatNode
3802     #  else_clause   StatNode or None
3803     #
3804     #  Used internally:
3805     #
3806     #  from_range         bool
3807     #  is_py_target       bool
3808     #  loopvar_node       ExprNode (usually a NameNode or temp node)
3809     #  py_loopvar_node    PyTempNode or None
3810     child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3811
3812     is_py_target = False
3813     loopvar_node = None
3814     py_loopvar_node = None
3815     from_range = False
3816
3817     def analyse_declarations(self, env):
3818         self.target.analyse_target_declaration(env)
3819         self.body.analyse_declarations(env)
3820         if self.else_clause:
3821             self.else_clause.analyse_declarations(env)
3822
3823     def analyse_expressions(self, env):
3824         import ExprNodes
3825         self.target.analyse_target_types(env)
3826         self.bound1.analyse_types(env)
3827         self.bound2.analyse_types(env)
3828         if self.step is not None:
3829             if isinstance(self.step, ExprNodes.UnaryMinusNode):
3830                 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3831             self.step.analyse_types(env)
3832         
3833         target_type = self.target.type
3834         if self.target.type.is_numeric:
3835             loop_type = self.target.type
3836         else:
3837             loop_type = PyrexTypes.c_int_type
3838             if not self.bound1.type.is_pyobject:
3839                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3840             if not self.bound2.type.is_pyobject:
3841                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3842             if self.step is not None and not self.step.type.is_pyobject:
3843                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3844         self.bound1 = self.bound1.coerce_to(loop_type, env)
3845         self.bound2 = self.bound2.coerce_to(loop_type, env)
3846         if not self.bound2.is_literal:
3847             self.bound2 = self.bound2.coerce_to_temp(env)
3848         if self.step is not None:
3849             self.step = self.step.coerce_to(loop_type, env)            
3850             if not self.step.is_literal:
3851                 self.step = self.step.coerce_to_temp(env)
3852
3853         target_type = self.target.type
3854         if not (target_type.is_pyobject or target_type.is_numeric):
3855             error(self.target.pos,
3856                 "for-from loop variable must be c numeric type or Python object")
3857         if target_type.is_numeric:
3858             self.is_py_target = False
3859             if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3860                 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3861             self.loopvar_node = self.target
3862             self.py_loopvar_node = None
3863         else:
3864             self.is_py_target = True
3865             c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3866             self.loopvar_node = c_loopvar_node
3867             self.py_loopvar_node = \
3868                 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3869         self.body.analyse_expressions(env)
3870         if self.else_clause:
3871             self.else_clause.analyse_expressions(env)
3872             
3873     def generate_execution_code(self, code):
3874         old_loop_labels = code.new_loop_labels()
3875         from_range = self.from_range
3876         self.bound1.generate_evaluation_code(code)
3877         self.bound2.generate_evaluation_code(code)
3878         offset, incop = self.relation_table[self.relation1]
3879         if self.step is not None:
3880             self.step.generate_evaluation_code(code)
3881             step = self.step.result()
3882             incop = "%s=%s" % (incop[0], step)
3883         import ExprNodes
3884         if isinstance(self.loopvar_node, ExprNodes.TempNode):
3885             self.loopvar_node.allocate(code)
3886         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3887             self.py_loopvar_node.allocate(code)
3888         if from_range:
3889             loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3890         else:
3891             loopvar_name = self.loopvar_node.result()
3892         code.putln(
3893             "for (%s = %s%s; %s %s %s; %s%s) {" % (
3894                 loopvar_name,
3895                 self.bound1.result(), offset,
3896                 loopvar_name, self.relation2, self.bound2.result(),
3897                 loopvar_name, incop))
3898         if self.py_loopvar_node:
3899             self.py_loopvar_node.generate_evaluation_code(code)
3900             self.target.generate_assignment_code(self.py_loopvar_node, code)
3901         elif from_range:
3902             code.putln("%s = %s;" % (
3903                             self.target.result(), loopvar_name))
3904         self.body.generate_execution_code(code)
3905         code.put_label(code.continue_label)
3906         if self.py_loopvar_node:
3907             # This mess is to make for..from loops with python targets behave 
3908             # exactly like those with C targets with regards to re-assignment 
3909             # of the loop variable. 
3910             import ExprNodes
3911             if self.target.entry.is_pyglobal:
3912                 # We know target is a NameNode, this is the only ugly case. 
3913                 target_node = ExprNodes.PyTempNode(self.target.pos, None)
3914                 target_node.allocate(code)
3915                 interned_cname = code.intern_identifier(self.target.entry.name)
3916                 code.putln("/*here*/")
3917                 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
3918                                 target_node.result(),
3919                                 Naming.module_cname, 
3920                                 interned_cname,
3921                                 code.error_goto_if_null(target_node.result(), self.target.pos)))
3922                 code.put_gotref(target_node.result())
3923             else:
3924                 target_node = self.target
3925             from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
3926             from_py_node.temp_code = loopvar_name
3927             from_py_node.generate_result_code(code)
3928             if self.target.entry.is_pyglobal:
3929                 code.put_decref(target_node.result(), target_node.type)
3930                 target_node.release(code)
3931         code.putln("}")
3932         if self.py_loopvar_node:
3933             # This is potentially wasteful, but we don't want the semantics to 
3934             # depend on whether or not the loop is a python type. 
3935             self.py_loopvar_node.generate_evaluation_code(code)
3936             self.target.generate_assignment_code(self.py_loopvar_node, code)
3937         break_label = code.break_label
3938         code.set_loop_labels(old_loop_labels)
3939         if self.else_clause:
3940             code.putln("/*else*/ {")
3941             self.else_clause.generate_execution_code(code)
3942             code.putln("}")
3943         code.put_label(break_label)
3944         self.bound1.generate_disposal_code(code)
3945         self.bound1.free_temps(code)
3946         self.bound2.generate_disposal_code(code)
3947         self.bound2.free_temps(code)
3948         if isinstance(self.loopvar_node, ExprNodes.TempNode):
3949             self.loopvar_node.release(code)
3950         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3951             self.py_loopvar_node.release(code)
3952         if self.step is not None:
3953             self.step.generate_disposal_code(code)
3954             self.step.free_temps(code)
3955     
3956     relation_table = {
3957         # {relop : (initial offset, increment op)}
3958         '<=': ("",   "++"),
3959         '<' : ("+1", "++"),
3960         '>=': ("",   "--"),
3961         '>' : ("-1", "--")
3962     }
3963     
3964     def annotate(self, code):
3965         self.target.annotate(code)
3966         self.bound1.annotate(code)
3967         self.bound2.annotate(code)
3968         if self.step:
3969             self.bound2.annotate(code)
3970         self.body.annotate(code)
3971         if self.else_clause:
3972             self.else_clause.annotate(code)
3973
3974
3975 class WithStatNode(StatNode):
3976     """
3977     Represents a Python with statement.
3978     
3979     This is only used at parse tree level; and is not present in
3980     analysis or generation phases.
3981     """
3982     #  manager          The with statement manager object
3983     #  target            Node (lhs expression)
3984     #  body             StatNode
3985     child_attrs = ["manager", "target", "body"]
3986
3987 class TryExceptStatNode(StatNode):
3988     #  try .. except statement
3989     #
3990     #  body             StatNode
3991     #  except_clauses   [ExceptClauseNode]
3992     #  else_clause      StatNode or None
3993
3994     child_attrs = ["body", "except_clauses", "else_clause"]
3995     
3996     def analyse_control_flow(self, env):
3997         env.start_branching(self.pos)
3998         self.body.analyse_control_flow(env)
3999         successful_try = env.control_flow # grab this for later
4000         env.next_branch(self.body.end_pos())
4001         env.finish_branching(self.body.end_pos())
4002         
4003         env.start_branching(self.except_clauses[0].pos)
4004         for except_clause in self.except_clauses:
4005             except_clause.analyse_control_flow(env)
4006             env.next_branch(except_clause.end_pos())
4007             
4008         # the else cause it executed only when the try clause finishes
4009         env.control_flow.incoming = successful_try
4010         if self.else_clause:
4011             self.else_clause.analyse_control_flow(env)
4012         env.finish_branching(self.end_pos())
4013
4014     def analyse_declarations(self, env):
4015         self.body.analyse_declarations(env)
4016         for except_clause in self.except_clauses:
4017             except_clause.analyse_declarations(env)
4018         if self.else_clause:
4019             self.else_clause.analyse_declarations(env)
4020         env.use_utility_code(reset_exception_utility_code)
4021
4022     def analyse_expressions(self, env):
4023         self.body.analyse_expressions(env)
4024         default_clause_seen = 0
4025         for except_clause in self.except_clauses:
4026             except_clause.analyse_expressions(env)
4027             if default_clause_seen:
4028                 error(except_clause.pos, "default 'except:' must be last")
4029             if not except_clause.pattern:
4030                 default_clause_seen = 1
4031         self.has_default_clause = default_clause_seen
4032         if self.else_clause:
4033             self.else_clause.analyse_expressions(env)
4034
4035     gil_check = StatNode._gil_check
4036     gil_message = "Try-except statement"
4037
4038     def generate_execution_code(self, code):
4039         old_return_label = code.return_label
4040         old_break_label = code.break_label
4041         old_continue_label = code.continue_label
4042         old_error_label = code.new_error_label()
4043         our_error_label = code.error_label
4044         except_end_label = code.new_label('exception_handled')
4045         except_error_label = code.new_label('except_error')
4046         except_return_label = code.new_label('except_return')
4047         try_return_label = code.new_label('try_return')
4048         try_break_label = code.new_label('try_break')
4049         try_continue_label = code.new_label('try_continue')
4050         try_end_label = code.new_label('try_end')
4051
4052         code.putln("{")
4053         code.putln("PyObject %s;" %
4054                    ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4055         code.putln("__Pyx_ExceptionSave(%s);" %
4056                    ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4057         for var in Naming.exc_save_vars:
4058             code.put_xgotref(var)
4059         code.putln(
4060             "/*try:*/ {")
4061         code.return_label = try_return_label
4062         code.break_label = try_break_label
4063         code.continue_label = try_continue_label
4064         self.body.generate_execution_code(code)
4065         code.putln(
4066             "}")
4067         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4068         code.error_label = except_error_label
4069         code.return_label = except_return_label
4070         if self.else_clause:
4071             code.putln(
4072                 "/*else:*/ {")
4073             self.else_clause.generate_execution_code(code)
4074             code.putln(
4075                 "}")
4076         for var in Naming.exc_save_vars:
4077             code.put_xdecref_clear(var, py_object_type)
4078         code.put_goto(try_end_label)
4079         if code.label_used(try_return_label):
4080             code.put_label(try_return_label)
4081             for var in Naming.exc_save_vars:
4082                 code.put_xdecref_clear(var, py_object_type)
4083             code.put_goto(old_return_label)
4084         code.put_label(our_error_label)
4085         for temp_name, type in temps_to_clean_up:
4086             code.put_xdecref_clear(temp_name, type)
4087         for except_clause in self.except_clauses:
4088             except_clause.generate_handling_code(code, except_end_label)
4089
4090         error_label_used = code.label_used(except_error_label)
4091         if error_label_used or not self.has_default_clause:
4092             if error_label_used:
4093                 code.put_label(except_error_label)
4094             for var in Naming.exc_save_vars:
4095                 code.put_xdecref(var, py_object_type)
4096             code.put_goto(old_error_label)
4097             
4098         if code.label_used(try_break_label):
4099             code.put_label(try_break_label)
4100             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4101             code.putln("__Pyx_ExceptionReset(%s);" %
4102                        ', '.join(Naming.exc_save_vars))
4103             code.put_goto(old_break_label)
4104             
4105         if code.label_used(try_continue_label):
4106             code.put_label(try_continue_label)
4107             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4108             code.putln("__Pyx_ExceptionReset(%s);" %
4109                        ', '.join(Naming.exc_save_vars))
4110             code.put_goto(old_continue_label)
4111
4112         if code.label_used(except_return_label):
4113             code.put_label(except_return_label)
4114             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4115             code.putln("__Pyx_ExceptionReset(%s);" %
4116                        ', '.join(Naming.exc_save_vars))
4117             code.put_goto(old_return_label)
4118
4119         if code.label_used(except_end_label):
4120             code.put_label(except_end_label)
4121             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4122             code.putln("__Pyx_ExceptionReset(%s);" %
4123                        ', '.join(Naming.exc_save_vars))
4124         code.put_label(try_end_label)
4125         code.putln("}")
4126
4127         code.return_label = old_return_label
4128         code.break_label = old_break_label
4129         code.continue_label = old_continue_label
4130         code.error_label = old_error_label
4131
4132     def annotate(self, code):
4133         self.body.annotate(code)
4134         for except_node in self.except_clauses:
4135             except_node.annotate(code)
4136         if self.else_clause:
4137             self.else_clause.annotate(code)
4138
4139
4140 class ExceptClauseNode(Node):
4141     #  Part of try ... except statement.
4142     #
4143     #  pattern        ExprNode
4144     #  target         ExprNode or None
4145     #  body           StatNode
4146     #  excinfo_target NameNode or None   optional target for exception info
4147     #  match_flag     string             result of exception match
4148     #  exc_value      ExcValueNode       used internally
4149     #  function_name  string             qualified name of enclosing function
4150     #  exc_vars       (string * 3)       local exception variables
4151
4152     # excinfo_target is never set by the parser, but can be set by a transform
4153     # in order to extract more extensive information about the exception as a
4154     # sys.exc_info()-style tuple into a target variable
4155     
4156     child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4157
4158     exc_value = None
4159     excinfo_target = None
4160
4161     def analyse_declarations(self, env):
4162         if self.target:
4163             self.target.analyse_target_declaration(env)
4164         if self.excinfo_target is not None:
4165             self.excinfo_target.analyse_target_declaration(env)
4166         self.body.analyse_declarations(env)
4167     
4168     def analyse_expressions(self, env):
4169         import ExprNodes
4170         genv = env.global_scope()
4171         self.function_name = env.qualified_name
4172         if self.pattern:
4173             self.pattern.analyse_expressions(env)
4174             self.pattern = self.pattern.coerce_to_pyobject(env)
4175
4176         if self.target:
4177             self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4178             self.target.analyse_target_expression(env, self.exc_value)
4179         if self.excinfo_target is not None:
4180             import ExprNodes
4181             self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4182                 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4183             self.excinfo_tuple.analyse_expressions(env)
4184             self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4185
4186         self.body.analyse_expressions(env)
4187
4188     def generate_handling_code(self, code, end_label):
4189         code.mark_pos(self.pos)
4190         if self.pattern:
4191             self.pattern.generate_evaluation_code(code)
4192             
4193             match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4194             code.putln(
4195                 "%s = PyErr_ExceptionMatches(%s);" % (
4196                     match_flag,
4197                     self.pattern.py_result()))
4198             self.pattern.generate_disposal_code(code)
4199             self.pattern.free_temps(code)
4200             code.putln(
4201                 "if (%s) {" %
4202                     match_flag)
4203             code.funcstate.release_temp(match_flag)
4204         else:
4205             code.putln("/*except:*/ {")
4206
4207         if not getattr(self.body, 'stats', True):
4208             # most simple case: no exception variable, empty body (pass)
4209             # => reset the exception state, done
4210             code.putln("PyErr_Restore(0,0,0);")
4211             code.put_goto(end_label)
4212             code.putln("}")
4213             return
4214         
4215         exc_vars = [code.funcstate.allocate_temp(py_object_type,
4216                                                  manage_ref=True)
4217                     for i in xrange(3)]
4218         code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4219         # We always have to fetch the exception value even if
4220         # there is no target, because this also normalises the 
4221         # exception and stores it in the thread state.
4222         code.globalstate.use_utility_code(get_exception_utility_code)
4223         exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4224         code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4225             code.error_goto(self.pos)))
4226         for x in exc_vars:
4227             code.put_gotref(x)
4228         if self.target:
4229             self.exc_value.set_var(exc_vars[1])
4230             self.exc_value.generate_evaluation_code(code)
4231             self.target.generate_assignment_code(self.exc_value, code)
4232         if self.excinfo_target is not None:
4233             for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4234                 node.set_var(tempvar)
4235             self.excinfo_tuple.generate_evaluation_code(code)
4236             self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4237
4238         old_break_label, old_continue_label = code.break_label, code.continue_label
4239         code.break_label = code.new_label('except_break')
4240         code.continue_label = code.new_label('except_continue')
4241
4242         old_exc_vars = code.funcstate.exc_vars
4243         code.funcstate.exc_vars = exc_vars
4244         self.body.generate_execution_code(code)
4245         code.funcstate.exc_vars = old_exc_vars
4246         for var in exc_vars:
4247             code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4248         code.put_goto(end_label)
4249         
4250         if code.label_used(code.break_label):
4251             code.put_label(code.break_label)
4252             for var in exc_vars:
4253                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4254             code.put_goto(old_break_label)
4255         code.break_label = old_break_label
4256
4257         if code.label_used(code.continue_label):
4258             code.put_label(code.continue_label)
4259             for var in exc_vars:
4260                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4261             code.put_goto(old_continue_label)
4262         code.continue_label = old_continue_label
4263
4264         for temp in exc_vars:
4265             code.funcstate.release_temp(temp)
4266
4267         code.putln(
4268             "}")
4269
4270     def annotate(self, code):
4271         if self.pattern:
4272             self.pattern.annotate(code)
4273         if self.target:
4274             self.target.annotate(code)
4275         self.body.annotate(code)
4276
4277
4278 class TryFinallyStatNode(StatNode):
4279     #  try ... finally statement
4280     #
4281     #  body             StatNode
4282     #  finally_clause   StatNode
4283     #
4284     #  The plan is that we funnel all continue, break
4285     #  return and error gotos into the beginning of the
4286     #  finally block, setting a variable to remember which
4287     #  one we're doing. At the end of the finally block, we
4288     #  switch on the variable to figure out where to go.
4289     #  In addition, if we're doing an error, we save the
4290     #  exception on entry to the finally block and restore
4291     #  it on exit.
4292
4293     child_attrs = ["body", "finally_clause"]
4294     
4295     preserve_exception = 1
4296     
4297     disallow_continue_in_try_finally = 0
4298     # There doesn't seem to be any point in disallowing
4299     # continue in the try block, since we have no problem
4300     # handling it.
4301
4302     def create_analysed(pos, env, body, finally_clause):
4303         node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4304         return node
4305     create_analysed = staticmethod(create_analysed)
4306     
4307     def analyse_control_flow(self, env):
4308         env.start_branching(self.pos)
4309         self.body.analyse_control_flow(env)
4310         env.next_branch(self.body.end_pos())
4311         env.finish_branching(self.body.end_pos())
4312         self.finally_clause.analyse_control_flow(env)
4313
4314     def analyse_declarations(self, env):
4315         self.body.analyse_declarations(env)
4316         self.finally_clause.analyse_declarations(env)
4317     
4318     def analyse_expressions(self, env):
4319         self.body.analyse_expressions(env)
4320         self.finally_clause.analyse_expressions(env)
4321
4322     gil_check = StatNode._gil_check
4323     gil_message = "Try-finally statement"
4324
4325     def generate_execution_code(self, code):
4326         old_error_label = code.error_label
4327         old_labels = code.all_new_labels()
4328         new_labels = code.get_all_labels()
4329         new_error_label = code.error_label
4330         catch_label = code.new_label()
4331         code.putln(
4332             "/*try:*/ {")
4333         if self.disallow_continue_in_try_finally:
4334             was_in_try_finally = code.funcstate.in_try_finally
4335             code.funcstate.in_try_finally = 1
4336         self.body.generate_execution_code(code)
4337         if self.disallow_continue_in_try_finally:
4338             code.funcstate.in_try_finally = was_in_try_finally
4339         code.putln(
4340             "}")
4341         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4342         code.putln(
4343             "/*finally:*/ {")
4344         cases_used = []
4345         error_label_used = 0
4346         for i, new_label in enumerate(new_labels):
4347             if new_label in code.labels_used:
4348                 cases_used.append(i)
4349                 if new_label == new_error_label:
4350                     error_label_used = 1
4351                     error_label_case = i
4352         if cases_used:
4353             code.putln(
4354                     "int __pyx_why;")
4355             if error_label_used and self.preserve_exception:
4356                 code.putln(
4357                     "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4358                 code.putln(
4359                     "int %s;" % Naming.exc_lineno_name)
4360                 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4361                 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4362                 code.putln(exc_var_init_zero)
4363             else:
4364                 exc_var_init_zero = None
4365             code.use_label(catch_label)
4366             code.putln(
4367                     "__pyx_why = 0; goto %s;" % catch_label)
4368             for i in cases_used:
4369                 new_label = new_labels[i]
4370                 #if new_label and new_label != "<try>":
4371                 if new_label == new_error_label and self.preserve_exception:
4372                     self.put_error_catcher(code, 
4373                         new_error_label, i+1, catch_label, temps_to_clean_up)
4374                 else:
4375                     code.put('%s: ' % new_label)
4376                     if exc_var_init_zero:
4377                         code.putln(exc_var_init_zero)
4378                     code.putln("__pyx_why = %s; goto %s;" % (
4379                             i+1,
4380                             catch_label))
4381             code.put_label(catch_label)
4382         code.set_all_labels(old_labels)
4383         if error_label_used:
4384             code.new_error_label()
4385             finally_error_label = code.error_label
4386         self.finally_clause.generate_execution_code(code)
4387         if error_label_used:
4388             if finally_error_label in code.labels_used and self.preserve_exception:
4389                 over_label = code.new_label()
4390                 code.put_goto(over_label);
4391                 code.put_label(finally_error_label)
4392                 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4393                 for var in Naming.exc_vars:
4394                     code.putln("Py_XDECREF(%s);" % var)
4395                 code.putln("}")
4396                 code.put_goto(old_error_label)
4397                 code.put_label(over_label)
4398             code.error_label = old_error_label
4399         if cases_used:
4400             code.putln(
4401                 "switch (__pyx_why) {")
4402             for i in cases_used:
4403                 old_label = old_labels[i]
4404                 if old_label == old_error_label and self.preserve_exception:
4405                     self.put_error_uncatcher(code, i+1, old_error_label)
4406                 else:
4407                     code.use_label(old_label)
4408                     code.putln(
4409                         "case %s: goto %s;" % (
4410                             i+1,
4411                             old_label))
4412             code.putln(
4413                 "}")
4414         code.putln(
4415             "}")
4416
4417     def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4418         code.globalstate.use_utility_code(restore_exception_utility_code)
4419         code.putln(
4420             "%s: {" %
4421                 error_label)
4422         code.putln(
4423                 "__pyx_why = %s;" %
4424                     i)
4425         for temp_name, type in temps_to_clean_up:
4426             code.put_xdecref_clear(temp_name, type)
4427         code.putln(
4428                 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4429                     Naming.exc_vars)
4430         code.putln(
4431                 "%s = %s;" % (
4432                     Naming.exc_lineno_name, Naming.lineno_cname))
4433         #code.putln(
4434         #        "goto %s;" %
4435         #            catch_label)
4436         code.put_goto(catch_label)
4437         code.putln(
4438             "}")
4439             
4440     def put_error_uncatcher(self, code, i, error_label):
4441         code.globalstate.use_utility_code(restore_exception_utility_code)
4442         code.putln(
4443             "case %s: {" %
4444                 i)
4445         code.putln(
4446                 "__Pyx_ErrRestore(%s, %s, %s);" %
4447                     Naming.exc_vars)
4448         code.putln(
4449                 "%s = %s;" % (
4450                     Naming.lineno_cname, Naming.exc_lineno_name))
4451         for var in Naming.exc_vars:
4452             code.putln(
4453                 "%s = 0;" %
4454                     var)
4455         code.put_goto(error_label)
4456         code.putln(
4457             "}")
4458
4459     def annotate(self, code):
4460         self.body.annotate(code)
4461         self.finally_clause.annotate(code)
4462
4463
4464 class GILStatNode(TryFinallyStatNode):
4465     #  'with gil' or 'with nogil' statement
4466     #
4467     #   state   string   'gil' or 'nogil'
4468
4469 #    child_attrs = []
4470     
4471     preserve_exception = 0
4472
4473     def __init__(self, pos, state, body):
4474         self.state = state
4475         TryFinallyStatNode.__init__(self, pos,
4476             body = body,
4477             finally_clause = GILExitNode(pos, state = state))
4478
4479     def analyse_expressions(self, env):
4480         env.use_utility_code(force_init_threads_utility_code)
4481         was_nogil = env.nogil
4482         env.nogil = 1
4483         TryFinallyStatNode.analyse_expressions(self, env)
4484         env.nogil = was_nogil
4485
4486     def gil_check(self, env):
4487         pass
4488
4489     def generate_execution_code(self, code):
4490         code.mark_pos(self.pos)
4491         if self.state == 'gil':
4492             code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4493         else:
4494             code.putln("{ PyThreadState *_save;")
4495             code.putln("Py_UNBLOCK_THREADS")
4496         TryFinallyStatNode.generate_execution_code(self, code)
4497         code.putln("}")
4498
4499
4500 class GILExitNode(StatNode):
4501     #  Used as the 'finally' block in a GILStatNode
4502     #
4503     #  state   string   'gil' or 'nogil'
4504
4505     child_attrs = []
4506
4507     def analyse_expressions(self, env):
4508         pass
4509
4510     def generate_execution_code(self, code):
4511         if self.state == 'gil':
4512             code.putln("PyGILState_Release();")
4513         else:
4514             code.putln("Py_BLOCK_THREADS")
4515
4516
4517 class CImportStatNode(StatNode):
4518     #  cimport statement
4519     #
4520     #  module_name   string           Qualified name of module being imported
4521     #  as_name       string or None   Name specified in "as" clause, if any
4522
4523     child_attrs = []
4524     
4525     def analyse_declarations(self, env):
4526         if not env.is_module_scope:
4527             error(self.pos, "cimport only allowed at module level")
4528             return
4529         module_scope = env.find_module(self.module_name, self.pos)
4530         if "." in self.module_name:
4531             names = [EncodedString(name) for name in self.module_name.split(".")]
4532             top_name = names[0]
4533             top_module_scope = env.context.find_submodule(top_name)
4534             module_scope = top_module_scope
4535             for name in names[1:]:
4536                 submodule_scope = module_scope.find_submodule(name)
4537                 module_scope.declare_module(name, submodule_scope, self.pos)
4538                 module_scope = submodule_scope
4539             if self.as_name:
4540                 env.declare_module(self.as_name, module_scope, self.pos)
4541             else:
4542                 env.declare_module(top_name, top_module_scope, self.pos)
4543         else:
4544             name = self.as_name or self.module_name
4545             env.declare_module(name, module_scope, self.pos)
4546
4547     def analyse_expressions(self, env):
4548         pass
4549     
4550     def generate_execution_code(self, code):
4551         pass
4552     
4553
4554 class FromCImportStatNode(StatNode):
4555     #  from ... cimport statement
4556     #
4557     #  module_name     string                        Qualified name of module
4558     #  imported_names  [(pos, name, as_name, kind)]  Names to be imported
4559     
4560     child_attrs = []
4561
4562     def analyse_declarations(self, env):
4563         if not env.is_module_scope:
4564             error(self.pos, "cimport only allowed at module level")
4565             return
4566         module_scope = env.find_module(self.module_name, self.pos)
4567         env.add_imported_module(module_scope)
4568         for pos, name, as_name, kind in self.imported_names:
4569             if name == "*":
4570                 for local_name, entry in module_scope.entries.items():
4571                     env.add_imported_entry(local_name, entry, pos)
4572             else:
4573                 entry = module_scope.lookup(name)
4574                 if entry:
4575                     if kind and not self.declaration_matches(entry, kind):
4576                         entry.redeclared(pos)
4577                 else:
4578                     if kind == 'struct' or kind == 'union':
4579                         entry = module_scope.declare_struct_or_union(name,
4580                             kind = kind, scope = None, typedef_flag = 0, pos = pos)
4581                     elif kind == 'class':
4582                         entry = module_scope.declare_c_class(name, pos = pos,
4583                             module_name = self.module_name)
4584                     else:
4585                         submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4586                         if submodule_scope.parent_module is module_scope:
4587                             env.declare_module(as_name or name, submodule_scope, self.pos)
4588                         else:
4589                             error(pos, "Name '%s' not declared in module '%s'"
4590                                 % (name, self.module_name))
4591                         
4592                 if entry:
4593                     local_name = as_name or name
4594                     env.add_imported_entry(local_name, entry, pos)
4595     
4596     def declaration_matches(self, entry, kind):
4597         if not entry.is_type:
4598             return 0
4599         type = entry.type
4600         if kind == 'class':
4601             if not type.is_extension_type:
4602                 return 0
4603         else:
4604             if not type.is_struct_or_union:
4605                 return 0
4606             if kind != type.kind:
4607                 return 0
4608         return 1
4609
4610     def analyse_expressions(self, env):
4611         pass
4612     
4613     def generate_execution_code(self, code):
4614         pass
4615
4616
4617 class FromImportStatNode(StatNode):
4618     #  from ... import statement
4619     #
4620     #  module           ImportNode
4621     #  items            [(string, NameNode)]
4622     #  interned_items   [(string, NameNode, ExprNode)]
4623     #  item             PyTempNode            used internally
4624     #  import_star      boolean               used internally
4625
4626     child_attrs = ["module"]
4627     import_star = 0
4628     
4629     def analyse_declarations(self, env):
4630         for name, target in self.items:
4631             if name == "*":
4632                 if not env.is_module_scope:
4633                     error(self.pos, "import * only allowed at module level")
4634                     return
4635                 env.has_import_star = 1
4636                 self.import_star = 1
4637             else:
4638                 target.analyse_target_declaration(env)
4639     
4640     def analyse_expressions(self, env):
4641         import ExprNodes
4642         self.module.analyse_expressions(env)
4643         self.item = ExprNodes.PyTempNode(self.pos, env)
4644         self.interned_items = []
4645         for name, target in self.items:
4646             if name == '*':
4647                 for _, entry in env.entries.items():
4648                     if not entry.is_type and entry.type.is_extension_type:
4649                         env.use_utility_code(ExprNodes.type_test_utility_code)
4650                         break
4651             else:
4652                 entry =  env.lookup(target.name)
4653                 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4654                     continue # already cimported
4655                 target.analyse_target_expression(env, None)
4656                 if target.type is py_object_type:
4657                     coerced_item = None
4658                 else:
4659                     coerced_item = self.item.coerce_to(target.type, env)
4660                 self.interned_items.append(
4661                     (name, target, coerced_item))
4662     
4663     def generate_execution_code(self, code):
4664         self.module.generate_evaluation_code(code)
4665         if self.import_star:
4666             code.putln(
4667                 'if (%s(%s) < 0) %s;' % (
4668                     Naming.import_star,
4669                     self.module.py_result(),
4670                     code.error_goto(self.pos)))
4671         self.item.allocate(code)
4672         for name, target, coerced_item in self.interned_items:
4673             cname = code.intern_identifier(name)
4674             code.putln(
4675                 '%s = PyObject_GetAttr(%s, %s); %s' % (
4676                     self.item.result(), 
4677                     self.module.py_result(),
4678                     cname,
4679                     code.error_goto_if_null(self.item.result(), self.pos)))
4680             code.put_gotref(self.item.py_result())
4681             if coerced_item is None:
4682                 target.generate_assignment_code(self.item, code)
4683             else:
4684                 coerced_item.allocate_temp_result(code)
4685                 coerced_item.generate_result_code(code)
4686                 target.generate_assignment_code(coerced_item, code)
4687                 if self.item.result() != coerced_item.result():
4688                     code.put_decref_clear(self.item.result(), self.item.type)
4689         self.item.release(code)
4690         self.module.generate_disposal_code(code)
4691         self.module.free_temps(code)
4692
4693
4694
4695 #------------------------------------------------------------------------------------
4696 #
4697 #  Runtime support code
4698 #
4699 #------------------------------------------------------------------------------------
4700
4701 utility_function_predeclarations = \
4702 """
4703 #ifdef __GNUC__
4704 #define INLINE __inline__
4705 #elif _WIN32
4706 #define INLINE __inline
4707 #else
4708 #define INLINE 
4709 #endif
4710
4711 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4712
4713 """ + """
4714
4715 static int %(skip_dispatch_cname)s = 0;
4716
4717 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4718
4719 if Options.gcc_branch_hints:
4720     branch_prediction_macros = \
4721     """
4722 #ifdef __GNUC__
4723 /* Test for GCC > 2.95 */
4724 #if __GNUC__ > 2 || \
4725               (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) 
4726 #define likely(x)   __builtin_expect(!!(x), 1)
4727 #define unlikely(x) __builtin_expect(!!(x), 0)
4728 #else /* __GNUC__ > 2 ... */
4729 #define likely(x)   (x)
4730 #define unlikely(x) (x)
4731 #endif /* __GNUC__ > 2 ... */
4732 #else /* __GNUC__ */
4733 #define likely(x)   (x)
4734 #define unlikely(x) (x)
4735 #endif /* __GNUC__ */
4736     """
4737 else:
4738     branch_prediction_macros = \
4739     """
4740 #define likely(x)   (x)
4741 #define unlikely(x) (x)
4742     """
4743
4744 #get_name_predeclaration = \
4745 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4746
4747 #get_name_interned_predeclaration = \
4748 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4749
4750 #------------------------------------------------------------------------------------
4751
4752 printing_utility_code = UtilityCode(
4753 proto = """
4754 static int __Pyx_Print(PyObject *, int); /*proto*/
4755 #if PY_MAJOR_VERSION >= 3
4756 static PyObject* %s = 0;
4757 static PyObject* %s = 0;
4758 #endif
4759 """ % (Naming.print_function, Naming.print_function_kwargs),
4760 impl = r"""
4761 #if PY_MAJOR_VERSION < 3
4762 static PyObject *__Pyx_GetStdout(void) {
4763     PyObject *f = PySys_GetObject((char *)"stdout");
4764     if (!f) {
4765         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4766     }
4767     return f;
4768 }
4769
4770 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4771     PyObject *f;
4772     PyObject* v;
4773     int i;
4774
4775     if (!(f = __Pyx_GetStdout()))
4776         return -1;
4777     for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4778         if (PyFile_SoftSpace(f, 1)) {
4779             if (PyFile_WriteString(" ", f) < 0)
4780                 return -1;
4781         }
4782         v = PyTuple_GET_ITEM(arg_tuple, i);
4783         if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4784             return -1;
4785         if (PyString_Check(v)) {
4786             char *s = PyString_AsString(v);
4787             Py_ssize_t len = PyString_Size(v);
4788             if (len > 0 &&
4789                 isspace(Py_CHARMASK(s[len-1])) &&
4790                 s[len-1] != ' ')
4791                     PyFile_SoftSpace(f, 0);
4792         }
4793     }
4794     if (newline) {
4795         if (PyFile_WriteString("\n", f) < 0)
4796             return -1;
4797         PyFile_SoftSpace(f, 0);
4798     }
4799     return 0;
4800 }
4801
4802 #else /* Python 3 has a print function */
4803
4804 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4805     PyObject* kwargs = 0;
4806     PyObject* result = 0;
4807     PyObject* end_string;
4808     if (!%(PRINT_FUNCTION)s) {
4809         %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4810         if (!%(PRINT_FUNCTION)s)
4811             return -1;
4812     }
4813     if (!newline) {
4814         if (!%(PRINT_KWARGS)s) {
4815             %(PRINT_KWARGS)s = PyDict_New();
4816             if (!%(PRINT_KWARGS)s)
4817                 return -1;
4818             end_string = PyUnicode_FromStringAndSize(" ", 1);
4819             if (!end_string)
4820                 return -1;
4821             if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4822                 Py_DECREF(end_string);
4823                 return -1;
4824             }
4825             Py_DECREF(end_string);
4826         }
4827         kwargs = %(PRINT_KWARGS)s;
4828     }
4829     result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4830     if (!result)
4831         return -1;
4832     Py_DECREF(result);
4833     return 0;
4834 }
4835
4836 #endif
4837 """ % {'BUILTINS'       : Naming.builtins_cname,
4838        'PRINT_FUNCTION' : Naming.print_function,
4839        'PRINT_KWARGS'   : Naming.print_function_kwargs}
4840 )
4841
4842
4843 printing_one_utility_code = UtilityCode(
4844 proto = """
4845 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4846 """,
4847 impl = r"""
4848 #if PY_MAJOR_VERSION < 3
4849
4850 static int __Pyx_PrintOne(PyObject *o) {
4851     PyObject *f;
4852     if (!(f = __Pyx_GetStdout()))
4853         return -1;
4854     if (PyFile_SoftSpace(f, 0)) {
4855         if (PyFile_WriteString(" ", f) < 0)
4856             return -1;
4857     }
4858     if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4859         return -1;
4860     if (PyFile_WriteString("\n", f) < 0)
4861         return -1;
4862     return 0;
4863     /* the line below is just to avoid compiler
4864      * compiler warnings about unused functions */
4865     return __Pyx_Print(NULL, 0);
4866 }
4867
4868 #else /* Python 3 has a print function */
4869
4870 static int __Pyx_PrintOne(PyObject *o) {
4871     int res;
4872     PyObject* arg_tuple = PyTuple_New(1);
4873     if (unlikely(!arg_tuple))
4874         return -1;
4875     Py_INCREF(o);
4876     PyTuple_SET_ITEM(arg_tuple, 0, o);
4877     res = __Pyx_Print(arg_tuple, 1);
4878     Py_DECREF(arg_tuple);
4879     return res;
4880 }
4881
4882 #endif
4883 """,
4884 requires=[printing_utility_code])
4885
4886
4887
4888 #------------------------------------------------------------------------------------
4889
4890 # The following function is based on do_raise() from ceval.c.
4891
4892 raise_utility_code = UtilityCode(
4893 proto = """
4894 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4895 """,
4896 impl = """
4897 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4898     Py_XINCREF(type);
4899     Py_XINCREF(value);
4900     Py_XINCREF(tb);
4901     /* First, check the traceback argument, replacing None with NULL. */
4902     if (tb == Py_None) {
4903         Py_DECREF(tb);
4904         tb = 0;
4905     }
4906     else if (tb != NULL && !PyTraceBack_Check(tb)) {
4907         PyErr_SetString(PyExc_TypeError,
4908             "raise: arg 3 must be a traceback or None");
4909         goto raise_error;
4910     }
4911     /* Next, replace a missing value with None */
4912     if (value == NULL) {
4913         value = Py_None;
4914         Py_INCREF(value);
4915     }
4916     #if PY_VERSION_HEX < 0x02050000
4917     if (!PyClass_Check(type))
4918     #else
4919     if (!PyType_Check(type))
4920     #endif
4921     {
4922         /* Raising an instance.  The value should be a dummy. */
4923         if (value != Py_None) {
4924             PyErr_SetString(PyExc_TypeError,
4925                 "instance exception may not have a separate value");
4926             goto raise_error;
4927         }
4928         /* Normalize to raise <class>, <instance> */
4929         Py_DECREF(value);
4930         value = type;
4931         #if PY_VERSION_HEX < 0x02050000
4932             if (PyInstance_Check(type)) {
4933                 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4934                 Py_INCREF(type);
4935             }
4936             else {
4937                 type = 0;
4938                 PyErr_SetString(PyExc_TypeError,
4939                     "raise: exception must be an old-style class or instance");
4940                 goto raise_error;
4941             }
4942         #else
4943             type = (PyObject*) Py_TYPE(type);
4944             Py_INCREF(type);
4945             if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4946                 PyErr_SetString(PyExc_TypeError,
4947                     "raise: exception class must be a subclass of BaseException");
4948                 goto raise_error;
4949             }
4950         #endif
4951     }
4952     __Pyx_ErrRestore(type, value, tb);
4953     return;
4954 raise_error:
4955     Py_XDECREF(value);
4956     Py_XDECREF(type);
4957     Py_XDECREF(tb);
4958     return;
4959 }
4960 """)
4961
4962 #------------------------------------------------------------------------------------
4963
4964 reraise_utility_code = UtilityCode(
4965 proto = """
4966 static void __Pyx_ReRaise(void); /*proto*/
4967 """,
4968 impl = """
4969 static void __Pyx_ReRaise(void) {
4970     PyThreadState *tstate = PyThreadState_GET();
4971     PyObject* tmp_type = tstate->curexc_type;
4972     PyObject* tmp_value = tstate->curexc_value;
4973     PyObject* tmp_tb = tstate->curexc_traceback;
4974     tstate->curexc_type = tstate->exc_type;
4975     tstate->curexc_value = tstate->exc_value;
4976     tstate->curexc_traceback = tstate->exc_traceback;
4977     tstate->exc_type = 0;
4978     tstate->exc_value = 0;
4979     tstate->exc_traceback = 0;
4980     Py_XDECREF(tmp_type);
4981     Py_XDECREF(tmp_value);
4982     Py_XDECREF(tmp_tb);
4983 }
4984 """)
4985
4986 #------------------------------------------------------------------------------------
4987
4988 arg_type_test_utility_code = UtilityCode(
4989 proto = """
4990 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4991     const char *name, int exact); /*proto*/
4992 """,
4993 impl = """
4994 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4995     const char *name, int exact)
4996 {
4997     if (!type) {
4998         PyErr_Format(PyExc_SystemError, "Missing type object");
4999         return 0;
5000     }
5001     if (none_allowed && obj == Py_None) return 1;
5002     else if (exact) {
5003         if (Py_TYPE(obj) == type) return 1;
5004     }
5005     else {
5006         if (PyObject_TypeCheck(obj, type)) return 1;
5007     }
5008     PyErr_Format(PyExc_TypeError,
5009         "Argument '%s' has incorrect type (expected %s, got %s)",
5010         name, type->tp_name, Py_TYPE(obj)->tp_name);
5011     return 0;
5012 }
5013 """)
5014
5015 #------------------------------------------------------------------------------------
5016 #
5017 #  __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5018 #  many or too few positional arguments were found.  This handles
5019 #  Py_ssize_t formatting correctly.
5020
5021 raise_argtuple_invalid_utility_code = UtilityCode(
5022 proto = """
5023 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5024     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5025 """,
5026 impl = """
5027 static void __Pyx_RaiseArgtupleInvalid(
5028     const char* func_name,
5029     int exact,
5030     Py_ssize_t num_min,
5031     Py_ssize_t num_max,
5032     Py_ssize_t num_found)
5033 {
5034     Py_ssize_t num_expected;
5035     const char *number, *more_or_less;
5036
5037     if (num_found < num_min) {
5038         num_expected = num_min;
5039         more_or_less = "at least";
5040     } else {
5041         num_expected = num_max;
5042         more_or_less = "at most";
5043     }
5044     if (exact) {
5045         more_or_less = "exactly";
5046     }
5047     number = (num_expected == 1) ? "" : "s";
5048     PyErr_Format(PyExc_TypeError,
5049         #if PY_VERSION_HEX < 0x02050000
5050             "%s() takes %s %d positional argument%s (%d given)",
5051         #else
5052             "%s() takes %s %zd positional argument%s (%zd given)",
5053         #endif
5054         func_name, more_or_less, num_expected, number, num_found);
5055 }
5056 """)
5057
5058 raise_keyword_required_utility_code = UtilityCode(
5059 proto = """
5060 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5061 """,
5062 impl = """
5063 static INLINE void __Pyx_RaiseKeywordRequired(
5064     const char* func_name,
5065     PyObject* kw_name)
5066 {
5067     PyErr_Format(PyExc_TypeError,
5068         #if PY_MAJOR_VERSION >= 3
5069         "%s() needs keyword-only argument %U", func_name, kw_name);
5070         #else
5071         "%s() needs keyword-only argument %s", func_name,
5072         PyString_AS_STRING(kw_name));
5073         #endif
5074 }
5075 """)
5076
5077 raise_double_keywords_utility_code = UtilityCode(
5078 proto = """
5079 static void __Pyx_RaiseDoubleKeywordsError(
5080     const char* func_name, PyObject* kw_name); /*proto*/
5081 """,
5082 impl = """
5083 static void __Pyx_RaiseDoubleKeywordsError(
5084     const char* func_name,
5085     PyObject* kw_name)
5086 {
5087     PyErr_Format(PyExc_TypeError,
5088         #if PY_MAJOR_VERSION >= 3
5089         "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5090         #else
5091         "%s() got multiple values for keyword argument '%s'", func_name,
5092         PyString_AS_STRING(kw_name));
5093         #endif
5094 }
5095 """)
5096
5097 #------------------------------------------------------------------------------------
5098 #
5099 #  __Pyx_CheckKeywordStrings raises an error if non-string keywords
5100 #  were passed to a function, or if any keywords were passed to a
5101 #  function that does not accept them.
5102
5103 keyword_string_check_utility_code = UtilityCode(
5104 proto = """
5105 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5106     const char* function_name, int kw_allowed); /*proto*/
5107 """,
5108 impl = """
5109 static INLINE int __Pyx_CheckKeywordStrings(
5110     PyObject *kwdict,
5111     const char* function_name,
5112     int kw_allowed)
5113 {
5114     PyObject* key = 0;
5115     Py_ssize_t pos = 0;
5116     while (PyDict_Next(kwdict, &pos, &key, 0)) {
5117         #if PY_MAJOR_VERSION < 3
5118         if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5119         #else
5120         if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5121         #endif
5122             goto invalid_keyword_type;
5123     }
5124     if ((!kw_allowed) && unlikely(key))
5125         goto invalid_keyword;
5126     return 1;
5127 invalid_keyword_type:
5128     PyErr_Format(PyExc_TypeError,
5129         "%s() keywords must be strings", function_name);
5130     return 0;
5131 invalid_keyword:
5132     PyErr_Format(PyExc_TypeError,
5133     #if PY_MAJOR_VERSION < 3
5134         "%s() got an unexpected keyword argument '%s'",
5135         function_name, PyString_AsString(key));
5136     #else
5137         "%s() got an unexpected keyword argument '%U'",
5138         function_name, key);
5139     #endif
5140     return 0;
5141 }
5142 """)
5143
5144 #------------------------------------------------------------------------------------
5145 #
5146 #  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5147 #  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
5148 #  keywords will raise an invalid keyword error.
5149 #
5150 #  Three kinds of errors are checked: 1) non-string keywords, 2)
5151 #  unexpected keywords and 3) overlap with positional arguments.
5152 #
5153 #  If num_posargs is greater 0, it denotes the number of positional
5154 #  arguments that were passed and that must therefore not appear
5155 #  amongst the keywords as well.
5156 #
5157 #  This method does not check for required keyword arguments.
5158 #
5159
5160 parse_keywords_utility_code = UtilityCode(
5161 proto = """
5162 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5163     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5164     const char* function_name); /*proto*/
5165 """,
5166 impl = """
5167 static int __Pyx_ParseOptionalKeywords(
5168     PyObject *kwds,
5169     PyObject **argnames[],
5170     PyObject *kwds2,
5171     PyObject *values[],
5172     Py_ssize_t num_pos_args,
5173     const char* function_name)
5174 {
5175     PyObject *key = 0, *value = 0;
5176     Py_ssize_t pos = 0;
5177     PyObject*** name;
5178     PyObject*** first_kw_arg = argnames + num_pos_args;
5179
5180     while (PyDict_Next(kwds, &pos, &key, &value)) {
5181         name = first_kw_arg;
5182         while (*name && (**name != key)) name++;
5183         if (*name) {
5184             values[name-argnames] = value;
5185         } else {
5186             #if PY_MAJOR_VERSION < 3
5187             if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5188             #else
5189             if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5190             #endif
5191                 goto invalid_keyword_type;
5192             } else {
5193                 for (name = first_kw_arg; *name; name++) {
5194                     #if PY_MAJOR_VERSION >= 3
5195                     if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5196                         PyUnicode_Compare(**name, key) == 0) break;
5197                     #else
5198                     if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5199                         _PyString_Eq(**name, key)) break;
5200                     #endif
5201                 }
5202                 if (*name) {
5203                     values[name-argnames] = value;
5204                 } else {
5205                     /* unexpected keyword found */
5206                     for (name=argnames; name != first_kw_arg; name++) {
5207                         if (**name == key) goto arg_passed_twice;
5208                         #if PY_MAJOR_VERSION >= 3
5209                         if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5210                             PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5211                         #else
5212                         if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5213                             _PyString_Eq(**name, key)) goto arg_passed_twice;
5214                         #endif
5215                     }
5216                     if (kwds2) {
5217                         if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5218                     } else {
5219                         goto invalid_keyword;
5220                     }
5221                 }
5222             }
5223         }
5224     }
5225     return 0;
5226 arg_passed_twice:
5227     __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5228     goto bad;
5229 invalid_keyword_type:
5230     PyErr_Format(PyExc_TypeError,
5231         "%s() keywords must be strings", function_name);
5232     goto bad;
5233 invalid_keyword:
5234     PyErr_Format(PyExc_TypeError,
5235     #if PY_MAJOR_VERSION < 3
5236         "%s() got an unexpected keyword argument '%s'",
5237         function_name, PyString_AsString(key));
5238     #else
5239         "%s() got an unexpected keyword argument '%U'",
5240         function_name, key);
5241     #endif
5242 bad:
5243     return -1;
5244 }
5245 """)
5246
5247 #------------------------------------------------------------------------------------
5248
5249 traceback_utility_code = UtilityCode(
5250 proto = """
5251 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5252 """,
5253 impl = """
5254 #include "compile.h"
5255 #include "frameobject.h"
5256 #include "traceback.h"
5257
5258 static void __Pyx_AddTraceback(const char *funcname) {
5259     PyObject *py_srcfile = 0;
5260     PyObject *py_funcname = 0;
5261     PyObject *py_globals = 0;
5262     PyObject *empty_string = 0;
5263     PyCodeObject *py_code = 0;
5264     PyFrameObject *py_frame = 0;
5265
5266     #if PY_MAJOR_VERSION < 3
5267     py_srcfile = PyString_FromString(%(FILENAME)s);
5268     #else
5269     py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5270     #endif
5271     if (!py_srcfile) goto bad;
5272     if (%(CLINENO)s) {
5273         #if PY_MAJOR_VERSION < 3
5274         py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5275         #else
5276         py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5277         #endif
5278     }
5279     else {
5280         #if PY_MAJOR_VERSION < 3
5281         py_funcname = PyString_FromString(funcname);
5282         #else
5283         py_funcname = PyUnicode_FromString(funcname);
5284         #endif
5285     }
5286     if (!py_funcname) goto bad;
5287     py_globals = PyModule_GetDict(%(GLOBALS)s);
5288     if (!py_globals) goto bad;
5289     #if PY_MAJOR_VERSION < 3
5290     empty_string = PyString_FromStringAndSize("", 0);
5291     #else
5292     empty_string = PyBytes_FromStringAndSize("", 0);
5293     #endif
5294     if (!empty_string) goto bad;
5295     py_code = PyCode_New(
5296         0,            /*int argcount,*/
5297         #if PY_MAJOR_VERSION >= 3
5298         0,            /*int kwonlyargcount,*/
5299         #endif
5300         0,            /*int nlocals,*/
5301         0,            /*int stacksize,*/
5302         0,            /*int flags,*/
5303         empty_string, /*PyObject *code,*/
5304         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
5305         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
5306         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
5307         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
5308         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
5309         py_srcfile,   /*PyObject *filename,*/
5310         py_funcname,  /*PyObject *name,*/
5311         %(LINENO)s,   /*int firstlineno,*/
5312         empty_string  /*PyObject *lnotab*/
5313     );
5314     if (!py_code) goto bad;
5315     py_frame = PyFrame_New(
5316         PyThreadState_GET(), /*PyThreadState *tstate,*/
5317         py_code,             /*PyCodeObject *code,*/
5318         py_globals,          /*PyObject *globals,*/
5319         0                    /*PyObject *locals*/
5320     );
5321     if (!py_frame) goto bad;
5322     py_frame->f_lineno = %(LINENO)s;
5323     PyTraceBack_Here(py_frame);
5324 bad:
5325     Py_XDECREF(py_srcfile);
5326     Py_XDECREF(py_funcname);
5327     Py_XDECREF(empty_string);
5328     Py_XDECREF(py_code);
5329     Py_XDECREF(py_frame);
5330 }
5331 """ % {
5332     'FILENAME': Naming.filename_cname,
5333     'LINENO':  Naming.lineno_cname,
5334     'CFILENAME': Naming.cfilenm_cname,
5335     'CLINENO':  Naming.clineno_cname,
5336     'GLOBALS': Naming.module_cname,
5337     'EMPTY_TUPLE' : Naming.empty_tuple,
5338 })
5339
5340 restore_exception_utility_code = UtilityCode(
5341 proto = """
5342 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5343 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5344 """,
5345 impl = """
5346 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5347     PyObject *tmp_type, *tmp_value, *tmp_tb;
5348     PyThreadState *tstate = PyThreadState_GET();
5349
5350 #if PY_MAJOR_VERSION >= 3
5351     /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5352     if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5353         tmp_type = tstate->exc_type;
5354         tmp_value = tstate->exc_value;
5355         tmp_tb = tstate->exc_traceback;
5356         PyErr_NormalizeException(&type, &value, &tb);
5357         PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5358         tstate->exc_type = 0;
5359         tstate->exc_value = 0;
5360         tstate->exc_traceback = 0;
5361         PyException_SetContext(value, tmp_value);
5362         Py_DECREF(tmp_type);
5363         Py_XDECREF(tmp_tb);
5364     }
5365 #endif
5366
5367     tmp_type = tstate->curexc_type;
5368     tmp_value = tstate->curexc_value;
5369     tmp_tb = tstate->curexc_traceback;
5370     tstate->curexc_type = type;
5371     tstate->curexc_value = value;
5372     tstate->curexc_traceback = tb;
5373     Py_XDECREF(tmp_type);
5374     Py_XDECREF(tmp_value);
5375     Py_XDECREF(tmp_tb);
5376 }
5377
5378 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5379     PyThreadState *tstate = PyThreadState_GET();
5380     *type = tstate->curexc_type;
5381     *value = tstate->curexc_value;
5382     *tb = tstate->curexc_traceback;
5383
5384     tstate->curexc_type = 0;
5385     tstate->curexc_value = 0;
5386     tstate->curexc_traceback = 0;
5387 }
5388
5389 """)
5390
5391 #------------------------------------------------------------------------------------
5392
5393 unraisable_exception_utility_code = UtilityCode(
5394 proto = """
5395 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5396 """,
5397 impl = """
5398 static void __Pyx_WriteUnraisable(const char *name) {
5399     PyObject *old_exc, *old_val, *old_tb;
5400     PyObject *ctx;
5401     __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5402     #if PY_MAJOR_VERSION < 3
5403     ctx = PyString_FromString(name);
5404     #else
5405     ctx = PyUnicode_FromString(name);
5406     #endif
5407     __Pyx_ErrRestore(old_exc, old_val, old_tb);
5408     if (!ctx) {
5409         PyErr_WriteUnraisable(Py_None);
5410     } else {
5411         PyErr_WriteUnraisable(ctx);
5412         Py_DECREF(ctx);
5413     }
5414 }
5415 """,
5416 requires=[restore_exception_utility_code])
5417
5418 #------------------------------------------------------------------------------------
5419
5420 set_vtable_utility_code = UtilityCode(
5421 proto = """
5422 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5423 """,
5424 impl = """
5425 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5426     PyObject *pycobj = 0;
5427     int result;
5428     
5429     pycobj = PyCObject_FromVoidPtr(vtable, 0);
5430     if (!pycobj)
5431         goto bad;
5432     if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5433         goto bad;
5434     result = 0;
5435     goto done;
5436
5437 bad:
5438     result = -1;
5439 done:
5440     Py_XDECREF(pycobj);
5441     return result;
5442 }
5443 """)
5444
5445 #------------------------------------------------------------------------------------
5446
5447 get_vtable_utility_code = UtilityCode(
5448 proto = """
5449 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5450 """,
5451 impl = r"""
5452 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5453     int result;
5454     PyObject *pycobj;
5455
5456     pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5457     if (!pycobj)
5458         goto bad;
5459     *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5460     if (!*(void **)vtabptr)
5461         goto bad;
5462     result = 0;
5463     goto done;
5464
5465 bad:
5466     result = -1;
5467 done:
5468     Py_XDECREF(pycobj);
5469     return result;
5470 }
5471 """)
5472
5473 #------------------------------------------------------------------------------------
5474
5475 init_string_tab_utility_code = UtilityCode(
5476 proto = """
5477 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5478 """,
5479 impl = """
5480 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5481     while (t->p) {
5482         #if PY_MAJOR_VERSION < 3
5483         if (t->is_unicode && (!t->is_identifier)) {
5484             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5485         } else if (t->intern) {
5486             *t->p = PyString_InternFromString(t->s);
5487         } else {
5488             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5489         }
5490         #else  /* Python 3+ has unicode identifiers */
5491         if (t->is_identifier || (t->is_unicode && t->intern)) {
5492             *t->p = PyUnicode_InternFromString(t->s);
5493         } else if (t->is_unicode) {
5494             *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5495         } else {
5496             *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5497         }
5498         #endif
5499         if (!*t->p)
5500             return -1;
5501         ++t;
5502     }
5503     return 0;
5504 }
5505 """)
5506
5507 #------------------------------------------------------------------------------------
5508
5509 get_exception_utility_code = UtilityCode(
5510 proto = """
5511 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5512 """,
5513 impl = """
5514 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5515     PyObject *tmp_type, *tmp_value, *tmp_tb;
5516     PyThreadState *tstate = PyThreadState_GET();
5517     *type = tstate->curexc_type;
5518     *value = tstate->curexc_value;
5519     *tb = tstate->curexc_traceback;
5520     tstate->curexc_type = 0;
5521     tstate->curexc_value = 0;
5522     tstate->curexc_traceback = 0;
5523     PyErr_NormalizeException(type, value, tb);
5524     if (PyErr_Occurred())
5525         goto bad;
5526     Py_INCREF(*type);
5527     Py_INCREF(*value);
5528     Py_INCREF(*tb);
5529     tmp_type = tstate->exc_type;
5530     tmp_value = tstate->exc_value;
5531     tmp_tb = tstate->exc_traceback;
5532     tstate->exc_type = *type;
5533     tstate->exc_value = *value;
5534     tstate->exc_traceback = *tb;
5535     /* Make sure tstate is in a consistent state when we XDECREF
5536     these objects (XDECREF may run arbitrary code). */
5537     Py_XDECREF(tmp_type);
5538     Py_XDECREF(tmp_value);
5539     Py_XDECREF(tmp_tb);
5540     return 0;
5541 bad:
5542     Py_XDECREF(*type);
5543     Py_XDECREF(*value);
5544     Py_XDECREF(*tb);
5545     return -1;
5546 }
5547
5548 """)
5549
5550 #------------------------------------------------------------------------------------
5551
5552 reset_exception_utility_code = UtilityCode(
5553 proto = """
5554 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5555 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5556 """,
5557 impl = """
5558 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5559     PyThreadState *tstate = PyThreadState_GET();
5560     *type = tstate->exc_type;
5561     *value = tstate->exc_value;
5562     *tb = tstate->exc_traceback;
5563     Py_XINCREF(*type);
5564     Py_XINCREF(*value);
5565     Py_XINCREF(*tb);
5566 }
5567
5568 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5569     PyObject *tmp_type, *tmp_value, *tmp_tb;
5570     PyThreadState *tstate = PyThreadState_GET();
5571     tmp_type = tstate->exc_type;
5572     tmp_value = tstate->exc_value;
5573     tmp_tb = tstate->exc_traceback;
5574     tstate->exc_type = type;
5575     tstate->exc_value = value;
5576     tstate->exc_traceback = tb;
5577     Py_XDECREF(tmp_type);
5578     Py_XDECREF(tmp_value);
5579     Py_XDECREF(tmp_tb);
5580 }
5581 """)
5582
5583 #------------------------------------------------------------------------------------
5584
5585 force_init_threads_utility_code = UtilityCode(
5586 proto="""
5587 #ifndef __PYX_FORCE_INIT_THREADS
5588 #if PY_VERSION_HEX < 0x02040200
5589 #define __PYX_FORCE_INIT_THREADS 1
5590 #else
5591 #define __PYX_FORCE_INIT_THREADS 0
5592 #endif
5593 #endif
5594 """)
5595
5596 #------------------------------------------------------------------------------------