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