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