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