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