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