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