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