Merged pull request #12 from bhy/T423.
[cython.git] / Cython / Compiler / Nodes.py
1
2 #
3 #   Pyrex - Parse tree nodes
4 #
5
6 import cython
7 from cython import set
8 cython.declare(sys=object, os=object, time=object, copy=object,
9                Builtin=object, error=object, warning=object, Naming=object, PyrexTypes=object,
10                py_object_type=object, ModuleScope=object, LocalScope=object, ClosureScope=object, \
11                StructOrUnionScope=object, PyClassScope=object, CClassScope=object,
12                CppClassScope=object, UtilityCode=object, EncodedString=object,
13                absolute_path_length=cython.Py_ssize_t)
14
15 import sys, os, time, copy
16
17 import Builtin
18 from Errors import error, warning, InternalError
19 import Naming
20 import PyrexTypes
21 import TypeSlots
22 from PyrexTypes import py_object_type, error_type, CFuncType
23 from Symtab import ModuleScope, LocalScope, ClosureScope, \
24     StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
25 from Cython.Utils import open_new_file, replace_suffix
26 from Code import UtilityCode, ClosureTempAllocator
27 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
28 import Options
29 import ControlFlow
30 import DebugFlags
31
32 absolute_path_length = 0
33
34 def relative_position(pos):
35     """
36     We embed the relative filename in the generated C file, since we
37     don't want to have to regnerate and compile all the source code
38     whenever the Python install directory moves (which could happen,
39     e.g,. when distributing binaries.)
40
41     INPUT:
42         a position tuple -- (absolute filename, line number column position)
43
44     OUTPUT:
45         relative filename
46         line number
47
48     AUTHOR: William Stein
49     """
50     global absolute_path_length
51     if absolute_path_length==0:
52         absolute_path_length = len(os.path.abspath(os.getcwd()))
53     return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
54
55 def embed_position(pos, docstring):
56     if not Options.embed_pos_in_docstring:
57         return docstring
58     pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
59     if docstring is None:
60         # unicode string
61         return EncodedString(pos_line)
62
63     # make sure we can encode the filename in the docstring encoding
64     # otherwise make the docstring a unicode string
65     encoding = docstring.encoding
66     if encoding is not None:
67         try:
68             encoded_bytes = pos_line.encode(encoding)
69         except UnicodeEncodeError:
70             encoding = None
71
72     if not docstring:
73         # reuse the string encoding of the original docstring
74         doc = EncodedString(pos_line)
75     else:
76         doc = EncodedString(pos_line + u'\n' + docstring)
77     doc.encoding = encoding
78     return doc
79
80
81 from Code import CCodeWriter
82 from types import FunctionType
83
84 def write_func_call(func):
85     def f(*args, **kwds):
86         if len(args) > 1 and isinstance(args[1], CCodeWriter):
87             # here we annotate the code with this function call
88             # but only if new code is generated
89             node, code = args[:2]
90             marker = '                    /* %s -> %s.%s %s */' % (
91                     ' ' * code.call_level,
92                     node.__class__.__name__,
93                     func.__name__,
94                     node.pos[1:])
95             pristine = code.buffer.stream.tell()
96             code.putln(marker)
97             start = code.buffer.stream.tell()
98             code.call_level += 4
99             res = func(*args, **kwds)
100             code.call_level -= 4
101             if start == code.buffer.stream.tell():
102                 code.buffer.stream.seek(pristine)
103             else:
104                 marker = marker.replace('->', '<-')
105                 code.putln(marker)
106             return res
107         else:
108             return func(*args, **kwds)
109     return f
110
111 class VerboseCodeWriter(type):
112     # Set this as a metaclass to trace function calls in code.
113     # This slows down code generation and makes much larger files.
114     def __new__(cls, name, bases, attrs):
115         attrs = dict(attrs)
116         for mname, m in attrs.items():
117             if isinstance(m, FunctionType):
118                 attrs[mname] = write_func_call(m)
119         return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
120
121
122 class Node(object):
123     #  pos         (string, int, int)   Source file position
124     #  is_name     boolean              Is a NameNode
125     #  is_literal  boolean              Is a ConstNode
126
127     if DebugFlags.debug_trace_code_generation:
128         __metaclass__ = VerboseCodeWriter
129
130     is_name = 0
131     is_literal = 0
132     temps = None
133
134     # All descandants should set child_attrs to a list of the attributes
135     # containing nodes considered "children" in the tree. Each such attribute
136     # can either contain a single node or a list of nodes. See Visitor.py.
137     child_attrs = None
138
139     def __init__(self, pos, **kw):
140         self.pos = pos
141         self.__dict__.update(kw)
142
143     gil_message = "Operation"
144
145     nogil_check = None
146
147     def gil_error(self, env=None):
148         error(self.pos, "%s not allowed without gil" % self.gil_message)
149
150     cpp_message = "Operation"
151
152     def cpp_check(self, env):
153         if not env.is_cpp():
154             self.cpp_error()
155
156     def cpp_error(self):
157         error(self.pos, "%s only allowed in c++" % self.cpp_message)
158
159     def clone_node(self):
160         """Clone the node. This is defined as a shallow copy, except for member lists
161            amongst the child attributes (from get_child_accessors) which are also
162            copied. Lists containing child nodes are thus seen as a way for the node
163            to hold multiple children directly; the list is not treated as a seperate
164            level in the tree."""
165         result = copy.copy(self)
166         for attrname in result.child_attrs:
167             value = getattr(result, attrname)
168             if isinstance(value, list):
169                 setattr(result, attrname, [x for x in value])
170         return result
171
172
173     #
174     #  There are 4 phases of parse tree processing, applied in order to
175     #  all the statements in a given scope-block:
176     #
177     #  (0) analyse_control_flow
178     #        Create the control flow tree into which state can be asserted and
179     #        queried.
180     #
181     #  (1) analyse_declarations
182     #        Make symbol table entries for all declarations at the current
183     #        level, both explicit (def, cdef, etc.) and implicit (assignment
184     #        to an otherwise undeclared name).
185     #
186     #  (2) analyse_expressions
187     #         Determine the result types of expressions and fill in the
188     #         'type' attribute of each ExprNode. Insert coercion nodes into the
189     #         tree where needed to convert to and from Python objects.
190     #         Allocate temporary locals for intermediate results. Fill
191     #         in the 'result_code' attribute of each ExprNode with a C code
192     #         fragment.
193     #
194     #  (3) generate_code
195     #         Emit C code for all declarations, statements and expressions.
196     #         Recursively applies the 3 processing phases to the bodies of
197     #         functions.
198     #
199
200     def analyse_control_flow(self, env):
201         pass
202
203     def analyse_declarations(self, env):
204         pass
205
206     def analyse_expressions(self, env):
207         raise InternalError("analyse_expressions not implemented for %s" % \
208             self.__class__.__name__)
209
210     def generate_code(self, code):
211         raise InternalError("generate_code not implemented for %s" % \
212             self.__class__.__name__)
213
214     def annotate(self, code):
215         # mro does the wrong thing
216         if isinstance(self, BlockNode):
217             self.body.annotate(code)
218
219     def end_pos(self):
220         try:
221             return self._end_pos
222         except AttributeError:
223             pos = self.pos
224             if not self.child_attrs:
225                 self._end_pos = pos
226                 return pos
227             for attr in self.child_attrs:
228                 child = getattr(self, attr)
229                 # Sometimes lists, sometimes nodes
230                 if child is None:
231                     pass
232                 elif isinstance(child, list):
233                     for c in child:
234                         pos = max(pos, c.end_pos())
235                 else:
236                     pos = max(pos, child.end_pos())
237             self._end_pos = pos
238             return pos
239
240     def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
241         if cutoff == 0:
242             return "<...nesting level cutoff...>"
243         if encountered is None:
244             encountered = set()
245         if id(self) in encountered:
246             return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self))
247         encountered.add(id(self))
248
249         def dump_child(x, level):
250             if isinstance(x, Node):
251                 return x.dump(level, filter_out, cutoff-1, encountered)
252             elif isinstance(x, list):
253                 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
254             else:
255                 return repr(x)
256
257
258         attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out]
259         if len(attrs) == 0:
260             return "<%s (0x%x)>" % (self.__class__.__name__, id(self))
261         else:
262             indent = "  " * level
263             res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self))
264             for key, value in attrs:
265                 res += "%s  %s: %s\n" % (indent, key, dump_child(value, level + 1))
266             res += "%s>" % indent
267             return res
268
269 class CompilerDirectivesNode(Node):
270     """
271     Sets compiler directives for the children nodes
272     """
273     #  directives     {string:value}  A dictionary holding the right value for
274     #                                 *all* possible directives.
275     #  body           Node
276     child_attrs = ["body"]
277
278     def analyse_control_flow(self, env):
279         old = env.directives
280         env.directives = self.directives
281         self.body.analyse_control_flow(env)
282         env.directives = old
283
284     def analyse_declarations(self, env):
285         old = env.directives
286         env.directives = self.directives
287         self.body.analyse_declarations(env)
288         env.directives = old
289
290     def analyse_expressions(self, env):
291         old = env.directives
292         env.directives = self.directives
293         self.body.analyse_expressions(env)
294         env.directives = old
295
296     def generate_function_definitions(self, env, code):
297         env_old = env.directives
298         code_old = code.globalstate.directives
299         code.globalstate.directives = self.directives
300         self.body.generate_function_definitions(env, code)
301         env.directives = env_old
302         code.globalstate.directives = code_old
303
304     def generate_execution_code(self, code):
305         old = code.globalstate.directives
306         code.globalstate.directives = self.directives
307         self.body.generate_execution_code(code)
308         code.globalstate.directives = old
309
310     def annotate(self, code):
311         old = code.globalstate.directives
312         code.globalstate.directives = self.directives
313         self.body.annotate(code)
314         code.globalstate.directives = old
315
316 class BlockNode(object):
317     #  Mixin class for nodes representing a declaration block.
318
319     def generate_cached_builtins_decls(self, env, code):
320         entries = env.global_scope().undeclared_cached_builtins
321         for entry in entries:
322             code.globalstate.add_cached_builtin_decl(entry)
323         del entries[:]
324
325     def generate_lambda_definitions(self, env, code):
326         for node in env.lambda_defs:
327             node.generate_function_definitions(env, code)
328
329 class StatListNode(Node):
330     # stats     a list of StatNode
331
332     child_attrs = ["stats"]
333
334     def create_analysed(pos, env, *args, **kw):
335         node = StatListNode(pos, *args, **kw)
336         return node # No node-specific analysis necesarry
337     create_analysed = staticmethod(create_analysed)
338
339     def analyse_control_flow(self, env):
340         for stat in self.stats:
341             stat.analyse_control_flow(env)
342
343     def analyse_declarations(self, env):
344         #print "StatListNode.analyse_declarations" ###
345         for stat in self.stats:
346             stat.analyse_declarations(env)
347
348     def analyse_expressions(self, env):
349         #print "StatListNode.analyse_expressions" ###
350         for stat in self.stats:
351             stat.analyse_expressions(env)
352
353     def generate_function_definitions(self, env, code):
354         #print "StatListNode.generate_function_definitions" ###
355         for stat in self.stats:
356             stat.generate_function_definitions(env, code)
357
358     def generate_execution_code(self, code):
359         #print "StatListNode.generate_execution_code" ###
360         for stat in self.stats:
361             code.mark_pos(stat.pos)
362             stat.generate_execution_code(code)
363
364     def annotate(self, code):
365         for stat in self.stats:
366             stat.annotate(code)
367
368
369 class StatNode(Node):
370     #
371     #  Code generation for statements is split into the following subphases:
372     #
373     #  (1) generate_function_definitions
374     #        Emit C code for the definitions of any structs,
375     #        unions, enums and functions defined in the current
376     #        scope-block.
377     #
378     #  (2) generate_execution_code
379     #        Emit C code for executable statements.
380     #
381
382     def generate_function_definitions(self, env, code):
383         pass
384
385     def generate_execution_code(self, code):
386         raise InternalError("generate_execution_code not implemented for %s" % \
387             self.__class__.__name__)
388
389
390 class CDefExternNode(StatNode):
391     #  include_file   string or None
392     #  body           StatNode
393
394     child_attrs = ["body"]
395
396     def analyse_declarations(self, env):
397         if self.include_file:
398             env.add_include_file(self.include_file)
399         old_cinclude_flag = env.in_cinclude
400         env.in_cinclude = 1
401         self.body.analyse_declarations(env)
402         env.in_cinclude = old_cinclude_flag
403
404     def analyse_expressions(self, env):
405         pass
406
407     def generate_execution_code(self, code):
408         pass
409
410     def annotate(self, code):
411         self.body.annotate(code)
412
413
414 class CDeclaratorNode(Node):
415     # Part of a C declaration.
416     #
417     # Processing during analyse_declarations phase:
418     #
419     #   analyse
420     #      Returns (name, type) pair where name is the
421     #      CNameDeclaratorNode of the name being declared
422     #      and type is the type it is being declared as.
423     #
424     #  calling_convention  string   Calling convention of CFuncDeclaratorNode
425     #                               for which this is a base
426
427     child_attrs = []
428
429     calling_convention = ""
430
431
432 class CNameDeclaratorNode(CDeclaratorNode):
433     #  name    string             The Pyrex name being declared
434     #  cname   string or None     C name, if specified
435     #  default ExprNode or None   the value assigned on declaration
436
437     child_attrs = ['default']
438
439     default = None
440
441     def analyse(self, base_type, env, nonempty = 0):
442         if nonempty and self.name == '':
443             # May have mistaken the name for the type.
444             if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
445                 error(self.pos, "Missing argument name")
446             elif base_type.is_void:
447                 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
448             else:
449                 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
450                 base_type = py_object_type
451         self.type = base_type
452         return self, base_type
453
454 class CPtrDeclaratorNode(CDeclaratorNode):
455     # base     CDeclaratorNode
456
457     child_attrs = ["base"]
458
459     def analyse(self, base_type, env, nonempty = 0):
460         if base_type.is_pyobject:
461             error(self.pos,
462                 "Pointer base type cannot be a Python object")
463         ptr_type = PyrexTypes.c_ptr_type(base_type)
464         return self.base.analyse(ptr_type, env, nonempty = nonempty)
465
466 class CReferenceDeclaratorNode(CDeclaratorNode):
467     # base     CDeclaratorNode
468
469     child_attrs = ["base"]
470
471     def analyse(self, base_type, env, nonempty = 0):
472         if base_type.is_pyobject:
473             error(self.pos,
474                   "Reference base type cannot be a Python object")
475         ref_type = PyrexTypes.c_ref_type(base_type)
476         return self.base.analyse(ref_type, env, nonempty = nonempty)
477
478 class CArrayDeclaratorNode(CDeclaratorNode):
479     # base        CDeclaratorNode
480     # dimension   ExprNode
481
482     child_attrs = ["base", "dimension"]
483
484     def analyse(self, base_type, env, nonempty = 0):
485         if base_type.is_cpp_class:
486             from ExprNodes import TupleNode
487             if isinstance(self.dimension, TupleNode):
488                 args = self.dimension.args
489             else:
490                 args = self.dimension,
491             values = [v.analyse_as_type(env) for v in args]
492             if None in values:
493                 ix = values.index(None)
494                 error(args[ix].pos, "Template parameter not a type.")
495                 return error_type
496             base_type = base_type.specialize_here(self.pos, values)
497             return self.base.analyse(base_type, env, nonempty = nonempty)
498         if self.dimension:
499             self.dimension.analyse_const_expression(env)
500             if not self.dimension.type.is_int:
501                 error(self.dimension.pos, "Array dimension not integer")
502             size = self.dimension.get_constant_c_result_code()
503             if size is not None:
504                 try:
505                     size = int(size)
506                 except ValueError:
507                     # runtime constant?
508                     pass
509         else:
510             size = None
511         if not base_type.is_complete():
512             error(self.pos,
513                 "Array element type '%s' is incomplete" % base_type)
514         if base_type.is_pyobject:
515             error(self.pos,
516                 "Array element cannot be a Python object")
517         if base_type.is_cfunction:
518             error(self.pos,
519                 "Array element cannot be a function")
520         array_type = PyrexTypes.c_array_type(base_type, size)
521         return self.base.analyse(array_type, env, nonempty = nonempty)
522
523
524 class CFuncDeclaratorNode(CDeclaratorNode):
525     # base             CDeclaratorNode
526     # args             [CArgDeclNode]
527     # has_varargs      boolean
528     # exception_value  ConstNode
529     # exception_check  boolean    True if PyErr_Occurred check needed
530     # nogil            boolean    Can be called without gil
531     # with_gil         boolean    Acquire gil around function body
532
533     child_attrs = ["base", "args", "exception_value"]
534
535     overridable = 0
536     optional_arg_count = 0
537
538     def analyse(self, return_type, env, nonempty = 0, directive_locals = {}):
539         if nonempty:
540             nonempty -= 1
541         func_type_args = []
542         for i, arg_node in enumerate(self.args):
543             name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
544                                                      is_self_arg = (i == 0 and env.is_c_class_scope))
545             name = name_declarator.name
546             if name in directive_locals:
547                 type_node = directive_locals[name]
548                 other_type = type_node.analyse_as_type(env)
549                 if other_type is None:
550                     error(type_node.pos, "Not a type")
551                 elif (type is not PyrexTypes.py_object_type
552                       and not type.same_as(other_type)):
553                     error(self.base.pos, "Signature does not agree with previous declaration")
554                     error(type_node.pos, "Previous declaration here")
555                 else:
556                     type = other_type
557             if name_declarator.cname:
558                 error(self.pos,
559                     "Function argument cannot have C name specification")
560             # Turn *[] argument into **
561             if type.is_array:
562                 type = PyrexTypes.c_ptr_type(type.base_type)
563             # Catch attempted C-style func(void) decl
564             if type.is_void:
565                 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
566             func_type_args.append(
567                 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
568             if arg_node.default:
569                 self.optional_arg_count += 1
570             elif self.optional_arg_count:
571                 error(self.pos, "Non-default argument follows default argument")
572
573         if self.optional_arg_count:
574             scope = StructOrUnionScope()
575             arg_count_member = '%sn' % Naming.pyrex_prefix
576             scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
577             for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
578                 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
579             struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
580             self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
581                                         kind = 'struct',
582                                         scope = scope,
583                                         typedef_flag = 0,
584                                         pos = self.pos,
585                                         cname = struct_cname)
586             self.op_args_struct.defined_in_pxd = 1
587             self.op_args_struct.used = 1
588
589         exc_val = None
590         exc_check = 0
591         if self.exception_check == '+':
592             env.add_include_file('stdexcept')
593         if return_type.is_pyobject \
594             and (self.exception_value or self.exception_check) \
595             and self.exception_check != '+':
596                 error(self.pos,
597                     "Exception clause not allowed for function returning Python object")
598         else:
599             if self.exception_value:
600                 self.exception_value.analyse_const_expression(env)
601                 if self.exception_check == '+':
602                     self.exception_value.analyse_types(env)
603                     exc_val_type = self.exception_value.type
604                     if not exc_val_type.is_error and \
605                           not exc_val_type.is_pyobject and \
606                           not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
607                         error(self.exception_value.pos,
608                             "Exception value must be a Python exception or cdef function with no arguments.")
609                     exc_val = self.exception_value
610                 else:
611                     self.exception_value = self.exception_value.coerce_to(return_type, env)
612                     if self.exception_value.analyse_const_expression(env):
613                         exc_val = self.exception_value.get_constant_c_result_code()
614                         if exc_val is None:
615                             raise InternalError("get_constant_c_result_code not implemented for %s" %
616                                 self.exception_value.__class__.__name__)
617                         if not return_type.assignable_from(self.exception_value.type):
618                             error(self.exception_value.pos,
619                                   "Exception value incompatible with function return type")
620             exc_check = self.exception_check
621         if return_type.is_cfunction:
622             error(self.pos,
623                 "Function cannot return a function")
624         func_type = PyrexTypes.CFuncType(
625             return_type, func_type_args, self.has_varargs,
626             optional_arg_count = self.optional_arg_count,
627             exception_value = exc_val, exception_check = exc_check,
628             calling_convention = self.base.calling_convention,
629             nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
630         if self.optional_arg_count:
631             func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
632         callspec = env.directives['callspec']
633         if callspec:
634             current = func_type.calling_convention
635             if current and current != callspec:
636                 error(self.pos, "cannot have both '%s' and '%s' "
637                       "calling conventions" % (current, callspec))
638             func_type.calling_convention = callspec
639         return self.base.analyse(func_type, env)
640
641
642 class CArgDeclNode(Node):
643     # Item in a function declaration argument list.
644     #
645     # base_type      CBaseTypeNode
646     # declarator     CDeclaratorNode
647     # not_none       boolean            Tagged with 'not None'
648     # or_none        boolean            Tagged with 'or None'
649     # accept_none    boolean            Resolved boolean for not_none/or_none
650     # default        ExprNode or None
651     # default_value  PyObjectConst      constant for default value
652     # annotation     ExprNode or None   Py3 function arg annotation
653     # is_self_arg    boolean            Is the "self" arg of an extension type method
654     # is_type_arg    boolean            Is the "class" arg of an extension type classmethod
655     # is_kw_only     boolean            Is a keyword-only argument
656
657     child_attrs = ["base_type", "declarator", "default"]
658
659     is_self_arg = 0
660     is_type_arg = 0
661     is_generic = 1
662     kw_only = 0
663     not_none = 0
664     or_none = 0
665     type = None
666     name_declarator = None
667     default_value = None
668     annotation = None
669
670     def analyse(self, env, nonempty = 0, is_self_arg = False):
671         if is_self_arg:
672             self.base_type.is_self_arg = self.is_self_arg = True
673         if self.type is None:
674             # The parser may missinterpret names as types...
675             # We fix that here.
676             if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
677                 if nonempty:
678                     self.declarator.name = self.base_type.name
679                     self.base_type.name = None
680                     self.base_type.is_basic_c_type = False
681                 could_be_name = True
682             else:
683                 could_be_name = False
684             base_type = self.base_type.analyse(env, could_be_name = could_be_name)
685             if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
686                 self.declarator.name = self.base_type.arg_name
687             # The parser is unable to resolve the ambiguity of [] as part of the
688             # type (e.g. in buffers) or empty declarator (as with arrays).
689             # This is only arises for empty multi-dimensional arrays.
690             if (base_type.is_array
691                     and isinstance(self.base_type, TemplatedTypeNode)
692                     and isinstance(self.declarator, CArrayDeclaratorNode)):
693                 declarator = self.declarator
694                 while isinstance(declarator.base, CArrayDeclaratorNode):
695                     declarator = declarator.base
696                 declarator.base = self.base_type.array_declarator
697                 base_type = base_type.base_type
698             return self.declarator.analyse(base_type, env, nonempty = nonempty)
699         else:
700             return self.name_declarator, self.type
701
702     def calculate_default_value_code(self, code):
703         if self.default_value is None:
704             if self.default:
705                 if self.default.is_literal:
706                     # will not output any code, just assign the result_code
707                     self.default.generate_evaluation_code(code)
708                     return self.type.cast_code(self.default.result())
709                 self.default_value = code.get_argument_default_const(self.type)
710         return self.default_value
711
712     def annotate(self, code):
713         if self.default:
714             self.default.annotate(code)
715
716
717 class CBaseTypeNode(Node):
718     # Abstract base class for C base type nodes.
719     #
720     # Processing during analyse_declarations phase:
721     #
722     #   analyse
723     #     Returns the type.
724
725     pass
726
727     def analyse_as_type(self, env):
728         return self.analyse(env)
729
730 class CAnalysedBaseTypeNode(Node):
731     # type            type
732
733     child_attrs = []
734
735     def analyse(self, env, could_be_name = False):
736         return self.type
737
738 class CSimpleBaseTypeNode(CBaseTypeNode):
739     # name             string
740     # module_path      [string]     Qualifying name components
741     # is_basic_c_type  boolean
742     # signed           boolean
743     # longness         integer
744     # complex          boolean
745     # is_self_arg      boolean      Is self argument of C method
746     # ##is_type_arg      boolean      Is type argument of class method
747
748     child_attrs = []
749     arg_name = None   # in case the argument name was interpreted as a type
750     module_path = []
751     is_basic_c_type = False
752     complex = False
753
754     def analyse(self, env, could_be_name = False):
755         # Return type descriptor.
756         #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
757         type = None
758         if self.is_basic_c_type:
759             type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
760             if not type:
761                 error(self.pos, "Unrecognised type modifier combination")
762         elif self.name == "object" and not self.module_path:
763             type = py_object_type
764         elif self.name is None:
765             if self.is_self_arg and env.is_c_class_scope:
766                 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
767                 type = env.parent_type
768             ## elif self.is_type_arg and env.is_c_class_scope:
769             ##     type = Builtin.type_type
770             else:
771                 type = py_object_type
772         else:
773             if self.module_path:
774                 scope = env.find_imported_module(self.module_path, self.pos)
775             else:
776                 scope = env
777             if scope:
778                 if scope.is_c_class_scope:
779                     scope = scope.global_scope()
780                 entry = scope.lookup(self.name)
781                 if entry and entry.is_type:
782                     type = entry.type
783                 elif could_be_name:
784                     if self.is_self_arg and env.is_c_class_scope:
785                         type = env.parent_type
786                     ## elif self.is_type_arg and env.is_c_class_scope:
787                     ##     type = Builtin.type_type
788                     else:
789                         type = py_object_type
790                     self.arg_name = self.name
791                 else:
792                     if self.templates:
793                         if not self.name in self.templates:
794                             error(self.pos, "'%s' is not a type identifier" % self.name)
795                         type = PyrexTypes.TemplatePlaceholderType(self.name)
796                     else:
797                         error(self.pos, "'%s' is not a type identifier" % self.name)
798         if self.complex:
799             if not type.is_numeric or type.is_complex:
800                 error(self.pos, "can only complexify c numeric types")
801             type = PyrexTypes.CComplexType(type)
802             type.create_declaration_utility_code(env)
803         elif type is Builtin.complex_type:
804             # Special case: optimise builtin complex type into C's
805             # double complex.  The parser cannot do this (as for the
806             # normal scalar types) as the user may have redeclared the
807             # 'complex' type.  Testing for the exact type here works.
808             type = PyrexTypes.c_double_complex_type
809             type.create_declaration_utility_code(env)
810             self.complex = True
811         if type:
812             return type
813         else:
814             return PyrexTypes.error_type
815
816 class CNestedBaseTypeNode(CBaseTypeNode):
817     # For C++ classes that live inside other C++ classes.
818
819     # name             string
820     # base_type        CBaseTypeNode
821
822     child_attrs = ['base_type']
823
824     def analyse(self, env, could_be_name = None):
825         base_type = self.base_type.analyse(env)
826         if base_type is PyrexTypes.error_type:
827             return PyrexTypes.error_type
828         if not base_type.is_cpp_class:
829             error(self.pos, "'%s' is not a valid type scope" % base_type)
830             return PyrexTypes.error_type
831         type_entry = base_type.scope.lookup_here(self.name)
832         if not type_entry or not type_entry.is_type:
833             error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
834             return PyrexTypes.error_type
835         return type_entry.type
836
837 class TemplatedTypeNode(CBaseTypeNode):
838     #  After parsing:
839     #  positional_args  [ExprNode]        List of positional arguments
840     #  keyword_args     DictNode          Keyword arguments
841     #  base_type_node   CBaseTypeNode
842
843     #  After analysis:
844     #  type             PyrexTypes.BufferType or PyrexTypes.CppClassType  ...containing the right options
845
846
847     child_attrs = ["base_type_node", "positional_args",
848                    "keyword_args", "dtype_node"]
849
850     dtype_node = None
851
852     name = None
853
854     def analyse(self, env, could_be_name = False, base_type = None):
855         if base_type is None:
856             base_type = self.base_type_node.analyse(env)
857         if base_type.is_error: return base_type
858
859         if base_type.is_cpp_class:
860             # Templated class
861             if self.keyword_args and self.keyword_args.key_value_pairs:
862                 error(self.pos, "c++ templates cannot take keyword arguments");
863                 self.type = PyrexTypes.error_type
864             else:
865                 template_types = []
866                 for template_node in self.positional_args:
867                     type = template_node.analyse_as_type(env)
868                     if type is None:
869                         error(template_node.pos, "unknown type in template argument")
870                         return error_type
871                     template_types.append(type)
872                 self.type = base_type.specialize_here(self.pos, template_types)
873
874         elif base_type.is_pyobject:
875             # Buffer
876             import Buffer
877
878             options = Buffer.analyse_buffer_options(
879                 self.pos,
880                 env,
881                 self.positional_args,
882                 self.keyword_args,
883                 base_type.buffer_defaults)
884
885             if sys.version_info[0] < 3:
886                 # Py 2.x enforces byte strings as keyword arguments ...
887                 options = dict([ (name.encode('ASCII'), value)
888                                  for name, value in options.items() ])
889
890             self.type = PyrexTypes.BufferType(base_type, **options)
891
892         else:
893             # Array
894             empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
895             if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
896                 error(self.pos, "invalid array declaration")
897                 self.type = PyrexTypes.error_type
898             else:
899                 # It would be nice to merge this class with CArrayDeclaratorNode,
900                 # but arrays are part of the declaration, not the type...
901                 if not self.positional_args:
902                     dimension = None
903                 else:
904                     dimension = self.positional_args[0]
905                 self.array_declarator = CArrayDeclaratorNode(self.pos,
906                     base = empty_declarator,
907                     dimension = dimension)
908                 self.type = self.array_declarator.analyse(base_type, env)[1]
909
910         return self.type
911
912 class CComplexBaseTypeNode(CBaseTypeNode):
913     # base_type   CBaseTypeNode
914     # declarator  CDeclaratorNode
915
916     child_attrs = ["base_type", "declarator"]
917
918     def analyse(self, env, could_be_name = False):
919         base = self.base_type.analyse(env, could_be_name)
920         _, type = self.declarator.analyse(base, env)
921         return type
922
923
924 class CVarDefNode(StatNode):
925     #  C variable definition or forward/extern function declaration.
926     #
927     #  visibility    'private' or 'public' or 'extern'
928     #  base_type     CBaseTypeNode
929     #  declarators   [CDeclaratorNode]
930     #  in_pxd        boolean
931     #  api           boolean
932
933     #  decorators    [cython.locals(...)] or None
934     #  directive_locals { string : NameNode } locals defined by cython.locals(...)
935
936     child_attrs = ["base_type", "declarators"]
937
938     decorators = None
939     directive_locals = None
940
941     def analyse_declarations(self, env, dest_scope = None):
942         if self.directive_locals is None:
943             self.directive_locals = {}
944         if not dest_scope:
945             dest_scope = env
946         self.dest_scope = dest_scope
947         base_type = self.base_type.analyse(env)
948
949         # If the field is an external typedef, we cannot be sure about the type,
950         # so do conversion ourself rather than rely on the CPython mechanism (through
951         # a property; made in AnalyseDeclarationsTransform).
952         if (dest_scope.is_c_class_scope
953             and self.visibility in ('public', 'readonly')):
954             need_property = True
955         else:
956             need_property = False
957         visibility = self.visibility
958
959         for declarator in self.declarators:
960             if isinstance(declarator, CFuncDeclaratorNode):
961                 name_declarator, type = declarator.analyse(base_type, env, directive_locals=self.directive_locals)
962             else:
963                 name_declarator, type = declarator.analyse(base_type, env)
964             if not type.is_complete():
965                 if not (self.visibility == 'extern' and type.is_array):
966                     error(declarator.pos,
967                         "Variable type '%s' is incomplete" % type)
968             if self.visibility == 'extern' and type.is_pyobject:
969                 error(declarator.pos,
970                     "Python object cannot be declared extern")
971             name = name_declarator.name
972             cname = name_declarator.cname
973             if name == '':
974                 error(declarator.pos, "Missing name in declaration.")
975                 return
976             if type.is_cfunction:
977                 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
978                     cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
979                     api = self.api)
980                 if entry is not None:
981                     entry.directive_locals = copy.copy(self.directive_locals)
982             else:
983                 if self.directive_locals:
984                     error(self.pos, "Decorators can only be followed by functions")
985                 if self.in_pxd and self.visibility != 'extern':
986                     error(self.pos,
987                         "Only 'extern' C variable declaration allowed in .pxd file")
988                 entry = dest_scope.declare_var(name, type, declarator.pos,
989                             cname=cname, visibility=visibility, api=self.api, is_cdef=1)
990                 entry.needs_property = need_property
991
992
993 class CStructOrUnionDefNode(StatNode):
994     #  name          string
995     #  cname         string or None
996     #  kind          "struct" or "union"
997     #  typedef_flag  boolean
998     #  visibility    "public" or "private"
999     #  api           boolean
1000     #  in_pxd        boolean
1001     #  attributes    [CVarDefNode] or None
1002     #  entry         Entry
1003     #  packed        boolean
1004
1005     child_attrs = ["attributes"]
1006
1007     def analyse_declarations(self, env):
1008         scope = None
1009         if self.visibility == 'extern' and self.packed:
1010             error(self.pos, "Cannot declare extern struct as 'packed'")
1011         if self.attributes is not None:
1012             scope = StructOrUnionScope(self.name)
1013         self.entry = env.declare_struct_or_union(
1014             self.name, self.kind, scope, self.typedef_flag, self.pos,
1015             self.cname, visibility = self.visibility, api = self.api,
1016             packed = self.packed)
1017         if self.attributes is not None:
1018             if self.in_pxd and not env.in_cinclude:
1019                 self.entry.defined_in_pxd = 1
1020             for attr in self.attributes:
1021                 attr.analyse_declarations(env, scope)
1022             if self.visibility != 'extern':
1023                 need_typedef_indirection = False
1024                 for attr in scope.var_entries:
1025                     type = attr.type
1026                     while type.is_array:
1027                         type = type.base_type
1028                     if type == self.entry.type:
1029                         error(attr.pos, "Struct cannot contain itself as a member.")
1030                     if self.typedef_flag:
1031                         while type.is_ptr:
1032                             type = type.base_type
1033                         if type == self.entry.type:
1034                             need_typedef_indirection = True
1035                 if need_typedef_indirection:
1036                     # C can't handle typedef structs that refer to themselves.
1037                     struct_entry = self.entry
1038                     self.entry = env.declare_typedef(
1039                         self.name, struct_entry.type, self.pos,
1040                         cname = self.cname, visibility='ignore')
1041                     struct_entry.type.typedef_flag = False
1042                     # FIXME: this might be considered a hack ;-)
1043                     struct_entry.cname = struct_entry.type.cname = \
1044                                          '_' + self.entry.type.typedef_cname
1045
1046     def analyse_expressions(self, env):
1047         pass
1048
1049     def generate_execution_code(self, code):
1050         pass
1051
1052
1053 class CppClassNode(CStructOrUnionDefNode):
1054
1055     #  name          string
1056     #  cname         string or None
1057     #  visibility    "extern"
1058     #  in_pxd        boolean
1059     #  attributes    [CVarDefNode] or None
1060     #  entry         Entry
1061     #  base_classes  [string]
1062     #  templates     [string] or None
1063
1064     def analyse_declarations(self, env):
1065         scope = None
1066         if self.attributes is not None:
1067             scope = CppClassScope(self.name, env)
1068         base_class_types = []
1069         for base_class_name in self.base_classes:
1070             base_class_entry = env.lookup(base_class_name)
1071             if base_class_entry is None:
1072                 error(self.pos, "'%s' not found" % base_class_name)
1073             elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1074                 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1075             else:
1076                 base_class_types.append(base_class_entry.type)
1077         if self.templates is None:
1078             template_types = None
1079         else:
1080             template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1081         self.entry = env.declare_cpp_class(
1082             self.name, scope, self.pos,
1083             self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1084         if self.entry is None:
1085             return
1086         self.entry.is_cpp_class = 1
1087         if self.attributes is not None:
1088             if self.in_pxd and not env.in_cinclude:
1089                 self.entry.defined_in_pxd = 1
1090             for attr in self.attributes:
1091                 attr.analyse_declarations(scope)
1092
1093 class CEnumDefNode(StatNode):
1094     #  name           string or None
1095     #  cname          string or None
1096     #  items          [CEnumDefItemNode]
1097     #  typedef_flag   boolean
1098     #  visibility     "public" or "private"
1099     #  api            boolean
1100     #  in_pxd         boolean
1101     #  entry          Entry
1102
1103     child_attrs = ["items"]
1104
1105     def analyse_declarations(self, env):
1106         self.entry = env.declare_enum(self.name, self.pos,
1107             cname = self.cname, typedef_flag = self.typedef_flag,
1108             visibility = self.visibility, api = self.api)
1109         if self.items is not None:
1110             if self.in_pxd and not env.in_cinclude:
1111                 self.entry.defined_in_pxd = 1
1112             for item in self.items:
1113                 item.analyse_declarations(env, self.entry)
1114
1115     def analyse_expressions(self, env):
1116         pass
1117
1118     def generate_execution_code(self, code):
1119         if self.visibility == 'public' or self.api:
1120             temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1121             for item in self.entry.enum_values:
1122                 code.putln("%s = PyInt_FromLong(%s); %s" % (
1123                         temp,
1124                         item.cname,
1125                         code.error_goto_if_null(temp, item.pos)))
1126                 code.put_gotref(temp)
1127                 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1128                         Naming.module_cname,
1129                         item.name,
1130                         temp,
1131                         code.error_goto(item.pos)))
1132                 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1133             code.funcstate.release_temp(temp)
1134
1135
1136 class CEnumDefItemNode(StatNode):
1137     #  name     string
1138     #  cname    string or None
1139     #  value    ExprNode or None
1140
1141     child_attrs = ["value"]
1142
1143     def analyse_declarations(self, env, enum_entry):
1144         if self.value:
1145             self.value.analyse_const_expression(env)
1146             if not self.value.type.is_int:
1147                 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1148                 self.value.analyse_const_expression(env)
1149         entry = env.declare_const(self.name, enum_entry.type,
1150             self.value, self.pos, cname = self.cname,
1151             visibility = enum_entry.visibility, api = enum_entry.api)
1152         enum_entry.enum_values.append(entry)
1153
1154
1155 class CTypeDefNode(StatNode):
1156     #  base_type    CBaseTypeNode
1157     #  declarator   CDeclaratorNode
1158     #  visibility   "public" or "private"
1159     #  api          boolean
1160     #  in_pxd       boolean
1161
1162     child_attrs = ["base_type", "declarator"]
1163
1164     def analyse_declarations(self, env):
1165         base = self.base_type.analyse(env)
1166         name_declarator, type = self.declarator.analyse(base, env)
1167         name = name_declarator.name
1168         cname = name_declarator.cname
1169         entry = env.declare_typedef(name, type, self.pos,
1170             cname = cname, visibility = self.visibility, api = self.api)
1171         if self.in_pxd and not env.in_cinclude:
1172             entry.defined_in_pxd = 1
1173
1174     def analyse_expressions(self, env):
1175         pass
1176     def generate_execution_code(self, code):
1177         pass
1178
1179
1180 class FuncDefNode(StatNode, BlockNode):
1181     #  Base class for function definition nodes.
1182     #
1183     #  return_type     PyrexType
1184     #  #filename        string        C name of filename string const
1185     #  entry           Symtab.Entry
1186     #  needs_closure   boolean        Whether or not this function has inner functions/classes/yield
1187     #  needs_outer_scope boolean      Whether or not this function requires outer scope
1188     #  directive_locals { string : NameNode } locals defined by cython.locals(...)
1189
1190     py_func = None
1191     assmt = None
1192     needs_closure = False
1193     needs_outer_scope = False
1194     is_generator = False
1195     is_generator_body = False
1196     modifiers = []
1197
1198     def analyse_default_values(self, env):
1199         genv = env.global_scope()
1200         default_seen = 0
1201         for arg in self.args:
1202             if arg.default:
1203                 default_seen = 1
1204                 if arg.is_generic:
1205                     arg.default.analyse_types(env)
1206                     arg.default = arg.default.coerce_to(arg.type, genv)
1207                 else:
1208                     error(arg.pos,
1209                         "This argument cannot have a default value")
1210                     arg.default = None
1211             elif arg.kw_only:
1212                 default_seen = 1
1213             elif default_seen:
1214                 error(arg.pos, "Non-default argument following default argument")
1215
1216     def align_argument_type(self, env, arg):
1217         directive_locals = self.directive_locals
1218         type = arg.type
1219         if arg.name in directive_locals:
1220             type_node = directive_locals[arg.name]
1221             other_type = type_node.analyse_as_type(env)
1222             if other_type is None:
1223                 error(type_node.pos, "Not a type")
1224             elif (type is not PyrexTypes.py_object_type
1225                     and not type.same_as(other_type)):
1226                 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1227                 error(type_node.pos, "Previous declaration here")
1228             else:
1229                 arg.type = other_type
1230         return arg
1231
1232     def need_gil_acquisition(self, lenv):
1233         return 0
1234
1235     def create_local_scope(self, env):
1236         genv = env
1237         while genv.is_py_class_scope or genv.is_c_class_scope:
1238             genv = genv.outer_scope
1239         if self.needs_closure:
1240             lenv = ClosureScope(name=self.entry.name,
1241                                 outer_scope = genv,
1242                                 scope_name=self.entry.cname)
1243         else:
1244             lenv = LocalScope(name=self.entry.name,
1245                               outer_scope=genv,
1246                               parent_scope=env)
1247         lenv.return_type = self.return_type
1248         type = self.entry.type
1249         if type.is_cfunction:
1250             lenv.nogil = type.nogil and not type.with_gil
1251         self.local_scope = lenv
1252         lenv.directives = env.directives
1253         return lenv
1254
1255     def generate_function_body(self, env, code):
1256         self.body.generate_execution_code(code)
1257
1258     def generate_function_definitions(self, env, code):
1259         import Buffer
1260
1261         lenv = self.local_scope
1262         if lenv.is_closure_scope and not lenv.is_passthrough:
1263             outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1264                                             Naming.outer_scope_cname)
1265         else:
1266             outer_scope_cname = Naming.outer_scope_cname
1267         lenv.mangle_closure_cnames(outer_scope_cname)
1268         # Generate closure function definitions
1269         self.body.generate_function_definitions(lenv, code)
1270         # generate lambda function definitions
1271         self.generate_lambda_definitions(lenv, code)
1272
1273         is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1274                              self.entry.scope.is_c_class_scope)
1275         is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1276                                  self.entry.scope.is_c_class_scope)
1277         is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1278         if is_buffer_slot:
1279             if 'cython_unused' not in self.modifiers:
1280                 self.modifiers = self.modifiers + ['cython_unused']
1281
1282         preprocessor_guard = None
1283         if self.entry.is_special and not is_buffer_slot:
1284             slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1285             if slot:
1286                 preprocessor_guard = slot.preprocessor_guard_code()
1287                 if (self.entry.name == '__long__' and
1288                     not self.entry.scope.lookup_here('__int__')):
1289                     preprocessor_guard = None
1290
1291         profile = code.globalstate.directives['profile']
1292         if profile and lenv.nogil:
1293             warning(self.pos, "Cannot profile nogil function.", 1)
1294             profile = False
1295         if profile:
1296             code.globalstate.use_utility_code(profile_utility_code)
1297
1298         # Generate C code for header and body of function
1299         code.enter_cfunc_scope()
1300         code.return_from_error_cleanup_label = code.new_label()
1301
1302         # ----- Top-level constants used by this function
1303         code.mark_pos(self.pos)
1304         self.generate_cached_builtins_decls(lenv, code)
1305         # ----- Function header
1306         code.putln("")
1307
1308         if preprocessor_guard:
1309             code.putln(preprocessor_guard)
1310
1311         with_pymethdef = self.needs_assignment_synthesis(env, code)
1312         if self.py_func:
1313             self.py_func.generate_function_header(code,
1314                 with_pymethdef = with_pymethdef,
1315                 proto_only=True)
1316         self.generate_function_header(code,
1317             with_pymethdef = with_pymethdef)
1318         # ----- Local variable declarations
1319         # Find function scope
1320         cenv = env
1321         while cenv.is_py_class_scope or cenv.is_c_class_scope:
1322             cenv = cenv.outer_scope
1323         if self.needs_closure:
1324             code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1325             code.putln(";")
1326         elif self.needs_outer_scope:
1327             if lenv.is_passthrough:
1328                 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1329                 code.putln(";")
1330             code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1331             code.putln(";")
1332         self.generate_argument_declarations(lenv, code)
1333         for entry in lenv.var_entries:
1334             if not entry.in_closure:
1335                 code.put_var_declaration(entry)
1336         init = ""
1337         if not self.return_type.is_void:
1338             if self.return_type.is_pyobject:
1339                 init = " = NULL"
1340             code.putln(
1341                 "%s%s;" %
1342                     (self.return_type.declaration_code(Naming.retval_cname),
1343                      init))
1344         tempvardecl_code = code.insertion_point()
1345         if not lenv.nogil:
1346             code.put_declare_refcount_context()
1347         self.generate_keyword_list(code)
1348         if profile:
1349             code.put_trace_declarations()
1350         # ----- Extern library function declarations
1351         lenv.generate_library_function_declarations(code)
1352         # ----- GIL acquisition
1353         acquire_gil = self.acquire_gil
1354         if acquire_gil:
1355             env.use_utility_code(force_init_threads_utility_code)
1356             code.putln("#ifdef WITH_THREAD")
1357             code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1358             code.putln("#endif")
1359         # ----- set up refnanny
1360         if not lenv.nogil:
1361             code.put_setup_refcount_context(self.entry.name)
1362         # ----- Automatic lead-ins for certain special functions
1363         if is_getbuffer_slot:
1364             self.getbuffer_init(code)
1365         # ----- Create closure scope object
1366         if self.needs_closure:
1367             code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1368                 Naming.cur_scope_cname,
1369                 lenv.scope_class.type.declaration_code(''),
1370                 lenv.scope_class.type.typeptr_cname,
1371                 lenv.scope_class.type.typeptr_cname,
1372                 Naming.empty_tuple))
1373             code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1374             if is_getbuffer_slot:
1375                 self.getbuffer_error_cleanup(code)
1376             if not lenv.nogil:
1377                 code.put_finish_refcount_context()
1378             # FIXME: what if the error return value is a Python value?
1379             code.putln("return %s;" % self.error_value())
1380             code.putln("}")
1381             code.put_gotref(Naming.cur_scope_cname)
1382             # Note that it is unsafe to decref the scope at this point.
1383         if self.needs_outer_scope:
1384             code.putln("%s = (%s)%s;" % (
1385                             outer_scope_cname,
1386                             cenv.scope_class.type.declaration_code(''),
1387                             Naming.self_cname))
1388             if lenv.is_passthrough:
1389                 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1390             elif self.needs_closure:
1391                 # inner closures own a reference to their outer parent
1392                 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1393                 code.put_giveref(outer_scope_cname)
1394         # ----- Trace function call
1395         if profile:
1396             # this looks a bit late, but if we don't get here due to a
1397             # fatal error before hand, it's not really worth tracing
1398             code.put_trace_call(self.entry.name, self.pos)
1399         # ----- Fetch arguments
1400         self.generate_argument_parsing_code(env, code)
1401         # If an argument is assigned to in the body, we must
1402         # incref it to properly keep track of refcounts.
1403         for entry in lenv.arg_entries:
1404             if entry.type.is_pyobject:
1405                 if (acquire_gil or entry.assignments) and not entry.in_closure:
1406                     code.put_var_incref(entry)
1407         # ----- Initialise local variables
1408         for entry in lenv.var_entries:
1409             if entry.type.is_pyobject and entry.init_to_none and entry.used:
1410                 code.put_init_var_to_py_none(entry)
1411         # ----- Initialise local buffer auxiliary variables
1412         for entry in lenv.var_entries + lenv.arg_entries:
1413             if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1414                 code.putln("%s.buf = NULL;" %
1415                            entry.buffer_aux.buffer_info_var.cname)
1416         # ----- Check and convert arguments
1417         self.generate_argument_type_tests(code)
1418         # ----- Acquire buffer arguments
1419         for entry in lenv.arg_entries:
1420             if entry.type.is_buffer:
1421                 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1422
1423         # -------------------------
1424         # ----- Function body -----
1425         # -------------------------
1426         self.generate_function_body(env, code)
1427
1428         # ----- Default return value
1429         code.putln("")
1430         if self.return_type.is_pyobject:
1431             #if self.return_type.is_extension_type:
1432             #    lhs = "(PyObject *)%s" % Naming.retval_cname
1433             #else:
1434             lhs = Naming.retval_cname
1435             code.put_init_to_py_none(lhs, self.return_type)
1436         else:
1437             val = self.return_type.default_value
1438             if val:
1439                 code.putln("%s = %s;" % (Naming.retval_cname, val))
1440         # ----- Error cleanup
1441         if code.error_label in code.labels_used:
1442             code.put_goto(code.return_label)
1443             code.put_label(code.error_label)
1444             for cname, type in code.funcstate.all_managed_temps():
1445                 code.put_xdecref(cname, type)
1446
1447             # Clean up buffers -- this calls a Python function
1448             # so need to save and restore error state
1449             buffers_present = len(lenv.buffer_entries) > 0
1450             if buffers_present:
1451                 code.globalstate.use_utility_code(restore_exception_utility_code)
1452                 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1453                 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1454                 for entry in lenv.buffer_entries:
1455                     Buffer.put_release_buffer_code(code, entry)
1456                     #code.putln("%s = 0;" % entry.cname)
1457                 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1458
1459             err_val = self.error_value()
1460             exc_check = self.caller_will_check_exceptions()
1461             if err_val is not None or exc_check:
1462                 # TODO: Fix exception tracing (though currently unused by cProfile).
1463                 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1464                 # code.put_trace_exception()
1465                 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1466             else:
1467                 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1468                             % self.entry.qualified_name, 0)
1469                 code.putln(
1470                     '__Pyx_WriteUnraisable("%s");' %
1471                         self.entry.qualified_name)
1472                 env.use_utility_code(unraisable_exception_utility_code)
1473                 env.use_utility_code(restore_exception_utility_code)
1474             default_retval = self.return_type.default_value
1475             if err_val is None and default_retval:
1476                 err_val = default_retval
1477             if err_val is not None:
1478                 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1479
1480             if is_getbuffer_slot:
1481                 self.getbuffer_error_cleanup(code)
1482
1483             # If we are using the non-error cleanup section we should
1484             # jump past it if we have an error. The if-test below determine
1485             # whether this section is used.
1486             if buffers_present or is_getbuffer_slot:
1487                 code.put_goto(code.return_from_error_cleanup_label)
1488
1489
1490         # ----- Non-error return cleanup
1491         code.put_label(code.return_label)
1492         for entry in lenv.buffer_entries:
1493             if entry.used:
1494                 Buffer.put_release_buffer_code(code, entry)
1495         if is_getbuffer_slot:
1496             self.getbuffer_normal_cleanup(code)
1497         # ----- Return cleanup for both error and no-error return
1498         code.put_label(code.return_from_error_cleanup_label)
1499         if not Options.init_local_none:
1500             for entry in lenv.var_entries:
1501                 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1502                     entry.xdecref_cleanup = 1
1503
1504         for entry in lenv.var_entries:
1505             if entry.type.is_pyobject:
1506                 if entry.used and not entry.in_closure:
1507                     code.put_var_decref(entry)
1508         # Decref any increfed args
1509         for entry in lenv.arg_entries:
1510             if entry.type.is_pyobject:
1511                 if (acquire_gil or entry.assignments) and not entry.in_closure:
1512                     code.put_var_decref(entry)
1513         if self.needs_closure:
1514             code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1515
1516         # ----- Return
1517         # This code is duplicated in ModuleNode.generate_module_init_func
1518         if not lenv.nogil:
1519             default_retval = self.return_type.default_value
1520             err_val = self.error_value()
1521             if err_val is None and default_retval:
1522                 err_val = default_retval
1523             if self.return_type.is_pyobject:
1524                 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1525
1526         if self.entry.is_special and self.entry.name == "__hash__":
1527             # Returning -1 for __hash__ is supposed to signal an error
1528             # We do as Python instances and coerce -1 into -2.
1529             code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1530                     Naming.retval_cname, Naming.retval_cname))
1531
1532         if profile:
1533             if self.return_type.is_pyobject:
1534                 code.put_trace_return(Naming.retval_cname)
1535             else:
1536                 code.put_trace_return("Py_None")
1537         if not lenv.nogil:
1538             code.put_finish_refcount_context()
1539
1540         if acquire_gil:
1541             code.putln("#ifdef WITH_THREAD")
1542             code.putln("PyGILState_Release(_save);")
1543             code.putln("#endif")
1544
1545         if not self.return_type.is_void:
1546             code.putln("return %s;" % Naming.retval_cname)
1547
1548         code.putln("}")
1549
1550         if preprocessor_guard:
1551             code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1552
1553         # ----- Go back and insert temp variable declarations
1554         tempvardecl_code.put_temp_declarations(code.funcstate)
1555         # ----- Python version
1556         code.exit_cfunc_scope()
1557         if self.py_func:
1558             self.py_func.generate_function_definitions(env, code)
1559         self.generate_wrapper_functions(code)
1560
1561     def declare_argument(self, env, arg):
1562         if arg.type.is_void:
1563             error(arg.pos, "Invalid use of 'void'")
1564         elif not arg.type.is_complete() and not arg.type.is_array:
1565             error(arg.pos,
1566                 "Argument type '%s' is incomplete" % arg.type)
1567         return env.declare_arg(arg.name, arg.type, arg.pos)
1568
1569     def generate_arg_type_test(self, arg, code):
1570         # Generate type test for one argument.
1571         if arg.type.typeobj_is_available():
1572             code.globalstate.use_utility_code(arg_type_test_utility_code)
1573             typeptr_cname = arg.type.typeptr_cname
1574             arg_code = "((PyObject *)%s)" % arg.entry.cname
1575             code.putln(
1576                 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1577                     arg_code,
1578                     typeptr_cname,
1579                     arg.accept_none,
1580                     arg.name,
1581                     arg.type.is_builtin_type,
1582                     code.error_goto(arg.pos)))
1583         else:
1584             error(arg.pos, "Cannot test type of extern C class "
1585                 "without type object name specification")
1586
1587     def generate_arg_none_check(self, arg, code):
1588         # Generate None check for one argument.
1589         code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1590         code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1591             arg.name,
1592             code.error_goto(arg.pos)))
1593         code.putln('}')
1594
1595     def generate_wrapper_functions(self, code):
1596         pass
1597
1598     def generate_execution_code(self, code):
1599         # Evaluate and store argument default values
1600         for arg in self.args:
1601             default = arg.default
1602             if default:
1603                 if not default.is_literal:
1604                     default.generate_evaluation_code(code)
1605                     default.make_owned_reference(code)
1606                     result = default.result_as(arg.type)
1607                     code.putln(
1608                         "%s = %s;" % (
1609                             arg.calculate_default_value_code(code),
1610                             result))
1611                     if arg.type.is_pyobject:
1612                         code.put_giveref(default.result())
1613                     default.generate_post_assignment_code(code)
1614                     default.free_temps(code)
1615         # For Python class methods, create and store function object
1616         if self.assmt:
1617             self.assmt.generate_execution_code(code)
1618
1619     #
1620     # Special code for the __getbuffer__ function
1621     #
1622     def getbuffer_init(self, code):
1623         info = self.local_scope.arg_entries[1].cname
1624         # Python 3.0 betas have a bug in memoryview which makes it call
1625         # getbuffer with a NULL parameter. For now we work around this;
1626         # the following block should be removed when this bug is fixed.
1627         code.putln("if (%s != NULL) {" % info)
1628         code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1629         code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1630         code.putln("}")
1631
1632     def getbuffer_error_cleanup(self, code):
1633         info = self.local_scope.arg_entries[1].cname
1634         code.putln("if (%s != NULL && %s->obj != NULL) {"
1635                    % (info, info))
1636         code.put_gotref("%s->obj" % info)
1637         code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;"
1638                    % (info, info))
1639         code.putln("}")
1640
1641     def getbuffer_normal_cleanup(self, code):
1642         info = self.local_scope.arg_entries[1].cname
1643         code.putln("if (%s != NULL && %s->obj == Py_None) {" % (info, info))
1644         code.put_gotref("Py_None")
1645         code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1646         code.putln("}")
1647
1648 class CFuncDefNode(FuncDefNode):
1649     #  C function definition.
1650     #
1651     #  modifiers     ['inline']
1652     #  visibility    'private' or 'public' or 'extern'
1653     #  base_type     CBaseTypeNode
1654     #  declarator    CDeclaratorNode
1655     #  body          StatListNode
1656     #  api           boolean
1657     #  decorators    [DecoratorNode]        list of decorators
1658     #
1659     #  with_gil      boolean    Acquire GIL around body
1660     #  type          CFuncType
1661     #  py_func       wrapper for calling from Python
1662     #  overridable   whether or not this is a cpdef function
1663     #  inline_in_pxd whether this is an inline function in a pxd file
1664
1665     child_attrs = ["base_type", "declarator", "body", "py_func"]
1666
1667     inline_in_pxd = False
1668     decorators = None
1669     directive_locals = None
1670
1671     def unqualified_name(self):
1672         return self.entry.name
1673
1674     def analyse_declarations(self, env):
1675         if self.directive_locals is None:
1676             self.directive_locals = {}
1677         self.directive_locals.update(env.directives['locals'])
1678         base_type = self.base_type.analyse(env)
1679         # The 2 here is because we need both function and argument names.
1680         if isinstance(self.declarator, CFuncDeclaratorNode):
1681             name_declarator, type = self.declarator.analyse(base_type, env,
1682                                                             nonempty = 2 * (self.body is not None),
1683                                                             directive_locals = self.directive_locals)
1684         else:
1685             name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1686         if not type.is_cfunction:
1687             error(self.pos,
1688                 "Suite attached to non-function declaration")
1689         # Remember the actual type according to the function header
1690         # written here, because the type in the symbol table entry
1691         # may be different if we're overriding a C method inherited
1692         # from the base type of an extension type.
1693         self.type = type
1694         type.is_overridable = self.overridable
1695         declarator = self.declarator
1696         while not hasattr(declarator, 'args'):
1697             declarator = declarator.base
1698         self.args = declarator.args
1699         for formal_arg, type_arg in zip(self.args, type.args):
1700             self.align_argument_type(env, type_arg)
1701             formal_arg.type = type_arg.type
1702             formal_arg.name = type_arg.name
1703             formal_arg.cname = type_arg.cname
1704             if type_arg.type.is_buffer and 'inline' in self.modifiers:
1705                 warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1)
1706         name = name_declarator.name
1707         cname = name_declarator.cname
1708         self.entry = env.declare_cfunction(
1709             name, type, self.pos,
1710             cname = cname, visibility = self.visibility,
1711             defining = self.body is not None,
1712             api = self.api, modifiers = self.modifiers)
1713         self.entry.inline_func_in_pxd = self.inline_in_pxd
1714         self.return_type = type.return_type
1715         if self.return_type.is_array and visibility != 'extern':
1716             error(self.pos,
1717                 "Function cannot return an array")
1718
1719         if self.overridable and not env.is_module_scope:
1720             if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1721                 # An error will be produced in the cdef function
1722                 self.overridable = False
1723
1724         if self.overridable:
1725             import ExprNodes
1726             py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1727             self.py_func = DefNode(pos = self.pos,
1728                                    name = self.entry.name,
1729                                    args = self.args,
1730                                    star_arg = None,
1731                                    starstar_arg = None,
1732                                    doc = self.doc,
1733                                    body = py_func_body,
1734                                    is_wrapper = 1)
1735             self.py_func.is_module_scope = env.is_module_scope
1736             self.py_func.analyse_declarations(env)
1737             self.entry.as_variable = self.py_func.entry
1738             # Reset scope entry the above cfunction
1739             env.entries[name] = self.entry
1740             if not env.is_module_scope or Options.lookup_module_cpdef:
1741                 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1742                 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1743         self.create_local_scope(env)
1744
1745     def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1746         import ExprNodes
1747         args = self.type.args
1748         if omit_optional_args:
1749             args = args[:len(args) - self.type.optional_arg_count]
1750         arg_names = [arg.name for arg in args]
1751         if is_module_scope:
1752             cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1753         else:
1754             self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1755             cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1756         skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1757         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)
1758         return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1759
1760     def declare_arguments(self, env):
1761         for arg in self.type.args:
1762             if not arg.name:
1763                 error(arg.pos, "Missing argument name")
1764             self.declare_argument(env, arg)
1765
1766     def need_gil_acquisition(self, lenv):
1767         return self.type.with_gil
1768
1769     def nogil_check(self, env):
1770         type = self.type
1771         with_gil = type.with_gil
1772         if type.nogil and not with_gil:
1773             if type.return_type.is_pyobject:
1774                 error(self.pos,
1775                       "Function with Python return type cannot be declared nogil")
1776             for entry in self.local_scope.var_entries:
1777                 if entry.type.is_pyobject:
1778                     error(self.pos, "Function declared nogil has Python locals or temporaries")
1779
1780     def analyse_expressions(self, env):
1781         self.local_scope.directives = env.directives
1782         if self.py_func is not None:
1783             # this will also analyse the default values
1784             self.py_func.analyse_expressions(env)
1785         else:
1786             self.analyse_default_values(env)
1787         self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1788
1789     def needs_assignment_synthesis(self, env, code=None):
1790         return False
1791
1792     def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1793         arg_decls = []
1794         type = self.type
1795         for arg in type.args[:len(type.args)-type.optional_arg_count]:
1796             arg_decls.append(arg.declaration_code())
1797         if with_dispatch and self.overridable:
1798             arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1799         if type.optional_arg_count and with_opt_args:
1800             arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1801         if type.has_varargs:
1802             arg_decls.append("...")
1803         if not arg_decls:
1804             arg_decls = ["void"]
1805         if cname is None:
1806             cname = self.entry.func_cname
1807         entity = type.function_header_code(cname, ', '.join(arg_decls))
1808         if self.entry.visibility == 'private':
1809             storage_class = "static "
1810         else:
1811             storage_class = ""
1812         dll_linkage = None
1813         modifiers = ""
1814         if 'inline' in self.modifiers:
1815             self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1816         if self.modifiers:
1817             modifiers = "%s " % ' '.join(self.modifiers).upper()
1818
1819         header = self.return_type.declaration_code(entity, dll_linkage=dll_linkage)
1820         #print (storage_class, modifiers, header)
1821         code.putln("%s%s%s {" % (storage_class, modifiers, header))
1822
1823     def generate_argument_declarations(self, env, code):
1824         for arg in self.args:
1825             if arg.default:
1826                 result = arg.calculate_default_value_code(code)
1827                 code.putln('%s = %s;' % (
1828                     arg.type.declaration_code(arg.cname), result))
1829
1830     def generate_keyword_list(self, code):
1831         pass
1832
1833     def generate_argument_parsing_code(self, env, code):
1834         i = 0
1835         if self.type.optional_arg_count:
1836             code.putln('if (%s) {' % Naming.optional_args_cname)
1837             for arg in self.args:
1838                 if arg.default:
1839                     code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1840                     declarator = arg.declarator
1841                     while not hasattr(declarator, 'name'):
1842                         declarator = declarator.base
1843                     code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1844                     i += 1
1845             for _ in range(self.type.optional_arg_count):
1846                 code.putln('}')
1847             code.putln('}')
1848
1849     def generate_argument_conversion_code(self, code):
1850         pass
1851
1852     def generate_argument_type_tests(self, code):
1853         # Generate type tests for args whose type in a parent
1854         # class is a supertype of the declared type.
1855         for arg in self.type.args:
1856             if arg.needs_type_test:
1857                 self.generate_arg_type_test(arg, code)
1858             elif arg.type.is_pyobject and not arg.accept_none:
1859                 self.generate_arg_none_check(arg, code)
1860
1861     def error_value(self):
1862         if self.return_type.is_pyobject:
1863             return "0"
1864         else:
1865             #return None
1866             return self.entry.type.exception_value
1867
1868     def caller_will_check_exceptions(self):
1869         return self.entry.type.exception_check
1870
1871     def generate_wrapper_functions(self, code):
1872         # If the C signature of a function has changed, we need to generate
1873         # wrappers to put in the slots here.
1874         k = 0
1875         entry = self.entry
1876         func_type = entry.type
1877         while entry.prev_entry is not None:
1878             k += 1
1879             entry = entry.prev_entry
1880             entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1881             code.putln()
1882             self.generate_function_header(code,
1883                                           0,
1884                                           with_dispatch = entry.type.is_overridable,
1885                                           with_opt_args = entry.type.optional_arg_count,
1886                                           cname = entry.func_cname)
1887             if not self.return_type.is_void:
1888                 code.put('return ')
1889             args = self.type.args
1890             arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1891             if entry.type.is_overridable:
1892                 arglist.append(Naming.skip_dispatch_cname)
1893             elif func_type.is_overridable:
1894                 arglist.append('0')
1895             if entry.type.optional_arg_count:
1896                 arglist.append(Naming.optional_args_cname)
1897             elif func_type.optional_arg_count:
1898                 arglist.append('NULL')
1899             code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1900             code.putln('}')
1901
1902
1903 class PyArgDeclNode(Node):
1904     # Argument which must be a Python object (used
1905     # for * and ** arguments).
1906     #
1907     # name        string
1908     # entry       Symtab.Entry
1909     # annotation  ExprNode or None   Py3 argument annotation
1910     child_attrs = []
1911
1912     def generate_function_definitions(self, env, code):
1913         self.entry.generate_function_definitions(env, code)
1914
1915 class DecoratorNode(Node):
1916     # A decorator
1917     #
1918     # decorator    NameNode or CallNode or AttributeNode
1919     child_attrs = ['decorator']
1920
1921
1922 class DefNode(FuncDefNode):
1923     # A Python function definition.
1924     #
1925     # name          string                 the Python name of the function
1926     # lambda_name   string                 the internal name of a lambda 'function'
1927     # decorators    [DecoratorNode]        list of decorators
1928     # args          [CArgDeclNode]         formal arguments
1929     # star_arg      PyArgDeclNode or None  * argument
1930     # starstar_arg  PyArgDeclNode or None  ** argument
1931     # doc           EncodedString or None
1932     # body          StatListNode
1933     # return_type_annotation
1934     #               ExprNode or None       the Py3 return type annotation
1935     #
1936     #  The following subnode is constructed internally
1937     #  when the def statement is inside a Python class definition.
1938     #
1939     #  assmt   AssignmentNode   Function construction/assignment
1940
1941     child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1942
1943     lambda_name = None
1944     assmt = None
1945     num_kwonly_args = 0
1946     num_required_kw_args = 0
1947     reqd_kw_flags_cname = "0"
1948     is_wrapper = 0
1949     no_assignment_synthesis = 0
1950     decorators = None
1951     return_type_annotation = None
1952     entry = None
1953     acquire_gil = 0
1954     self_in_stararg = 0
1955     star_arg = None
1956     starstar_arg = None
1957     doc = None
1958
1959     def __init__(self, pos, **kwds):
1960         FuncDefNode.__init__(self, pos, **kwds)
1961         k = rk = r = 0
1962         for arg in self.args:
1963             if arg.kw_only:
1964                 k += 1
1965                 if not arg.default:
1966                     rk += 1
1967             if not arg.default:
1968                 r += 1
1969         self.num_kwonly_args = k
1970         self.num_required_kw_args = rk
1971         self.num_required_args = r
1972
1973     def as_cfunction(self, cfunc=None, scope=None):
1974         if self.star_arg:
1975             error(self.star_arg.pos, "cdef function cannot have star argument")
1976         if self.starstar_arg:
1977             error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1978         if cfunc is None:
1979             cfunc_args = []
1980             for formal_arg in self.args:
1981                 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1982                 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1983                                                           cname = None,
1984                                                           type = py_object_type,
1985                                                           pos = formal_arg.pos))
1986             cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1987                                               args = cfunc_args,
1988                                               has_varargs = False,
1989                                               exception_value = None,
1990                                               exception_check = False,
1991                                               nogil = False,
1992                                               with_gil = False,
1993                                               is_overridable = True)
1994             cfunc = CVarDefNode(self.pos, type=cfunc_type)
1995         else:
1996             if scope is None:
1997                 scope = cfunc.scope
1998             cfunc_type = cfunc.type
1999             if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
2000                 error(self.pos, "wrong number of arguments")
2001                 error(cfunc.pos, "previous declaration here")
2002             for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
2003                 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
2004                                                            is_self_arg = (i == 0 and scope.is_c_class_scope))
2005                 if type is None or type is PyrexTypes.py_object_type:
2006                     formal_arg.type = type_arg.type
2007                     formal_arg.name_declarator = name_declarator
2008         import ExprNodes
2009         if cfunc_type.exception_value is None:
2010             exception_value = None
2011         else:
2012             exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
2013         declarator = CFuncDeclaratorNode(self.pos,
2014                                          base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
2015                                          args = self.args,
2016                                          has_varargs = False,
2017                                          exception_check = cfunc_type.exception_check,
2018                                          exception_value = exception_value,
2019                                          with_gil = cfunc_type.with_gil,
2020                                          nogil = cfunc_type.nogil)
2021         return CFuncDefNode(self.pos,
2022                             modifiers = [],
2023                             base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
2024                             declarator = declarator,
2025                             body = self.body,
2026                             doc = self.doc,
2027                             overridable = cfunc_type.is_overridable,
2028                             type = cfunc_type,
2029                             with_gil = cfunc_type.with_gil,
2030                             nogil = cfunc_type.nogil,
2031                             visibility = 'private',
2032                             api = False,
2033                             directive_locals = getattr(cfunc, 'directive_locals', {}))
2034
2035     def is_cdef_func_compatible(self):
2036         """Determines if the function's signature is compatible with a
2037         cdef function.  This can be used before calling
2038         .as_cfunction() to see if that will be successful.
2039         """
2040         if self.needs_closure:
2041             return False
2042         if self.star_arg or self.starstar_arg:
2043             return False
2044         return True
2045
2046     def analyse_declarations(self, env):
2047         self.is_classmethod = self.is_staticmethod = False
2048         if self.decorators:
2049             for decorator in self.decorators:
2050                 func = decorator.decorator
2051                 if func.is_name:
2052                     self.is_classmethod |= func.name == 'classmethod'
2053                     self.is_staticmethod |= func.name == 'staticmethod'
2054
2055         if self.is_classmethod and env.lookup_here('classmethod'):
2056             # classmethod() was overridden - not much we can do here ...
2057             self.is_classmethod = False
2058         if self.is_staticmethod and env.lookup_here('staticmethod'):
2059             # staticmethod() was overridden - not much we can do here ...
2060             self.is_staticmethod = False
2061
2062         if self.name == '__new__' and env.is_py_class_scope:
2063             self.is_staticmethod = 1
2064
2065         self.analyse_argument_types(env)
2066         if self.name == '<lambda>':
2067             self.declare_lambda_function(env)
2068         else:
2069             self.declare_pyfunction(env)
2070         self.analyse_signature(env)
2071         self.return_type = self.entry.signature.return_type()
2072         self.create_local_scope(env)
2073
2074     def analyse_argument_types(self, env):
2075         directive_locals = self.directive_locals = env.directives['locals']
2076         allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2077         for arg in self.args:
2078             if hasattr(arg, 'name'):
2079                 name_declarator = None
2080             else:
2081                 base_type = arg.base_type.analyse(env)
2082                 name_declarator, type = \
2083                     arg.declarator.analyse(base_type, env)
2084                 arg.name = name_declarator.name
2085                 arg.type = type
2086             self.align_argument_type(env, arg)
2087             if name_declarator and name_declarator.cname:
2088                 error(self.pos,
2089                     "Python function argument cannot have C name specification")
2090             arg.type = arg.type.as_argument_type()
2091             arg.hdr_type = None
2092             arg.needs_conversion = 0
2093             arg.needs_type_test = 0
2094             arg.is_generic = 1
2095             if arg.type.is_pyobject:
2096                 if arg.or_none:
2097                     arg.accept_none = True
2098                 elif arg.not_none:
2099                     arg.accept_none = False
2100                 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2101                     if arg.default and arg.default.constant_result is None:
2102                         # special case: def func(MyType obj = None)
2103                         arg.accept_none = True
2104                     else:
2105                         # default depends on compiler directive
2106                         arg.accept_none = allow_none_for_extension_args
2107                 else:
2108                     # probably just a plain 'object'
2109                     arg.accept_none = True
2110             else:
2111                 arg.accept_none = True # won't be used, but must be there
2112                 if arg.not_none:
2113                     error(arg.pos, "Only Python type arguments can have 'not None'")
2114                 if arg.or_none:
2115                     error(arg.pos, "Only Python type arguments can have 'or None'")
2116
2117     def analyse_signature(self, env):
2118         if self.entry.is_special:
2119             if self.decorators:
2120                 error(self.pos, "special functions of cdef classes cannot have decorators")
2121             self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2122         elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2123             # Use the simpler calling signature for zero- and one-argument functions.
2124             if self.entry.signature is TypeSlots.pyfunction_signature:
2125                 if len(self.args) == 0:
2126                     self.entry.signature = TypeSlots.pyfunction_noargs
2127                 elif len(self.args) == 1:
2128                     if self.args[0].default is None and not self.args[0].kw_only:
2129                         self.entry.signature = TypeSlots.pyfunction_onearg
2130             elif self.entry.signature is TypeSlots.pymethod_signature:
2131                 if len(self.args) == 1:
2132                     self.entry.signature = TypeSlots.unaryfunc
2133                 elif len(self.args) == 2:
2134                     if self.args[1].default is None and not self.args[1].kw_only:
2135                         self.entry.signature = TypeSlots.ibinaryfunc
2136
2137         sig = self.entry.signature
2138         nfixed = sig.num_fixed_args()
2139         if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2140                and len(self.args) == 0 and self.star_arg:
2141             # this is the only case where a diverging number of
2142             # arguments is not an error - when we have no explicit
2143             # 'self' parameter as in method(*args)
2144             sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2145             self.self_in_stararg = 1
2146             nfixed = 0
2147
2148         for i in range(min(nfixed, len(self.args))):
2149             arg = self.args[i]
2150             arg.is_generic = 0
2151             if sig.is_self_arg(i) and not self.is_staticmethod:
2152                 if self.is_classmethod:
2153                     arg.is_type_arg = 1
2154                     arg.hdr_type = arg.type = Builtin.type_type
2155                 else:
2156                     arg.is_self_arg = 1
2157                     arg.hdr_type = arg.type = env.parent_type
2158                 arg.needs_conversion = 0
2159             else:
2160                 arg.hdr_type = sig.fixed_arg_type(i)
2161                 if not arg.type.same_as(arg.hdr_type):
2162                     if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2163                         arg.needs_type_test = 1
2164                     else:
2165                         arg.needs_conversion = 1
2166             if arg.needs_conversion:
2167                 arg.hdr_cname = Naming.arg_prefix + arg.name
2168             else:
2169                 arg.hdr_cname = Naming.var_prefix + arg.name
2170
2171         if nfixed > len(self.args):
2172             self.bad_signature()
2173             return
2174         elif nfixed < len(self.args):
2175             if not sig.has_generic_args:
2176                 self.bad_signature()
2177             for arg in self.args:
2178                 if arg.is_generic and \
2179                         (arg.type.is_extension_type or arg.type.is_builtin_type):
2180                     arg.needs_type_test = 1
2181
2182     def bad_signature(self):
2183         sig = self.entry.signature
2184         expected_str = "%d" % sig.num_fixed_args()
2185         if sig.has_generic_args:
2186             expected_str = expected_str + " or more"
2187         name = self.name
2188         if name.startswith("__") and name.endswith("__"):
2189             desc = "Special method"
2190         else:
2191             desc = "Method"
2192         error(self.pos,
2193             "%s %s has wrong number of arguments "
2194             "(%d declared, %s expected)" % (
2195                 desc, self.name, len(self.args), expected_str))
2196
2197     def signature_has_nongeneric_args(self):
2198         argcount = len(self.args)
2199         if argcount == 0 or (
2200                 argcount == 1 and (self.args[0].is_self_arg or
2201                                    self.args[0].is_type_arg)):
2202             return 0
2203         return 1
2204
2205     def signature_has_generic_args(self):
2206         return self.entry.signature.has_generic_args
2207
2208     def declare_pyfunction(self, env):
2209         #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2210         name = self.name
2211         entry = env.lookup_here(name)
2212         if entry and entry.type.is_cfunction and not self.is_wrapper:
2213             warning(self.pos, "Overriding cdef method with def method.", 5)
2214         entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2215         self.entry = entry
2216         prefix = env.next_id(env.scope_prefix)
2217
2218         entry.func_cname = \
2219             Naming.pyfunc_prefix + prefix + name
2220         entry.pymethdef_cname = \
2221             Naming.pymethdef_prefix + prefix + name
2222         if Options.docstrings:
2223             entry.doc = embed_position(self.pos, self.doc)
2224             entry.doc_cname = \
2225                 Naming.funcdoc_prefix + prefix + name
2226             if entry.is_special:
2227                 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2228                     entry.wrapperbase_cname = None
2229                 else:
2230                     entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2231         else:
2232             entry.doc = None
2233
2234     def declare_lambda_function(self, env):
2235         entry = env.declare_lambda_function(self.lambda_name, self.pos)
2236         entry.doc = None
2237         self.entry = entry
2238
2239     def declare_arguments(self, env):
2240         for arg in self.args:
2241             if not arg.name:
2242                 error(arg.pos, "Missing argument name")
2243             else:
2244                 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2245                 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2246             if arg.needs_conversion:
2247                 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2248                 if arg.type.is_pyobject:
2249                     arg.entry.init = "0"
2250                 arg.entry.init_to_none = 0
2251             else:
2252                 arg.entry = self.declare_argument(env, arg)
2253             arg.entry.used = 1
2254             arg.entry.is_self_arg = arg.is_self_arg
2255             if arg.hdr_type:
2256                 if arg.is_self_arg or arg.is_type_arg or \
2257                     (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2258                         arg.entry.is_declared_generic = 1
2259         self.declare_python_arg(env, self.star_arg)
2260         self.declare_python_arg(env, self.starstar_arg)
2261
2262     def declare_python_arg(self, env, arg):
2263         if arg:
2264             if env.directives['infer_types'] != False:
2265                 type = PyrexTypes.unspecified_type
2266             else:
2267                 type = py_object_type
2268             entry = env.declare_var(arg.name, type, arg.pos)
2269             entry.used = 1
2270             entry.init = "0"
2271             entry.init_to_none = 0
2272             entry.xdecref_cleanup = 1
2273             arg.entry = entry
2274             env.control_flow.set_state((), (arg.name, 'initialized'), True)
2275
2276     def analyse_expressions(self, env):
2277         self.local_scope.directives = env.directives
2278         self.analyse_default_values(env)
2279         if self.needs_assignment_synthesis(env):
2280             # Shouldn't we be doing this at the module level too?
2281             self.synthesize_assignment_node(env)
2282
2283     def needs_assignment_synthesis(self, env, code=None):
2284         if self.no_assignment_synthesis:
2285             return False
2286         # Should enable for module level as well, that will require more testing...
2287         if self.entry.is_anonymous:
2288             return True
2289         if env.is_module_scope:
2290             if code is None:
2291                 return env.directives['binding']
2292             else:
2293                 return code.globalstate.directives['binding']
2294         return env.is_py_class_scope or env.is_closure_scope
2295
2296     def synthesize_assignment_node(self, env):
2297         import ExprNodes
2298         genv = env
2299         while genv.is_py_class_scope or genv.is_c_class_scope:
2300             genv = genv.outer_scope
2301
2302         if genv.is_closure_scope:
2303             rhs = ExprNodes.InnerFunctionNode(
2304                 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2305         else:
2306             rhs = ExprNodes.PyCFunctionNode(
2307                 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2308
2309         if env.is_py_class_scope:
2310             if not self.is_staticmethod and not self.is_classmethod:
2311                 rhs.binding = True
2312
2313         self.assmt = SingleAssignmentNode(self.pos,
2314             lhs = ExprNodes.NameNode(self.pos, name = self.name),
2315             rhs = rhs)
2316         self.assmt.analyse_declarations(env)
2317         self.assmt.analyse_expressions(env)
2318
2319     def generate_function_header(self, code, with_pymethdef, proto_only=0):
2320         arg_code_list = []
2321         sig = self.entry.signature
2322         if sig.has_dummy_arg or self.self_in_stararg:
2323             arg_code_list.append(
2324                 "PyObject *%s" % Naming.self_cname)
2325         for arg in self.args:
2326             if not arg.is_generic:
2327                 if arg.is_self_arg or arg.is_type_arg:
2328                     arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2329                 else:
2330                     arg_code_list.append(
2331                         arg.hdr_type.declaration_code(arg.hdr_cname))
2332         if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2333             arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2334         if (self.entry.scope.is_c_class_scope and self.entry.name == "__ipow__"):
2335             arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2336         if sig.has_generic_args:
2337             arg_code_list.append(
2338                 "PyObject *%s, PyObject *%s"
2339                     % (Naming.args_cname, Naming.kwds_cname))
2340         arg_code = ", ".join(arg_code_list)
2341         dc = self.return_type.declaration_code(self.entry.func_cname)
2342         mf = " ".join(self.modifiers).upper()
2343         if mf: mf += " "
2344         header = "static %s%s(%s)" % (mf, dc, arg_code)
2345         code.putln("%s; /*proto*/" % header)
2346         if proto_only:
2347             return
2348         if (Options.docstrings and self.entry.doc and
2349                 not self.entry.scope.is_property_scope and
2350                 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2351             docstr = self.entry.doc
2352             if docstr.is_unicode:
2353                 docstr = docstr.utf8encode()
2354             code.putln(
2355                 'static char %s[] = "%s";' % (
2356                     self.entry.doc_cname,
2357                     split_string_literal(escape_byte_string(docstr))))
2358             if self.entry.is_special:
2359                 code.putln(
2360                     "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2361         if with_pymethdef:
2362             code.put(
2363                 "static PyMethodDef %s = " %
2364                     self.entry.pymethdef_cname)
2365             code.put_pymethoddef(self.entry, ";", allow_skip=False)
2366         code.putln("%s {" % header)
2367
2368     def generate_argument_declarations(self, env, code):
2369         for arg in self.args:
2370             if arg.is_generic: # or arg.needs_conversion:
2371                 if arg.needs_conversion:
2372                     code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2373                 elif not arg.entry.in_closure:
2374                     code.put_var_declaration(arg.entry)
2375
2376     def generate_keyword_list(self, code):
2377         if self.signature_has_generic_args() and \
2378                 self.signature_has_nongeneric_args():
2379             code.put(
2380                 "static PyObject **%s[] = {" %
2381                     Naming.pykwdlist_cname)
2382             for arg in self.args:
2383                 if arg.is_generic:
2384                     pystring_cname = code.intern_identifier(arg.name)
2385                     code.put('&%s,' % pystring_cname)
2386             code.putln("0};")
2387
2388     def generate_argument_parsing_code(self, env, code):
2389         # Generate fast equivalent of PyArg_ParseTuple call for
2390         # generic arguments, if any, including args/kwargs
2391         if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2392             # get rid of unused argument warning
2393             code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2394
2395         old_error_label = code.new_error_label()
2396         our_error_label = code.error_label
2397         end_label = code.new_label("argument_unpacking_done")
2398
2399         has_kwonly_args = self.num_kwonly_args > 0
2400         has_star_or_kw_args = self.star_arg is not None \
2401             or self.starstar_arg is not None or has_kwonly_args
2402
2403         for arg in self.args:
2404             if not arg.type.is_pyobject:
2405                 done = arg.type.create_from_py_utility_code(env)
2406                 if not done: pass # will fail later
2407
2408         if not self.signature_has_generic_args():
2409             if has_star_or_kw_args:
2410                 error(self.pos, "This method cannot have * or keyword arguments")
2411             self.generate_argument_conversion_code(code)
2412
2413         elif not self.signature_has_nongeneric_args():
2414             # func(*args) or func(**kw) or func(*args, **kw)
2415             self.generate_stararg_copy_code(code)
2416
2417         else:
2418             positional_args = []
2419             kw_only_args = []
2420             for arg in self.args:
2421                 arg_entry = arg.entry
2422                 if arg.is_generic:
2423                     if arg.default:
2424                         if not arg.is_self_arg and not arg.is_type_arg:
2425                             if arg.kw_only:
2426                                 kw_only_args.append(arg)
2427                             else:
2428                                 positional_args.append(arg)
2429                     elif arg.kw_only:
2430                         kw_only_args.append(arg)
2431                     elif not arg.is_self_arg and not arg.is_type_arg:
2432                         positional_args.append(arg)
2433
2434             self.generate_tuple_and_keyword_parsing_code(
2435                 positional_args, kw_only_args, end_label, code)
2436
2437         code.error_label = old_error_label
2438         if code.label_used(our_error_label):
2439             if not code.label_used(end_label):
2440                 code.put_goto(end_label)
2441             code.put_label(our_error_label)
2442             if has_star_or_kw_args:
2443                 self.generate_arg_decref(self.star_arg, code)
2444                 if self.starstar_arg:
2445                     if self.starstar_arg.entry.xdecref_cleanup:
2446                         code.put_var_xdecref_clear(self.starstar_arg.entry)
2447                     else:
2448                         code.put_var_decref_clear(self.starstar_arg.entry)
2449             code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2450             # The arguments are put into the closure one after the
2451             # other, so when type errors are found, all references in
2452             # the closure instance must be properly ref-counted to
2453             # facilitate generic closure instance deallocation.  In
2454             # the case of an argument type error, it's best to just
2455             # DECREF+clear the already handled references, as this
2456             # frees their references as early as possible.
2457             for arg in self.args:
2458                 if arg.type.is_pyobject and arg.entry.in_closure:
2459                     code.put_var_xdecref_clear(arg.entry)
2460             if self.needs_closure:
2461                 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2462             code.put_finish_refcount_context()
2463             code.putln("return %s;" % self.error_value())
2464         if code.label_used(end_label):
2465             code.put_label(end_label)
2466
2467         # fix refnanny view on closure variables here, instead of
2468         # doing it separately for each arg parsing special case
2469         if self.star_arg and self.star_arg.entry.in_closure:
2470             code.put_var_giveref(self.star_arg.entry)
2471         if self.starstar_arg and self.starstar_arg.entry.in_closure:
2472             code.put_var_giveref(self.starstar_arg.entry)
2473         for arg in self.args:
2474             if arg.type.is_pyobject and arg.entry.in_closure:
2475                 code.put_var_giveref(arg.entry)
2476
2477     def generate_arg_assignment(self, arg, item, code):
2478         if arg.type.is_pyobject:
2479             if arg.is_generic:
2480                 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2481             entry = arg.entry
2482             if entry.in_closure:
2483                 code.put_incref(item, PyrexTypes.py_object_type)
2484             code.putln("%s = %s;" % (entry.cname, item))
2485         else:
2486             func = arg.type.from_py_function
2487             if func:
2488                 code.putln("%s = %s(%s); %s" % (
2489                     arg.entry.cname,
2490                     func,
2491                     item,
2492                     code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2493             else:
2494                 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2495
2496     def generate_arg_xdecref(self, arg, code):
2497         if arg:
2498             code.put_var_xdecref_clear(arg.entry)
2499
2500     def generate_arg_decref(self, arg, code):
2501         if arg:
2502             code.put_var_decref_clear(arg.entry)
2503
2504     def generate_stararg_copy_code(self, code):
2505         if not self.star_arg:
2506             code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2507             code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2508                        Naming.args_cname)
2509             code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2510                     self.name, Naming.args_cname, self.error_value()))
2511             code.putln("}")
2512
2513         if self.starstar_arg:
2514             if self.star_arg:
2515                 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2516             else:
2517                 kwarg_check = "%s" % Naming.kwds_cname
2518         else:
2519             kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2520                 Naming.kwds_cname, Naming.kwds_cname)
2521         code.globalstate.use_utility_code(keyword_string_check_utility_code)
2522         code.putln(
2523             "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2524                 kwarg_check, Naming.kwds_cname, self.name,
2525                 bool(self.starstar_arg), self.error_value()))
2526
2527         if self.starstar_arg:
2528             code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2529                     self.starstar_arg.entry.cname,
2530                     Naming.kwds_cname,
2531                     Naming.kwds_cname))
2532             code.putln("if (unlikely(!%s)) return %s;" % (
2533                     self.starstar_arg.entry.cname, self.error_value()))
2534             self.starstar_arg.entry.xdecref_cleanup = 0
2535             code.put_gotref(self.starstar_arg.entry.cname)
2536
2537         if self.self_in_stararg:
2538             # need to create a new tuple with 'self' inserted as first item
2539             code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2540                     self.star_arg.entry.cname,
2541                     Naming.args_cname,
2542                     self.star_arg.entry.cname))
2543             if self.starstar_arg:
2544                 code.putln("{")
2545                 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2546                 code.putln("return %s;" % self.error_value())
2547                 code.putln("}")
2548             else:
2549                 code.putln("return %s;" % self.error_value())
2550             code.put_gotref(self.star_arg.entry.cname)
2551             code.put_incref(Naming.self_cname, py_object_type)
2552             code.put_giveref(Naming.self_cname)
2553             code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2554                 self.star_arg.entry.cname, Naming.self_cname))
2555             temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2556             code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2557                 temp, temp, Naming.args_cname, temp))
2558             code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2559                 Naming.args_cname, temp))
2560             code.put_incref("item", py_object_type)
2561             code.put_giveref("item")
2562             code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2563                 self.star_arg.entry.cname, temp))
2564             code.putln("}")
2565             code.funcstate.release_temp(temp)
2566             self.star_arg.entry.xdecref_cleanup = 0
2567         elif self.star_arg:
2568             code.put_incref(Naming.args_cname, py_object_type)
2569             code.putln("%s = %s;" % (
2570                     self.star_arg.entry.cname,
2571                     Naming.args_cname))
2572             self.star_arg.entry.xdecref_cleanup = 0
2573
2574     def generate_tuple_and_keyword_parsing_code(self, positional_args,
2575                                                 kw_only_args, success_label, code):
2576         argtuple_error_label = code.new_label("argtuple_error")
2577
2578         min_positional_args = self.num_required_args - self.num_required_kw_args
2579         if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2580             min_positional_args -= 1
2581         max_positional_args = len(positional_args)
2582         has_fixed_positional_count = not self.star_arg and \
2583             min_positional_args == max_positional_args
2584
2585         if self.num_required_kw_args:
2586             code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2587
2588         if self.starstar_arg or self.star_arg:
2589             self.generate_stararg_init_code(max_positional_args, code)
2590
2591         # --- optimised code when we receive keyword arguments
2592         if self.num_required_kw_args:
2593             likely_hint = "likely"
2594         else:
2595             likely_hint = "unlikely"
2596         code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2597         self.generate_keyword_unpacking_code(
2598             min_positional_args, max_positional_args,
2599             has_fixed_positional_count,
2600             positional_args, kw_only_args, argtuple_error_label, code)
2601
2602         # --- optimised code when we do not receive any keyword arguments
2603         if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2604             # Python raises arg tuple related errors first, so we must
2605             # check the length here
2606             if min_positional_args == max_positional_args and not self.star_arg:
2607                 compare = '!='
2608             else:
2609                 compare = '<'
2610             code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2611                     Naming.args_cname, compare, min_positional_args))
2612             code.put_goto(argtuple_error_label)
2613
2614         if self.num_required_kw_args:
2615             # pure error case: keywords required but not passed
2616             if max_positional_args > min_positional_args and not self.star_arg:
2617                 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2618                         Naming.args_cname, max_positional_args))
2619                 code.put_goto(argtuple_error_label)
2620             code.putln('} else {')
2621             for i, arg in enumerate(kw_only_args):
2622                 if not arg.default:
2623                     pystring_cname = code.intern_identifier(arg.name)
2624                     # required keyword-only argument missing
2625                     code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2626                             self.name,
2627                             pystring_cname))
2628                     code.putln(code.error_goto(self.pos))
2629                     break
2630
2631         elif min_positional_args == max_positional_args:
2632             # parse the exact number of positional arguments from the
2633             # args tuple
2634             code.putln('} else {')
2635             for i, arg in enumerate(positional_args):
2636                 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2637                 self.generate_arg_assignment(arg, item, code)
2638             self.generate_arg_default_assignments(code)
2639
2640         else:
2641             # parse the positional arguments from the variable length
2642             # args tuple
2643             code.putln('} else {')
2644             self.generate_arg_default_assignments(code)
2645             code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2646             if self.star_arg:
2647                 code.putln('default:')
2648             reversed_args = list(enumerate(positional_args))[::-1]
2649             for i, arg in reversed_args:
2650                 if i >= min_positional_args-1:
2651                     if min_positional_args > 1:
2652                         code.putln('case %2d:' % (i+1)) # pure code beautification
2653                     else:
2654                         code.put('case %2d: ' % (i+1))
2655                 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2656                 self.generate_arg_assignment(arg, item, code)
2657             if min_positional_args == 0:
2658                 code.put('case  0: ')
2659             code.putln('break;')
2660             if self.star_arg:
2661                 if min_positional_args:
2662                     for i in range(min_positional_args-1, -1, -1):
2663                         code.putln('case %2d:' % i)
2664                     code.put_goto(argtuple_error_label)
2665             else:
2666                 code.put('default: ')
2667                 code.put_goto(argtuple_error_label)
2668             code.putln('}')
2669
2670         code.putln('}')
2671
2672         if code.label_used(argtuple_error_label):
2673             code.put_goto(success_label)
2674             code.put_label(argtuple_error_label)
2675             code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2676             code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2677                     self.name, has_fixed_positional_count,
2678                     min_positional_args, max_positional_args,
2679                     Naming.args_cname))
2680             code.putln(code.error_goto(self.pos))
2681
2682     def generate_arg_default_assignments(self, code):
2683         for arg in self.args:
2684             if arg.is_generic and arg.default:
2685                 code.putln(
2686                     "%s = %s;" % (
2687                         arg.entry.cname,
2688                         arg.calculate_default_value_code(code)))
2689
2690     def generate_stararg_init_code(self, max_positional_args, code):
2691         if self.starstar_arg:
2692             self.starstar_arg.entry.xdecref_cleanup = 0
2693             code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2694                     self.starstar_arg.entry.cname,
2695                     self.starstar_arg.entry.cname,
2696                     self.error_value()))
2697             code.put_gotref(self.starstar_arg.entry.cname)
2698         if self.star_arg:
2699             self.star_arg.entry.xdecref_cleanup = 0
2700             code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2701                     Naming.args_cname,
2702                     max_positional_args))
2703             code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % (
2704                     self.star_arg.entry.cname, Naming.args_cname,
2705                     max_positional_args, Naming.args_cname))
2706             code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2707             if self.starstar_arg:
2708                 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2709             if self.needs_closure:
2710                 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2711             code.put_finish_refcount_context()
2712             code.putln('return %s;' % self.error_value())
2713             code.putln('}')
2714             code.put_gotref(self.star_arg.entry.cname)
2715             code.putln('} else {')
2716             code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2717             code.put_incref(Naming.empty_tuple, py_object_type)
2718             code.putln('}')
2719
2720     def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2721                                         has_fixed_positional_count, positional_args,
2722                                         kw_only_args, argtuple_error_label, code):
2723         all_args = tuple(positional_args) + tuple(kw_only_args)
2724         max_args = len(all_args)
2725
2726         code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2727                    Naming.kwds_cname)
2728         # the 'values' array collects borrowed references to arguments
2729         # before doing any type coercion etc.
2730         code.putln("PyObject* values[%d] = {%s};" % (
2731             max_args, ','.join('0'*max_args)))
2732
2733         # assign borrowed Python default values to the values array,
2734         # so that they can be overwritten by received arguments below
2735         for i, arg in enumerate(all_args):
2736             if arg.default and arg.type.is_pyobject:
2737                 default_value = arg.calculate_default_value_code(code)
2738                 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2739
2740         # parse the args tuple and check that it's not too long
2741         code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2742         if self.star_arg:
2743             code.putln('default:')
2744         for i in range(max_positional_args-1, -1, -1):
2745             code.put('case %2d: ' % (i+1))
2746             code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2747                     i, Naming.args_cname, i))
2748         code.putln('case  0: break;')
2749         if not self.star_arg:
2750             code.put('default: ') # more arguments than allowed
2751             code.put_goto(argtuple_error_label)
2752         code.putln('}')
2753
2754         # now fill up the positional/required arguments with values
2755         # from the kw dict
2756         if self.num_required_args or max_positional_args > 0:
2757             last_required_arg = -1
2758             for i, arg in enumerate(all_args):
2759                 if not arg.default:
2760                     last_required_arg = i
2761             if last_required_arg < max_positional_args:
2762                 last_required_arg = max_positional_args-1
2763             num_required_args = self.num_required_args
2764             if max_positional_args > 0:
2765                 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2766             for i, arg in enumerate(all_args[:last_required_arg+1]):
2767                 if max_positional_args > 0 and i <= max_positional_args:
2768                     if self.star_arg and i == max_positional_args:
2769                         code.putln('default:')
2770                     else:
2771                         code.putln('case %2d:' % i)
2772                 pystring_cname = code.intern_identifier(arg.name)
2773                 if arg.default:
2774                     if arg.kw_only:
2775                         # handled separately below
2776                         continue
2777                     code.putln('if (kw_args > 0) {')
2778                     code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2779                         Naming.kwds_cname, pystring_cname))
2780                     code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2781                     code.putln('}')
2782                 else:
2783                     num_required_args -= 1
2784                     code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2785                         i, Naming.kwds_cname, pystring_cname))
2786                     code.putln('if (likely(values[%d])) kw_args--;' % i);
2787                     if i < min_positional_args:
2788                         if i == 0:
2789                             # special case: we know arg 0 is missing
2790                             code.put('else ')
2791                             code.put_goto(argtuple_error_label)
2792                         else:
2793                             # print the correct number of values (args or
2794                             # kwargs) that were passed into positional
2795                             # arguments up to this point
2796                             code.putln('else {')
2797                             code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2798                             code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2799                                     self.name, has_fixed_positional_count,
2800                                     min_positional_args, max_positional_args, i))
2801                             code.putln(code.error_goto(self.pos))
2802                             code.putln('}')
2803                     elif arg.kw_only:
2804                         code.putln('else {')
2805                         code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2806                                 self.name, pystring_cname))
2807                         code.putln(code.error_goto(self.pos))
2808                         code.putln('}')
2809             if max_positional_args > 0:
2810                 code.putln('}')
2811
2812         if kw_only_args and not self.starstar_arg:
2813             # unpack optional keyword-only arguments
2814             # checking for interned strings in a dict is faster than iterating
2815             # but it's too likely that we must iterate if we expect **kwargs
2816             optional_args = []
2817             for i, arg in enumerate(all_args[max_positional_args:]):
2818                 if not arg.kw_only or not arg.default:
2819                     continue
2820                 optional_args.append((i+max_positional_args, arg))
2821             if optional_args:
2822                 # this mimics an unrolled loop so that we can "break" out of it
2823                 code.putln('while (kw_args > 0) {')
2824                 code.putln('PyObject* value;')
2825                 for i, arg in optional_args:
2826                     pystring_cname = code.intern_identifier(arg.name)
2827                     code.putln(
2828                         'value = PyDict_GetItem(%s, %s);' % (
2829                         Naming.kwds_cname, pystring_cname))
2830                     code.putln(
2831                         'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2832                 code.putln('break;')
2833                 code.putln('}')
2834
2835         code.putln('if (unlikely(kw_args > 0)) {')
2836         # non-positional/-required kw args left in dict: default args,
2837         # kw-only args, **kwargs or error
2838         #
2839         # This is sort of a catch-all: except for checking required
2840         # arguments, this will always do the right thing for unpacking
2841         # keyword arguments, so that we can concentrate on optimising
2842         # common cases above.
2843         if max_positional_args == 0:
2844             pos_arg_count = "0"
2845         elif self.star_arg:
2846             code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2847                     Naming.args_cname, max_positional_args,
2848                     Naming.args_cname, max_positional_args))
2849             pos_arg_count = "used_pos_args"
2850         else:
2851             pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2852         code.globalstate.use_utility_code(parse_keywords_utility_code)
2853         code.put(
2854             'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2855                 Naming.kwds_cname,
2856                 Naming.pykwdlist_cname,
2857                 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2858                 pos_arg_count,
2859                 self.name))
2860         code.putln(code.error_goto(self.pos))
2861         code.putln('}')
2862
2863         # convert arg values to their final type and assign them
2864         for i, arg in enumerate(all_args):
2865             if arg.default and not arg.type.is_pyobject:
2866                 code.putln("if (values[%d]) {" % i)
2867             self.generate_arg_assignment(arg, "values[%d]" % i, code)
2868             if arg.default and not arg.type.is_pyobject:
2869                 code.putln('} else {')
2870                 code.putln(
2871                     "%s = %s;" % (
2872                         arg.entry.cname,
2873                         arg.calculate_default_value_code(code)))
2874                 code.putln('}')
2875
2876     def generate_argument_conversion_code(self, code):
2877         # Generate code to convert arguments from signature type to
2878         # declared type, if needed.  Also copies signature arguments
2879         # into closure fields.
2880         for arg in self.args:
2881             if arg.needs_conversion:
2882                 self.generate_arg_conversion(arg, code)
2883             elif arg.entry.in_closure:
2884                 if arg.type.is_pyobject:
2885                     code.put_incref(arg.hdr_cname, py_object_type)
2886                 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2887
2888     def generate_arg_conversion(self, arg, code):
2889         # Generate conversion code for one argument.
2890         old_type = arg.hdr_type
2891         new_type = arg.type
2892         if old_type.is_pyobject:
2893             if arg.default:
2894                 code.putln("if (%s) {" % arg.hdr_cname)
2895             else:
2896                 code.putln("assert(%s); {" % arg.hdr_cname)
2897             self.generate_arg_conversion_from_pyobject(arg, code)
2898             code.putln("}")
2899         elif new_type.is_pyobject:
2900             self.generate_arg_conversion_to_pyobject(arg, code)
2901         else:
2902             if new_type.assignable_from(old_type):
2903                 code.putln(
2904                     "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2905             else:
2906                 error(arg.pos,
2907                     "Cannot convert 1 argument from '%s' to '%s'" %
2908                         (old_type, new_type))
2909
2910     def generate_arg_conversion_from_pyobject(self, arg, code):
2911         new_type = arg.type
2912         func = new_type.from_py_function
2913         # copied from CoerceFromPyTypeNode
2914         if func:
2915             lhs = arg.entry.cname
2916             rhs = "%s(%s)" % (func, arg.hdr_cname)
2917             if new_type.is_enum:
2918                 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2919             code.putln("%s = %s; %s" % (
2920                 lhs,
2921                 rhs,
2922                 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2923         else:
2924             error(arg.pos,
2925                 "Cannot convert Python object argument to type '%s'"
2926                     % new_type)
2927
2928     def generate_arg_conversion_to_pyobject(self, arg, code):
2929         old_type = arg.hdr_type
2930         func = old_type.to_py_function
2931         if func:
2932             code.putln("%s = %s(%s); %s" % (
2933                 arg.entry.cname,
2934                 func,
2935                 arg.hdr_cname,
2936                 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2937             code.put_var_gotref(arg.entry)
2938         else:
2939             error(arg.pos,
2940                 "Cannot convert argument of type '%s' to Python object"
2941                     % old_type)
2942
2943     def generate_argument_type_tests(self, code):
2944         # Generate type tests for args whose signature
2945         # type is PyObject * and whose declared type is
2946         # a subtype thereof.
2947         for arg in self.args:
2948             if arg.needs_type_test:
2949                 self.generate_arg_type_test(arg, code)
2950             elif not arg.accept_none and arg.type.is_pyobject:
2951                 self.generate_arg_none_check(arg, code)
2952
2953     def error_value(self):
2954         return self.entry.signature.error_value
2955
2956     def caller_will_check_exceptions(self):
2957         return 1
2958
2959
2960 class GeneratorDefNode(DefNode):
2961     # Generator DefNode.
2962     #
2963     # gbody          GeneratorBodyDefNode
2964     #
2965
2966     is_generator = True
2967     needs_closure = True
2968
2969     child_attrs = DefNode.child_attrs + ["gbody"]
2970
2971     def __init__(self, **kwargs):
2972         # XXX: don't actually needs a body
2973         kwargs['body'] = StatListNode(kwargs['pos'], stats=[])
2974         super(GeneratorDefNode, self).__init__(**kwargs)
2975
2976     def analyse_declarations(self, env):
2977         super(GeneratorDefNode, self).analyse_declarations(env)
2978         self.gbody.local_scope = self.local_scope
2979         self.gbody.analyse_declarations(env)
2980
2981     def generate_function_body(self, env, code):
2982         body_cname = self.gbody.entry.func_cname
2983         generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
2984
2985         code.putln('%s.resume_label = 0;' % generator_cname)
2986         code.putln('%s.body = (__pyx_generator_body_t) %s;' % (generator_cname, body_cname))
2987         code.put_giveref(Naming.cur_scope_cname)
2988         code.put_finish_refcount_context()
2989         code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
2990
2991     def generate_function_definitions(self, env, code):
2992         self.gbody.generate_function_header(code, proto=True)
2993         super(GeneratorDefNode, self).generate_function_definitions(env, code)
2994         self.gbody.generate_function_definitions(env, code)
2995
2996
2997 class GeneratorBodyDefNode(DefNode):
2998     # Generator body DefNode.
2999     #
3000
3001     is_generator_body = True
3002
3003     def __init__(self, pos=None, name=None, body=None):
3004         super(GeneratorBodyDefNode, self).__init__(pos=pos, body=body, name=name, doc=None,
3005                                                    args=[],
3006                                                    star_arg=None, starstar_arg=None)
3007
3008     def declare_generator_body(self, env):
3009         prefix = env.next_id(env.scope_prefix)
3010         name = env.next_id('generator')
3011         entry = env.declare_var(prefix + name, py_object_type, self.pos, visibility='private')
3012         entry.func_cname = Naming.genbody_prefix + prefix + name
3013         entry.qualified_name = EncodedString(self.name)
3014         self.entry = entry
3015
3016     def analyse_declarations(self, env):
3017         self.analyse_argument_types(env)
3018         self.declare_generator_body(env)
3019
3020     def generate_function_header(self, code, proto=False):
3021         header = "static PyObject *%s(%s, PyObject *%s)" % (
3022             self.entry.func_cname,
3023             self.local_scope.scope_class.type.declaration_code(Naming.cur_scope_cname),
3024             Naming.sent_value_cname)
3025         if proto:
3026             code.putln('%s; /* proto */' % header)
3027         else:
3028             code.putln('%s /* generator body */\n{' % header);
3029
3030     def generate_function_definitions(self, env, code):
3031         lenv = self.local_scope
3032
3033         # Generate closure function definitions
3034         self.body.generate_function_definitions(lenv, code)
3035
3036         # Generate C code for header and body of function
3037         code.enter_cfunc_scope()
3038         code.return_from_error_cleanup_label = code.new_label()
3039
3040         # ----- Top-level constants used by this function
3041         code.mark_pos(self.pos)
3042         self.generate_cached_builtins_decls(lenv, code)
3043         # ----- Function header
3044         code.putln("")
3045         self.generate_function_header(code)
3046         # ----- Local variables
3047         code.putln("PyObject *%s = NULL;" % Naming.retval_cname)
3048         tempvardecl_code = code.insertion_point()
3049         code.put_declare_refcount_context()
3050         code.put_setup_refcount_context(self.entry.name)
3051
3052         # ----- Resume switch point.
3053         code.funcstate.init_closure_temps(lenv.scope_class.type.scope)
3054         resume_code = code.insertion_point()
3055         first_run_label = code.new_label('first_run')
3056         code.use_label(first_run_label)
3057         code.put_label(first_run_label)
3058         code.putln('%s' %
3059                    (code.error_goto_if_null(Naming.sent_value_cname, self.pos)))
3060
3061         # ----- Function body
3062         self.generate_function_body(env, code)
3063         code.putln('PyErr_SetNone(PyExc_StopIteration); %s' % code.error_goto(self.pos))
3064         # ----- Error cleanup
3065         if code.error_label in code.labels_used:
3066             code.put_goto(code.return_label)
3067             code.put_label(code.error_label)
3068             for cname, type in code.funcstate.all_managed_temps():
3069                 code.put_xdecref(cname, type)
3070             code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
3071
3072         # ----- Non-error return cleanup
3073         code.put_label(code.return_label)
3074         code.put_xdecref(Naming.retval_cname, py_object_type)
3075         code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
3076         code.put_finish_refcount_context()
3077         code.putln('return NULL;');
3078         code.putln("}")
3079
3080         # ----- Go back and insert temp variable declarations
3081         tempvardecl_code.put_temp_declarations(code.funcstate)
3082         # ----- Generator resume code
3083         resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
3084         resume_code.putln("case 0: goto %s;" % first_run_label)
3085
3086         from ParseTreeTransforms import YieldNodeCollector
3087         collector = YieldNodeCollector()
3088         collector.visitchildren(self)
3089         for yield_expr in collector.yields:
3090             resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
3091         resume_code.putln("default: /* CPython raises the right error here */");
3092         resume_code.put_finish_refcount_context()
3093         resume_code.putln("return NULL;");
3094         resume_code.putln("}");
3095
3096         code.exit_cfunc_scope()
3097
3098
3099 class OverrideCheckNode(StatNode):
3100     # A Node for dispatching to the def method if it
3101     # is overriden.
3102     #
3103     #  py_func
3104     #
3105     #  args
3106     #  func_temp
3107     #  body
3108
3109     child_attrs = ['body']
3110
3111     body = None
3112
3113     def analyse_expressions(self, env):
3114         self.args = env.arg_entries
3115         if self.py_func.is_module_scope:
3116             first_arg = 0
3117         else:
3118             first_arg = 1
3119         import ExprNodes
3120         self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
3121         call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3122         call_node = ExprNodes.SimpleCallNode(self.pos,
3123                                              function=self.func_node,
3124                                              args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3125         self.body = ReturnStatNode(self.pos, value=call_node)
3126         self.body.analyse_expressions(env)
3127
3128     def generate_execution_code(self, code):
3129         interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
3130         # Check to see if we are an extension type
3131         if self.py_func.is_module_scope:
3132             self_arg = "((PyObject *)%s)" % Naming.module_cname
3133         else:
3134             self_arg = "((PyObject *)%s)" % self.args[0].cname
3135         code.putln("/* Check if called by wrapper */")
3136         code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
3137         code.putln("/* Check if overriden in Python */")
3138         if self.py_func.is_module_scope:
3139             code.putln("else {")
3140         else:
3141             code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
3142         func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3143         self.func_node.set_cname(func_node_temp)
3144         # need to get attribute manually--scope would return cdef method
3145         err = code.error_goto_if_null(func_node_temp, self.pos)
3146         code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
3147             func_node_temp, self_arg, interned_attr_cname, err))
3148         code.put_gotref(func_node_temp)
3149         is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
3150         is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
3151             func_node_temp, self.py_func.entry.func_cname)
3152         code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
3153         self.body.generate_execution_code(code)
3154         code.putln("}")
3155         code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
3156         code.funcstate.release_temp(func_node_temp)
3157         code.putln("}")
3158
3159 class ClassDefNode(StatNode, BlockNode):
3160     pass
3161
3162 class PyClassDefNode(ClassDefNode):
3163     #  A Python class definition.
3164     #
3165     #  name     EncodedString   Name of the class
3166     #  doc      string or None
3167     #  body     StatNode        Attribute definition code
3168     #  entry    Symtab.Entry
3169     #  scope    PyClassScope
3170     #  decorators    [DecoratorNode]        list of decorators or None
3171     #
3172     #  The following subnodes are constructed internally:
3173     #
3174     #  dict     DictNode   Class dictionary or Py3 namespace
3175     #  classobj ClassNode  Class object
3176     #  target   NameNode   Variable to assign class object to
3177
3178     child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
3179     decorators = None
3180     py3_style_class = False # Python3 style class (bases+kwargs)
3181
3182     def __init__(self, pos, name, bases, doc, body, decorators = None,
3183                  keyword_args = None, starstar_arg = None):
3184         StatNode.__init__(self, pos)
3185         self.name = name
3186         self.doc = doc
3187         self.body = body
3188         self.decorators = decorators
3189         import ExprNodes
3190         if self.doc and Options.docstrings:
3191             doc = embed_position(self.pos, self.doc)
3192             doc_node = ExprNodes.StringNode(pos, value = doc)
3193         else:
3194             doc_node = None
3195         if keyword_args or starstar_arg:
3196             self.py3_style_class = True
3197             self.bases = bases
3198             self.metaclass = None
3199             if keyword_args and not starstar_arg:
3200                 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3201                     if item.key.value == 'metaclass':
3202                         if self.metaclass is not None:
3203                             error(item.pos, "keyword argument 'metaclass' passed multiple times")
3204                         # special case: we already know the metaclass,
3205                         # so we don't need to do the "build kwargs,
3206                         # find metaclass" dance at runtime
3207                         self.metaclass = item.value
3208                         del keyword_args.key_value_pairs[i]
3209             if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3210                 self.mkw = ExprNodes.KeywordArgsNode(
3211                     pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3212             else:
3213                 self.mkw = ExprNodes.NullNode(pos)
3214             if self.metaclass is None:
3215                 self.metaclass = ExprNodes.PyClassMetaclassNode(
3216                     pos, mkw = self.mkw, bases = self.bases)
3217             self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3218                         doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3219                         mkw = self.mkw)
3220             self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3221                     bases = self.bases, dict = self.dict, doc = doc_node,
3222                     metaclass = self.metaclass, mkw = self.mkw)
3223         else:
3224             self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3225             self.metaclass = None
3226             self.mkw = None
3227             self.bases = None
3228             self.classobj = ExprNodes.ClassNode(pos, name = name,
3229                     bases = bases, dict = self.dict, doc = doc_node)
3230         self.target = ExprNodes.NameNode(pos, name = name)
3231
3232     def as_cclass(self):
3233         """
3234         Return this node as if it were declared as an extension class
3235         """
3236         if self.py3_style_class:
3237             error(self.classobj.pos, "Python3 style class could not be represented as C class")
3238             return
3239         bases = self.classobj.bases.args
3240         if len(bases) == 0:
3241             base_class_name = None
3242             base_class_module = None
3243         elif len(bases) == 1:
3244             base = bases[0]
3245             path = []
3246             from ExprNodes import AttributeNode, NameNode
3247             while isinstance(base, AttributeNode):
3248                 path.insert(0, base.attribute)
3249                 base = base.obj
3250             if isinstance(base, NameNode):
3251                 path.insert(0, base.name)
3252                 base_class_name = path[-1]
3253                 if len(path) > 1:
3254                     base_class_module = u'.'.join(path[:-1])
3255                 else:
3256                     base_class_module = None
3257             else:
3258                 error(self.classobj.bases.args.pos, "Invalid base class")
3259         else:
3260             error(self.classobj.bases.args.pos, "C class may only have one base class")
3261             return None
3262
3263         return CClassDefNode(self.pos,
3264                              visibility = 'private',
3265                              module_name = None,
3266                              class_name = self.name,
3267                              base_class_module = base_class_module,
3268                              base_class_name = base_class_name,
3269                              decorators = self.decorators,
3270                              body = self.body,
3271                              in_pxd = False,
3272                              doc = self.doc)
3273
3274     def create_scope(self, env):
3275         genv = env
3276         while genv.is_py_class_scope or genv.is_c_class_scope:
3277             genv = genv.outer_scope
3278         cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3279         return cenv
3280
3281     def analyse_declarations(self, env):
3282         self.target.analyse_target_declaration(env)
3283         cenv = self.create_scope(env)
3284         cenv.directives = env.directives
3285         cenv.class_obj_cname = self.target.entry.cname
3286         self.body.analyse_declarations(cenv)
3287
3288     def analyse_expressions(self, env):
3289         if self.py3_style_class:
3290             self.bases.analyse_expressions(env)
3291             self.metaclass.analyse_expressions(env)
3292             self.mkw.analyse_expressions(env)
3293         self.dict.analyse_expressions(env)
3294         self.classobj.analyse_expressions(env)
3295         genv = env.global_scope()
3296         cenv = self.scope
3297         self.body.analyse_expressions(cenv)
3298         self.target.analyse_target_expression(env, self.classobj)
3299
3300     def generate_function_definitions(self, env, code):
3301         self.generate_lambda_definitions(self.scope, code)
3302         self.body.generate_function_definitions(self.scope, code)
3303
3304     def generate_execution_code(self, code):
3305         code.pyclass_stack.append(self)
3306         cenv = self.scope
3307         if self.py3_style_class:
3308             self.bases.generate_evaluation_code(code)
3309             self.mkw.generate_evaluation_code(code)
3310             self.metaclass.generate_evaluation_code(code)
3311         self.dict.generate_evaluation_code(code)
3312         cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3313         self.body.generate_execution_code(code)
3314         self.classobj.generate_evaluation_code(code)
3315         cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3316         self.target.generate_assignment_code(self.classobj, code)
3317         self.dict.generate_disposal_code(code)
3318         self.dict.free_temps(code)
3319         if self.py3_style_class:
3320             self.mkw.generate_disposal_code(code)
3321             self.mkw.free_temps(code)
3322             self.metaclass.generate_disposal_code(code)
3323             self.metaclass.free_temps(code)
3324             self.bases.generate_disposal_code(code)
3325             self.bases.free_temps(code)
3326         code.pyclass_stack.pop()
3327
3328 class CClassDefNode(ClassDefNode):
3329     #  An extension type definition.
3330     #
3331     #  visibility         'private' or 'public' or 'extern'
3332     #  typedef_flag       boolean
3333     #  api                boolean
3334     #  module_name        string or None    For import of extern type objects
3335     #  class_name         string            Unqualified name of class
3336     #  as_name            string or None    Name to declare as in this scope
3337     #  base_class_module  string or None    Module containing the base class
3338     #  base_class_name    string or None    Name of the base class
3339     #  objstruct_name     string or None    Specified C name of object struct
3340     #  typeobj_name       string or None    Specified C name of type object
3341     #  in_pxd             boolean           Is in a .pxd file
3342     #  decorators         [DecoratorNode]   list of decorators or None
3343     #  doc                string or None
3344     #  body               StatNode or None
3345     #  entry              Symtab.Entry
3346     #  base_type          PyExtensionType or None
3347     #  buffer_defaults_node DictNode or None Declares defaults for a buffer
3348     #  buffer_defaults_pos
3349
3350     child_attrs = ["body"]
3351     buffer_defaults_node = None
3352     buffer_defaults_pos = None
3353     typedef_flag = False
3354     api = False
3355     objstruct_name = None
3356     typeobj_name = None
3357     decorators = None
3358     shadow = False
3359
3360     def analyse_declarations(self, env):
3361         #print "CClassDefNode.analyse_declarations:", self.class_name
3362         #print "...visibility =", self.visibility
3363         #print "...module_name =", self.module_name
3364
3365         import Buffer
3366         if self.buffer_defaults_node:
3367             buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3368                                                             env, [], self.buffer_defaults_node,
3369                                                             need_complete=False)
3370         else:
3371             buffer_defaults = None
3372
3373         if env.in_cinclude and not self.objstruct_name:
3374             error(self.pos, "Object struct name specification required for "
3375                 "C class defined in 'extern from' block")
3376         self.base_type = None
3377         # Now that module imports are cached, we need to
3378         # import the modules for extern classes.
3379         if self.module_name:
3380             self.module = None
3381             for module in env.cimported_modules:
3382                 if module.name == self.module_name:
3383                     self.module = module
3384             if self.module is None:
3385                 self.module = ModuleScope(self.module_name, None, env.context)
3386                 self.module.has_extern_class = 1
3387                 env.add_imported_module(self.module)
3388
3389         if self.base_class_name:
3390             if self.base_class_module:
3391                 base_class_scope = env.find_module(self.base_class_module, self.pos)
3392             else:
3393                 base_class_scope = env
3394             if self.base_class_name == 'object':
3395                 # extension classes are special and don't need to inherit from object
3396                 if base_class_scope is None or base_class_scope.lookup('object') is None:
3397                     self.base_class_name = None
3398                     self.base_class_module = None
3399                     base_class_scope = None
3400             if base_class_scope:
3401                 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3402                 if base_class_entry:
3403                     if not base_class_entry.is_type:
3404                         error(self.pos, "'%s' is not a type name" % self.base_class_name)
3405                     elif not base_class_entry.type.is_extension_type and \
3406                              not (base_class_entry.type.is_builtin_type and \
3407                                   base_class_entry.type.objstruct_cname):
3408                         error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3409                     elif not base_class_entry.type.is_complete():
3410                         error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3411                             self.base_class_name, self.class_name))
3412                     elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3413                              base_class_entry.type.scope.directives['final']:
3414                         error(self.pos, "Base class '%s' of type '%s' is final" % (
3415                             self.base_class_name, self.class_name))
3416                     elif base_class_entry.type.is_builtin_type and \
3417                              base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3418                         error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3419                               % base_class_entry.type.name)
3420                     else:
3421                         self.base_type = base_class_entry.type
3422         has_body = self.body is not None
3423         if self.module_name and self.visibility != 'extern':
3424             module_path = self.module_name.split(".")
3425             home_scope = env.find_imported_module(module_path, self.pos)
3426             if not home_scope:
3427                 return
3428         else:
3429             home_scope = env
3430
3431         if self.visibility == 'extern':
3432             if (self.module_name == '__builtin__' and
3433                 self.class_name in Builtin.builtin_types and
3434                 env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython
3435                 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3436
3437         self.entry = home_scope.declare_c_class(
3438             name = self.class_name,
3439             pos = self.pos,
3440             defining = has_body and self.in_pxd,
3441             implementing = has_body and not self.in_pxd,
3442             module_name = self.module_name,
3443             base_type = self.base_type,
3444             objstruct_cname = self.objstruct_name,
3445             typeobj_cname = self.typeobj_name,
3446             visibility = self.visibility,
3447             typedef_flag = self.typedef_flag,
3448             api = self.api,
3449             buffer_defaults = buffer_defaults,
3450             shadow = self.shadow)
3451         if self.shadow:
3452             home_scope.lookup(self.class_name).as_variable = self.entry
3453         if home_scope is not env and self.visibility == 'extern':
3454             env.add_imported_entry(self.class_name, self.entry, self.pos)
3455         self.scope = scope = self.entry.type.scope
3456         if scope is not None:
3457             scope.directives = env.directives
3458
3459         if self.doc and Options.docstrings:
3460             scope.doc = embed_position(self.pos, self.doc)
3461
3462         if has_body:
3463             self.body.analyse_declarations(scope)
3464             if self.in_pxd:
3465                 scope.defined = 1
3466             else:
3467                 scope.implemented = 1
3468         env.allocate_vtable_names(self.entry)
3469
3470     def analyse_expressions(self, env):
3471         if self.body:
3472             scope = self.entry.type.scope
3473             self.body.analyse_expressions(scope)
3474
3475     def generate_function_definitions(self, env, code):
3476         if self.body:
3477             self.generate_lambda_definitions(self.scope, code)
3478             self.body.generate_function_definitions(self.scope, code)
3479
3480     def generate_execution_code(self, code):
3481         # This is needed to generate evaluation code for
3482         # default values of method arguments.
3483         if self.body:
3484             self.body.generate_execution_code(code)
3485
3486     def annotate(self, code):
3487         if self.body:
3488             self.body.annotate(code)
3489
3490
3491 class PropertyNode(StatNode):
3492     #  Definition of a property in an extension type.
3493     #
3494     #  name   string
3495     #  doc    EncodedString or None    Doc string
3496     #  body   StatListNode
3497
3498     child_attrs = ["body"]
3499
3500     def analyse_declarations(self, env):
3501         entry = env.declare_property(self.name, self.doc, self.pos)
3502         if entry:
3503             entry.scope.directives = env.directives
3504             self.body.analyse_declarations(entry.scope)
3505
3506     def analyse_expressions(self, env):
3507         self.body.analyse_expressions(env)
3508
3509     def generate_function_definitions(self, env, code):
3510         self.body.generate_function_definitions(env, code)
3511
3512     def generate_execution_code(self, code):
3513         pass
3514
3515     def annotate(self, code):
3516         self.body.annotate(code)
3517
3518
3519 class GlobalNode(StatNode):
3520     # Global variable declaration.
3521     #
3522     # names    [string]
3523
3524     child_attrs = []
3525
3526     def analyse_declarations(self, env):
3527         for name in self.names:
3528             env.declare_global(name, self.pos)
3529
3530     def analyse_expressions(self, env):
3531         pass
3532
3533     def generate_execution_code(self, code):
3534         pass
3535
3536
3537 class NonlocalNode(StatNode):
3538     # Nonlocal variable declaration via the 'nonlocal' keyword.
3539     #
3540     # names    [string]
3541
3542     child_attrs = []
3543
3544     def analyse_declarations(self, env):
3545         for name in self.names:
3546             env.declare_nonlocal(name, self.pos)
3547
3548     def analyse_expressions(self, env):
3549         pass
3550
3551     def generate_execution_code(self, code):
3552         pass
3553
3554
3555 class ExprStatNode(StatNode):
3556     #  Expression used as a statement.
3557     #
3558     #  expr   ExprNode
3559
3560     child_attrs = ["expr"]
3561
3562     def analyse_declarations(self, env):
3563         import ExprNodes
3564         if isinstance(self.expr, ExprNodes.GeneralCallNode):
3565             func = self.expr.function.as_cython_attribute()
3566             if func == u'declare':
3567                 args, kwds = self.expr.explicit_args_kwds()
3568                 if len(args):
3569                     error(self.expr.pos, "Variable names must be specified.")
3570                 for var, type_node in kwds.key_value_pairs:
3571                     type = type_node.analyse_as_type(env)
3572                     if type is None:
3573                         error(type_node.pos, "Unknown type")
3574                     else:
3575                         env.declare_var(var.value, type, var.pos, is_cdef = True)
3576                 self.__class__ = PassStatNode
3577
3578     def analyse_expressions(self, env):
3579         self.expr.result_is_used = False # hint that .result() may safely be left empty
3580         self.expr.analyse_expressions(env)
3581
3582     def nogil_check(self, env):
3583         if self.expr.type.is_pyobject and self.expr.is_temp:
3584             self.gil_error()
3585
3586     gil_message = "Discarding owned Python object"
3587
3588     def generate_execution_code(self, code):
3589         self.expr.generate_evaluation_code(code)
3590         if not self.expr.is_temp and self.expr.result():
3591             code.putln("%s;" % self.expr.result())
3592         self.expr.generate_disposal_code(code)
3593         self.expr.free_temps(code)
3594
3595     def generate_function_definitions(self, env, code):
3596         self.expr.generate_function_definitions(env, code)
3597
3598     def annotate(self, code):
3599         self.expr.annotate(code)
3600
3601
3602 class AssignmentNode(StatNode):
3603     #  Abstract base class for assignment nodes.
3604     #
3605     #  The analyse_expressions and generate_execution_code
3606     #  phases of assignments are split into two sub-phases
3607     #  each, to enable all the right hand sides of a
3608     #  parallel assignment to be evaluated before assigning
3609     #  to any of the left hand sides.
3610
3611     def analyse_expressions(self, env):
3612         self.analyse_types(env)
3613
3614 #       def analyse_expressions(self, env):
3615 #           self.analyse_expressions_1(env)
3616 #           self.analyse_expressions_2(env)
3617
3618     def generate_execution_code(self, code):
3619         self.generate_rhs_evaluation_code(code)
3620         self.generate_assignment_code(code)
3621
3622
3623 class SingleAssignmentNode(AssignmentNode):
3624     #  The simplest case:
3625     #
3626     #    a = b
3627     #
3628     #  lhs      ExprNode      Left hand side
3629     #  rhs      ExprNode      Right hand side
3630     #  first    bool          Is this guaranteed the first assignment to lhs?
3631
3632     child_attrs = ["lhs", "rhs"]
3633     first = False
3634     declaration_only = False
3635
3636     def analyse_declarations(self, env):
3637         import ExprNodes
3638
3639         # handle declarations of the form x = cython.foo()
3640         if isinstance(self.rhs, ExprNodes.CallNode):
3641             func_name = self.rhs.function.as_cython_attribute()
3642             if func_name:
3643                 args, kwds = self.rhs.explicit_args_kwds()
3644
3645                 if func_name in ['declare', 'typedef']:
3646                     if len(args) > 2 or kwds is not None:
3647                         error(self.rhs.pos, "Can only declare one type at a time.")
3648                         return
3649                     type = args[0].analyse_as_type(env)
3650                     if type is None:
3651                         error(args[0].pos, "Unknown type")
3652                         return
3653                     lhs = self.lhs
3654                     if func_name == 'declare':
3655                         if isinstance(lhs, ExprNodes.NameNode):
3656                             vars = [(lhs.name, lhs.pos)]
3657                         elif isinstance(lhs, ExprNodes.TupleNode):
3658                             vars = [(var.name, var.pos) for var in lhs.args]
3659                         else:
3660                             error(lhs.pos, "Invalid declaration")
3661                             return
3662                         for var, pos in vars:
3663                             env.declare_var(var, type, pos, is_cdef = True)
3664                         if len(args) == 2:
3665                             # we have a value
3666                             self.rhs = args[1]
3667                         else:
3668                             self.declaration_only = True
3669                     else:
3670                         self.declaration_only = True
3671                         if not isinstance(lhs, ExprNodes.NameNode):
3672                             error(lhs.pos, "Invalid declaration.")
3673                         env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3674
3675                 elif func_name in ['struct', 'union']:
3676                     self.declaration_only = True
3677                     if len(args) > 0 or kwds is None:
3678                         error(self.rhs.pos, "Struct or union members must be given by name.")
3679                         return
3680                     members = []
3681                     for member, type_node in kwds.key_value_pairs:
3682                         type = type_node.analyse_as_type(env)
3683                         if type is None:
3684                             error(type_node.pos, "Unknown type")
3685                         else:
3686                             members.append((member.value, type, member.pos))
3687                     if len(members) < len(kwds.key_value_pairs):
3688                         return
3689                     if not isinstance(self.lhs, ExprNodes.NameNode):
3690                         error(self.lhs.pos, "Invalid declaration.")
3691                     name = self.lhs.name
3692                     scope = StructOrUnionScope(name)
3693                     env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3694                     for member, type, pos in members:
3695                         scope.declare_var(member, type, pos)
3696
3697         if self.declaration_only:
3698             return
3699         else:
3700             self.lhs.analyse_target_declaration(env)
3701
3702     def analyse_types(self, env, use_temp = 0):
3703         self.rhs.analyse_types(env)
3704         self.lhs.analyse_target_types(env)
3705         self.lhs.gil_assignment_check(env)
3706         self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3707         if use_temp:
3708             self.rhs = self.rhs.coerce_to_temp(env)
3709
3710     def generate_rhs_evaluation_code(self, code):
3711         self.rhs.generate_evaluation_code(code)
3712
3713     def generate_assignment_code(self, code):
3714         self.lhs.generate_assignment_code(self.rhs, code)
3715
3716     def generate_function_definitions(self, env, code):
3717         self.rhs.generate_function_definitions(env, code)
3718
3719     def annotate(self, code):
3720         self.lhs.annotate(code)
3721         self.rhs.annotate(code)
3722
3723
3724 class CascadedAssignmentNode(AssignmentNode):
3725     #  An assignment with multiple left hand sides:
3726     #
3727     #    a = b = c
3728     #
3729     #  lhs_list   [ExprNode]   Left hand sides
3730     #  rhs        ExprNode     Right hand sides
3731     #
3732     #  Used internally:
3733     #
3734     #  coerced_rhs_list   [ExprNode]   RHS coerced to type of each LHS
3735
3736     child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3737     coerced_rhs_list = None
3738
3739     def analyse_declarations(self, env):
3740         for lhs in self.lhs_list:
3741             lhs.analyse_target_declaration(env)
3742
3743     def analyse_types(self, env, use_temp = 0):
3744         self.rhs.analyse_types(env)
3745         if not self.rhs.is_simple():
3746             if use_temp:
3747                 self.rhs = self.rhs.coerce_to_temp(env)
3748             else:
3749                 self.rhs = self.rhs.coerce_to_simple(env)
3750         from ExprNodes import CloneNode
3751         self.coerced_rhs_list = []
3752         for lhs in self.lhs_list:
3753             lhs.analyse_target_types(env)
3754             lhs.gil_assignment_check(env)
3755             rhs = CloneNode(self.rhs)
3756             rhs = rhs.coerce_to(lhs.type, env)
3757             self.coerced_rhs_list.append(rhs)
3758
3759     def generate_rhs_evaluation_code(self, code):
3760         self.rhs.generate_evaluation_code(code)
3761
3762     def generate_assignment_code(self, code):
3763         for i in range(len(self.lhs_list)):
3764             lhs = self.lhs_list[i]
3765             rhs = self.coerced_rhs_list[i]
3766             rhs.generate_evaluation_code(code)
3767             lhs.generate_assignment_code(rhs, code)
3768             # Assignment has disposed of the cloned RHS
3769         self.rhs.generate_disposal_code(code)
3770         self.rhs.free_temps(code)
3771
3772     def generate_function_definitions(self, env, code):
3773         self.rhs.generate_function_definitions(env, code)
3774
3775     def annotate(self, code):
3776         for i in range(len(self.lhs_list)):
3777             lhs = self.lhs_list[i].annotate(code)
3778             rhs = self.coerced_rhs_list[i].annotate(code)
3779         self.rhs.annotate(code)
3780
3781
3782 class ParallelAssignmentNode(AssignmentNode):
3783     #  A combined packing/unpacking assignment:
3784     #
3785     #    a, b, c =  d, e, f
3786     #
3787     #  This has been rearranged by the parser into
3788     #
3789     #    a = d ; b = e ; c = f
3790     #
3791     #  but we must evaluate all the right hand sides
3792     #  before assigning to any of the left hand sides.
3793     #
3794     #  stats     [AssignmentNode]   The constituent assignments
3795
3796     child_attrs = ["stats"]
3797
3798     def analyse_declarations(self, env):
3799         for stat in self.stats:
3800             stat.analyse_declarations(env)
3801
3802     def analyse_expressions(self, env):
3803         for stat in self.stats:
3804             stat.analyse_types(env, use_temp = 1)
3805
3806 #    def analyse_expressions(self, env):
3807 #        for stat in self.stats:
3808 #            stat.analyse_expressions_1(env, use_temp = 1)
3809 #        for stat in self.stats:
3810 #            stat.analyse_expressions_2(env)
3811
3812     def generate_execution_code(self, code):
3813         for stat in self.stats:
3814             stat.generate_rhs_evaluation_code(code)
3815         for stat in self.stats:
3816             stat.generate_assignment_code(code)
3817
3818     def generate_function_definitions(self, env, code):
3819         for stat in self.stats:
3820             stat.generate_function_definitions(env, code)
3821
3822     def annotate(self, code):
3823         for stat in self.stats:
3824             stat.annotate(code)
3825
3826
3827 class InPlaceAssignmentNode(AssignmentNode):
3828     #  An in place arithmetic operand:
3829     #
3830     #    a += b
3831     #    a -= b
3832     #    ...
3833     #
3834     #  lhs      ExprNode      Left hand side
3835     #  rhs      ExprNode      Right hand side
3836     #  op       char          one of "+-*/%^&|"
3837     #  dup     (ExprNode)     copy of lhs used for operation (auto-generated)
3838     #
3839     #  This code is a bit tricky because in order to obey Python
3840     #  semantics the sub-expressions (e.g. indices) of the lhs must
3841     #  not be evaluated twice. So we must re-use the values calculated
3842     #  in evaluation phase for the assignment phase as well.
3843     #  Fortunately, the type of the lhs node is fairly constrained
3844     #  (it must be a NameNode, AttributeNode, or IndexNode).
3845
3846     child_attrs = ["lhs", "rhs"]
3847
3848     def analyse_declarations(self, env):
3849         self.lhs.analyse_target_declaration(env)
3850
3851     def analyse_types(self, env):
3852         self.rhs.analyse_types(env)
3853         self.lhs.analyse_target_types(env)
3854
3855     def generate_execution_code(self, code):
3856         import ExprNodes
3857         self.rhs.generate_evaluation_code(code)
3858         self.lhs.generate_subexpr_evaluation_code(code)
3859         c_op = self.operator
3860         if c_op == "//":
3861             c_op = "/"
3862         elif c_op == "**":
3863             error(self.pos, "No C inplace power operator")
3864         if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3865             if self.lhs.type.is_pyobject:
3866                 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3867             if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3868                 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3869             self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3870         else:
3871             # C++
3872             # TODO: make sure overload is declared
3873             code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3874         self.lhs.generate_subexpr_disposal_code(code)
3875         self.lhs.free_subexpr_temps(code)
3876         self.rhs.generate_disposal_code(code)
3877         self.rhs.free_temps(code)
3878
3879     def annotate(self, code):
3880         self.lhs.annotate(code)
3881         self.rhs.annotate(code)
3882
3883     def create_binop_node(self):
3884         import ExprNodes
3885         return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3886
3887
3888 class PrintStatNode(StatNode):
3889     #  print statement
3890     #
3891     #  arg_tuple         TupleNode
3892     #  stream            ExprNode or None (stdout)
3893     #  append_newline    boolean
3894
3895     child_attrs = ["arg_tuple", "stream"]
3896
3897     def analyse_expressions(self, env):
3898         if self.stream:
3899             self.stream.analyse_expressions(env)
3900             self.stream = self.stream.coerce_to_pyobject(env)
3901         self.arg_tuple.analyse_expressions(env)
3902         self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3903         env.use_utility_code(printing_utility_code)
3904         if len(self.arg_tuple.args) == 1 and self.append_newline:
3905             env.use_utility_code(printing_one_utility_code)
3906
3907     nogil_check = Node.gil_error
3908     gil_message = "Python print statement"
3909
3910     def generate_execution_code(self, code):
3911         if self.stream:
3912             self.stream.generate_evaluation_code(code)
3913             stream_result = self.stream.py_result()
3914         else:
3915             stream_result = '0'
3916         if len(self.arg_tuple.args) == 1 and self.append_newline:
3917             arg = self.arg_tuple.args[0]
3918             arg.generate_evaluation_code(code)
3919
3920             code.putln(
3921                 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3922                     stream_result,
3923                     arg.py_result(),
3924                     code.error_goto(self.pos)))
3925             arg.generate_disposal_code(code)
3926             arg.free_temps(code)
3927         else:
3928             self.arg_tuple.generate_evaluation_code(code)
3929             code.putln(
3930                 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3931                     stream_result,
3932                     self.arg_tuple.py_result(),
3933                     self.append_newline,
3934                     code.error_goto(self.pos)))
3935             self.arg_tuple.generate_disposal_code(code)
3936             self.arg_tuple.free_temps(code)
3937
3938         if self.stream:
3939             self.stream.generate_disposal_code(code)
3940             self.stream.free_temps(code)
3941
3942     def generate_function_definitions(self, env, code):
3943         if self.stream:
3944             self.stream.generate_function_definitions(env, code)
3945         self.arg_tuple.generate_function_definitions(env, code)
3946
3947     def annotate(self, code):
3948         if self.stream:
3949             self.stream.annotate(code)
3950         self.arg_tuple.annotate(code)
3951
3952
3953 class ExecStatNode(StatNode):
3954     #  exec statement
3955     #
3956     #  args     [ExprNode]
3957
3958     child_attrs = ["args"]
3959
3960     def analyse_expressions(self, env):
3961         for i, arg in enumerate(self.args):
3962             arg.analyse_expressions(env)
3963             arg = arg.coerce_to_pyobject(env)
3964             self.args[i] = arg
3965         env.use_utility_code(Builtin.pyexec_utility_code)
3966
3967     nogil_check = Node.gil_error
3968     gil_message = "Python exec statement"
3969
3970     def generate_execution_code(self, code):
3971         args = []
3972         for arg in self.args:
3973             arg.generate_evaluation_code(code)
3974             args.append( arg.py_result() )
3975         args = tuple(args + ['0', '0'][:3-len(args)])
3976         temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3977         code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3978                 (temp_result,) + args))
3979         for arg in self.args:
3980             arg.generate_disposal_code(code)
3981             arg.free_temps(code)
3982         code.putln(
3983             code.error_goto_if_null(temp_result, self.pos))
3984         code.put_gotref(temp_result)
3985         code.put_decref_clear(temp_result, py_object_type)
3986         code.funcstate.release_temp(temp_result)
3987
3988     def annotate(self, code):
3989         for arg in self.args:
3990             arg.annotate(code)
3991
3992
3993 class DelStatNode(StatNode):
3994     #  del statement
3995     #
3996     #  args     [ExprNode]
3997
3998     child_attrs = ["args"]
3999
4000     def analyse_declarations(self, env):
4001         for arg in self.args:
4002             arg.analyse_target_declaration(env)
4003
4004     def analyse_expressions(self, env):
4005         for arg in self.args:
4006             arg.analyse_target_expression(env, None)
4007             if arg.type.is_pyobject:
4008                 pass
4009             elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
4010                 self.cpp_check(env)
4011             elif arg.type.is_cpp_class:
4012                 error(arg.pos, "Deletion of non-heap C++ object")
4013             else:
4014                 error(arg.pos, "Deletion of non-Python, non-C++ object")
4015             #arg.release_target_temp(env)
4016
4017     def nogil_check(self, env):
4018         for arg in self.args:
4019             if arg.type.is_pyobject:
4020                 self.gil_error()
4021
4022     gil_message = "Deleting Python object"
4023
4024     def generate_execution_code(self, code):
4025         for arg in self.args:
4026             if arg.type.is_pyobject:
4027                 arg.generate_deletion_code(code)
4028             elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
4029                 arg.generate_result_code(code)
4030                 code.putln("delete %s;" % arg.result())
4031             # else error reported earlier
4032
4033     def annotate(self, code):
4034         for arg in self.args:
4035             arg.annotate(code)
4036
4037
4038 class PassStatNode(StatNode):
4039     #  pass statement
4040
4041     child_attrs = []
4042
4043     def analyse_expressions(self, env):
4044         pass
4045
4046     def generate_execution_code(self, code):
4047         pass
4048
4049
4050 class BreakStatNode(StatNode):
4051
4052     child_attrs = []
4053
4054     def analyse_expressions(self, env):
4055         pass
4056
4057     def generate_execution_code(self, code):
4058         if not code.break_label:
4059             error(self.pos, "break statement not inside loop")
4060         else:
4061             code.put_goto(code.break_label)
4062
4063
4064 class ContinueStatNode(StatNode):
4065
4066     child_attrs = []
4067
4068     def analyse_expressions(self, env):
4069         pass
4070
4071     def generate_execution_code(self, code):
4072         if code.funcstate.in_try_finally:
4073             error(self.pos, "continue statement inside try of try...finally")
4074         elif not code.continue_label:
4075             error(self.pos, "continue statement not inside loop")
4076         else:
4077             code.put_goto(code.continue_label)
4078
4079
4080 class ReturnStatNode(StatNode):
4081     #  return statement
4082     #
4083     #  value         ExprNode or None
4084     #  return_type   PyrexType
4085
4086     child_attrs = ["value"]
4087
4088     def analyse_expressions(self, env):
4089         return_type = env.return_type
4090         self.return_type = return_type
4091         if not return_type:
4092             error(self.pos, "Return not inside a function body")
4093             return
4094         if self.value:
4095             self.value.analyse_types(env)
4096             if return_type.is_void or return_type.is_returncode:
4097                 error(self.value.pos,
4098                     "Return with value in void function")
4099             else:
4100                 self.value = self.value.coerce_to(env.return_type, env)
4101         else:
4102             if (not return_type.is_void
4103                 and not return_type.is_pyobject
4104                 and not return_type.is_returncode):
4105                     error(self.pos, "Return value required")
4106
4107     def nogil_check(self, env):
4108         if self.return_type.is_pyobject:
4109             self.gil_error()
4110
4111     gil_message = "Returning Python object"
4112
4113     def generate_execution_code(self, code):
4114         code.mark_pos(self.pos)
4115         if not self.return_type:
4116             # error reported earlier
4117             return
4118         if self.return_type.is_pyobject:
4119             code.put_xdecref(Naming.retval_cname,
4120                              self.return_type)
4121         if self.value:
4122             self.value.generate_evaluation_code(code)
4123             self.value.make_owned_reference(code)
4124             code.putln(
4125                 "%s = %s;" % (
4126                     Naming.retval_cname,
4127                     self.value.result_as(self.return_type)))
4128             self.value.generate_post_assignment_code(code)
4129             self.value.free_temps(code)
4130         else:
4131             if self.return_type.is_pyobject:
4132                 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
4133             elif self.return_type.is_returncode:
4134                 code.putln(
4135                     "%s = %s;" % (
4136                         Naming.retval_cname,
4137                         self.return_type.default_value))
4138         for cname, type in code.funcstate.temps_holding_reference():
4139             code.put_decref_clear(cname, type)
4140         code.put_goto(code.return_label)
4141
4142     def generate_function_definitions(self, env, code):
4143         if self.value is not None:
4144             self.value.generate_function_definitions(env, code)
4145
4146     def annotate(self, code):
4147         if self.value:
4148             self.value.annotate(code)
4149
4150
4151 class RaiseStatNode(StatNode):
4152     #  raise statement
4153     #
4154     #  exc_type    ExprNode or None
4155     #  exc_value   ExprNode or None
4156     #  exc_tb      ExprNode or None
4157     #  cause       ExprNode or None
4158
4159     child_attrs = ["exc_type", "exc_value", "exc_tb", "cause"]
4160
4161     def analyse_expressions(self, env):
4162         if self.exc_type:
4163             self.exc_type.analyse_types(env)
4164             self.exc_type = self.exc_type.coerce_to_pyobject(env)
4165         if self.exc_value:
4166             self.exc_value.analyse_types(env)
4167             self.exc_value = self.exc_value.coerce_to_pyobject(env)
4168         if self.exc_tb:
4169             self.exc_tb.analyse_types(env)
4170             self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4171         if self.cause:
4172             self.cause.analyse_types(env)
4173             self.cause = self.cause.coerce_to_pyobject(env)
4174         # special cases for builtin exceptions
4175         self.builtin_exc_name = None
4176         if self.exc_type and not self.exc_value and not self.exc_tb:
4177             exc = self.exc_type
4178             import ExprNodes
4179             if (isinstance(exc, ExprNodes.SimpleCallNode) and
4180                 not (exc.args or (exc.arg_tuple is not None and
4181                                   exc.arg_tuple.args))):
4182                 exc = exc.function # extract the exception type
4183             if exc.is_name and exc.entry.is_builtin:
4184                 self.builtin_exc_name = exc.name
4185                 if self.builtin_exc_name == 'MemoryError':
4186                     self.exc_type = None # has a separate implementation
4187
4188     nogil_check = Node.gil_error
4189     gil_message = "Raising exception"
4190
4191     def generate_execution_code(self, code):
4192         if self.builtin_exc_name == 'MemoryError':
4193             code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos))
4194             return
4195
4196         if self.exc_type:
4197             self.exc_type.generate_evaluation_code(code)
4198             type_code = self.exc_type.py_result()
4199         else:
4200             type_code = "0"
4201         if self.exc_value:
4202             self.exc_value.generate_evaluation_code(code)
4203             value_code = self.exc_value.py_result()
4204         else:
4205             value_code = "0"
4206         if self.exc_tb:
4207             self.exc_tb.generate_evaluation_code(code)
4208             tb_code = self.exc_tb.py_result()
4209         else:
4210             tb_code = "0"
4211         if self.cause:
4212             self.cause.generate_evaluation_code(code)
4213             cause_code = self.cause.py_result()
4214         else:
4215             cause_code = "0"
4216         code.globalstate.use_utility_code(raise_utility_code)
4217         code.putln(
4218             "__Pyx_Raise(%s, %s, %s, %s);" % (
4219                 type_code,
4220                 value_code,
4221                 tb_code,
4222                 cause_code))
4223         for obj in (self.exc_type, self.exc_value, self.exc_tb, self.cause):
4224             if obj:
4225                 obj.generate_disposal_code(code)
4226                 obj.free_temps(code)
4227         code.putln(
4228             code.error_goto(self.pos))
4229
4230     def generate_function_definitions(self, env, code):
4231         if self.exc_type is not None:
4232             self.exc_type.generate_function_definitions(env, code)
4233         if self.exc_value is not None:
4234             self.exc_value.generate_function_definitions(env, code)
4235         if self.exc_tb is not None:
4236             self.exc_tb.generate_function_definitions(env, code)
4237         if self.cause is not None:
4238             self.cause.generate_function_definitions(env, code)
4239
4240     def annotate(self, code):
4241         if self.exc_type:
4242             self.exc_type.annotate(code)
4243         if self.exc_value:
4244             self.exc_value.annotate(code)
4245         if self.exc_tb:
4246             self.exc_tb.annotate(code)
4247         if self.cause:
4248             self.cause.annotate(code)
4249
4250
4251 class ReraiseStatNode(StatNode):
4252
4253     child_attrs = []
4254
4255     def analyse_expressions(self, env):
4256         env.use_utility_code(restore_exception_utility_code)
4257
4258     nogil_check = Node.gil_error
4259     gil_message = "Raising exception"
4260
4261     def generate_execution_code(self, code):
4262         vars = code.funcstate.exc_vars
4263         if vars:
4264             for varname in vars:
4265                 code.put_giveref(varname)
4266             code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4267             for varname in vars:
4268                 code.put("%s = 0; " % varname)
4269             code.putln()
4270             code.putln(code.error_goto(self.pos))
4271         else:
4272             error(self.pos, "Reraise not inside except clause")
4273
4274
4275 class AssertStatNode(StatNode):
4276     #  assert statement
4277     #
4278     #  cond    ExprNode
4279     #  value   ExprNode or None
4280
4281     child_attrs = ["cond", "value"]
4282
4283     def analyse_expressions(self, env):
4284         self.cond = self.cond.analyse_boolean_expression(env)
4285         if self.value:
4286             self.value.analyse_types(env)
4287             self.value = self.value.coerce_to_pyobject(env)
4288
4289     nogil_check = Node.gil_error
4290     gil_message = "Raising exception"
4291
4292     def generate_execution_code(self, code):
4293         code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4294         self.cond.generate_evaluation_code(code)
4295         code.putln(
4296             "if (unlikely(!%s)) {" %
4297                 self.cond.result())
4298         if self.value:
4299             self.value.generate_evaluation_code(code)
4300             code.putln(
4301                 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4302                     self.value.py_result())
4303             self.value.generate_disposal_code(code)
4304             self.value.free_temps(code)
4305         else:
4306             code.putln(
4307                 "PyErr_SetNone(PyExc_AssertionError);")
4308         code.putln(
4309                 code.error_goto(self.pos))
4310         code.putln(
4311             "}")
4312         self.cond.generate_disposal_code(code)
4313         self.cond.free_temps(code)
4314         code.putln("#endif")
4315
4316     def generate_function_definitions(self, env, code):
4317         self.cond.generate_function_definitions(env, code)
4318         if self.value is not None:
4319             self.value.generate_function_definitions(env, code)
4320
4321     def annotate(self, code):
4322         self.cond.annotate(code)
4323         if self.value:
4324             self.value.annotate(code)
4325
4326
4327 class IfStatNode(StatNode):
4328     #  if statement
4329     #
4330     #  if_clauses   [IfClauseNode]
4331     #  else_clause  StatNode or None
4332
4333     child_attrs = ["if_clauses", "else_clause"]
4334
4335     def analyse_control_flow(self, env):
4336         env.start_branching(self.pos)
4337         for if_clause in self.if_clauses:
4338             if_clause.analyse_control_flow(env)
4339             env.next_branch(if_clause.end_pos())
4340         if self.else_clause:
4341             self.else_clause.analyse_control_flow(env)
4342         env.finish_branching(self.end_pos())
4343
4344     def analyse_declarations(self, env):
4345         for if_clause in self.if_clauses:
4346             if_clause.analyse_declarations(env)
4347         if self.else_clause:
4348             self.else_clause.analyse_declarations(env)
4349
4350     def analyse_expressions(self, env):
4351         for if_clause in self.if_clauses:
4352             if_clause.analyse_expressions(env)
4353         if self.else_clause:
4354             self.else_clause.analyse_expressions(env)
4355
4356     def generate_execution_code(self, code):
4357         code.mark_pos(self.pos)
4358         end_label = code.new_label()
4359         for if_clause in self.if_clauses:
4360             if_clause.generate_execution_code(code, end_label)
4361         if self.else_clause:
4362             code.putln("/*else*/ {")
4363             self.else_clause.generate_execution_code(code)
4364             code.putln("}")
4365         code.put_label(end_label)
4366
4367     def generate_function_definitions(self, env, code):
4368         for clause in self.if_clauses:
4369             clause.generate_function_definitions(env, code)
4370         if self.else_clause is not None:
4371             self.else_clause.generate_function_definitions(env, code)
4372
4373     def annotate(self, code):
4374         for if_clause in self.if_clauses:
4375             if_clause.annotate(code)
4376         if self.else_clause:
4377             self.else_clause.annotate(code)
4378
4379
4380 class IfClauseNode(Node):
4381     #  if or elif clause in an if statement
4382     #
4383     #  condition   ExprNode
4384     #  body        StatNode
4385
4386     child_attrs = ["condition", "body"]
4387
4388     def analyse_control_flow(self, env):
4389         self.body.analyse_control_flow(env)
4390
4391     def analyse_declarations(self, env):
4392         self.body.analyse_declarations(env)
4393
4394     def analyse_expressions(self, env):
4395         self.condition = \
4396             self.condition.analyse_temp_boolean_expression(env)
4397         self.body.analyse_expressions(env)
4398
4399     def get_constant_condition_result(self):
4400         if self.condition.has_constant_result():
4401             return bool(self.condition.constant_result)
4402         else:
4403             return None
4404
4405     def generate_execution_code(self, code, end_label):
4406         self.condition.generate_evaluation_code(code)
4407         code.putln(
4408             "if (%s) {" %
4409                 self.condition.result())
4410         self.condition.generate_disposal_code(code)
4411         self.condition.free_temps(code)
4412         self.body.generate_execution_code(code)
4413         code.put_goto(end_label)
4414         code.putln("}")
4415
4416     def generate_function_definitions(self, env, code):
4417         self.condition.generate_function_definitions(env, code)
4418         self.body.generate_function_definitions(env, code)
4419
4420     def annotate(self, code):
4421         self.condition.annotate(code)
4422         self.body.annotate(code)
4423
4424
4425 class SwitchCaseNode(StatNode):
4426     # Generated in the optimization of an if-elif-else node
4427     #
4428     # conditions    [ExprNode]
4429     # body          StatNode
4430
4431     child_attrs = ['conditions', 'body']
4432
4433     def generate_execution_code(self, code):
4434         for cond in self.conditions:
4435             code.mark_pos(cond.pos)
4436             cond.generate_evaluation_code(code)
4437             code.putln("case %s:" % cond.result())
4438         self.body.generate_execution_code(code)
4439         code.putln("break;")
4440
4441     def generate_function_definitions(self, env, code):
4442         for cond in self.conditions:
4443             cond.generate_function_definitions(env, code)
4444         self.body.generate_function_definitions(env, code)
4445
4446     def annotate(self, code):
4447         for cond in self.conditions:
4448             cond.annotate(code)
4449         self.body.annotate(code)
4450
4451 class SwitchStatNode(StatNode):
4452     # Generated in the optimization of an if-elif-else node
4453     #
4454     # test          ExprNode
4455     # cases         [SwitchCaseNode]
4456     # else_clause   StatNode or None
4457
4458     child_attrs = ['test', 'cases', 'else_clause']
4459
4460     def generate_execution_code(self, code):
4461         self.test.generate_evaluation_code(code)
4462         code.putln("switch (%s) {" % self.test.result())
4463         for case in self.cases:
4464             case.generate_execution_code(code)
4465         if self.else_clause is not None:
4466             code.putln("default:")
4467             self.else_clause.generate_execution_code(code)
4468             code.putln("break;")
4469         code.putln("}")
4470
4471     def generate_function_definitions(self, env, code):
4472         self.test.generate_function_definitions(env, code)
4473         for case in self.cases:
4474             case.generate_function_definitions(env, code)
4475         if self.else_clause is not None:
4476             self.else_clause.generate_function_definitions(env, code)
4477
4478     def annotate(self, code):
4479         self.test.annotate(code)
4480         for case in self.cases:
4481             case.annotate(code)
4482         if self.else_clause is not None:
4483             self.else_clause.annotate(code)
4484
4485 class LoopNode(object):
4486
4487     def analyse_control_flow(self, env):
4488         env.start_branching(self.pos)
4489         self.body.analyse_control_flow(env)
4490         env.next_branch(self.body.end_pos())
4491         if self.else_clause:
4492             self.else_clause.analyse_control_flow(env)
4493         env.finish_branching(self.end_pos())
4494
4495
4496 class WhileStatNode(LoopNode, StatNode):
4497     #  while statement
4498     #
4499     #  condition    ExprNode
4500     #  body         StatNode
4501     #  else_clause  StatNode
4502
4503     child_attrs = ["condition", "body", "else_clause"]
4504
4505     def analyse_declarations(self, env):
4506         self.body.analyse_declarations(env)
4507         if self.else_clause:
4508             self.else_clause.analyse_declarations(env)
4509
4510     def analyse_expressions(self, env):
4511         self.condition = \
4512             self.condition.analyse_temp_boolean_expression(env)
4513         self.body.analyse_expressions(env)
4514         if self.else_clause:
4515             self.else_clause.analyse_expressions(env)
4516
4517     def generate_execution_code(self, code):
4518         old_loop_labels = code.new_loop_labels()
4519         code.putln(
4520             "while (1) {")
4521         self.condition.generate_evaluation_code(code)
4522         self.condition.generate_disposal_code(code)
4523         code.putln(
4524             "if (!%s) break;" %
4525                 self.condition.result())
4526         self.condition.free_temps(code)
4527         self.body.generate_execution_code(code)
4528         code.put_label(code.continue_label)
4529         code.putln("}")
4530         break_label = code.break_label
4531         code.set_loop_labels(old_loop_labels)
4532         if self.else_clause:
4533             code.putln("/*else*/ {")
4534             self.else_clause.generate_execution_code(code)
4535             code.putln("}")
4536         code.put_label(break_label)
4537
4538     def generate_function_definitions(self, env, code):
4539         self.condition.generate_function_definitions(env, code)
4540         self.body.generate_function_definitions(env, code)
4541         if self.else_clause is not None:
4542             self.else_clause.generate_function_definitions(env, code)
4543
4544     def annotate(self, code):
4545         self.condition.annotate(code)
4546         self.body.annotate(code)
4547         if self.else_clause:
4548             self.else_clause.annotate(code)
4549
4550
4551 def ForStatNode(pos, **kw):
4552     if 'iterator' in kw:
4553         return ForInStatNode(pos, **kw)
4554     else:
4555         return ForFromStatNode(pos, **kw)
4556
4557 class ForInStatNode(LoopNode, StatNode):
4558     #  for statement
4559     #
4560     #  target        ExprNode
4561     #  iterator      IteratorNode
4562     #  body          StatNode
4563     #  else_clause   StatNode
4564     #  item          NextNode       used internally
4565
4566     child_attrs = ["target", "iterator", "body", "else_clause"]
4567     item = None
4568
4569     def analyse_declarations(self, env):
4570         self.target.analyse_target_declaration(env)
4571         self.body.analyse_declarations(env)
4572         if self.else_clause:
4573             self.else_clause.analyse_declarations(env)
4574
4575     def analyse_expressions(self, env):
4576         import ExprNodes
4577         self.target.analyse_target_types(env)
4578         self.iterator.analyse_expressions(env)
4579         self.item = ExprNodes.NextNode(self.iterator, env)
4580         if (self.iterator.type.is_ptr or self.iterator.type.is_array) and \
4581             self.target.type.assignable_from(self.iterator.type):
4582             # C array slice optimization.
4583             pass
4584         else:
4585             self.item = self.item.coerce_to(self.target.type, env)
4586         self.body.analyse_expressions(env)
4587         if self.else_clause:
4588             self.else_clause.analyse_expressions(env)
4589
4590     def generate_execution_code(self, code):
4591         old_loop_labels = code.new_loop_labels()
4592         self.iterator.allocate_counter_temp(code)
4593         self.iterator.generate_evaluation_code(code)
4594         code.putln(
4595             "for (;;) {")
4596         self.item.generate_evaluation_code(code)
4597         self.target.generate_assignment_code(self.item, code)
4598         self.body.generate_execution_code(code)
4599         code.put_label(code.continue_label)
4600         code.putln(
4601             "}")
4602         break_label = code.break_label
4603         code.set_loop_labels(old_loop_labels)
4604
4605         if self.else_clause:
4606             # in nested loops, the 'else' block can contain a
4607             # 'continue' statement for the outer loop, but we may need
4608             # to generate cleanup code before taking that path, so we
4609             # intercept it here
4610             orig_continue_label = code.continue_label
4611             code.continue_label = code.new_label('outer_continue')
4612
4613             code.putln("/*else*/ {")
4614             self.else_clause.generate_execution_code(code)
4615             code.putln("}")
4616
4617             if code.label_used(code.continue_label):
4618                 code.put_goto(break_label)
4619                 code.put_label(code.continue_label)
4620                 self.iterator.generate_disposal_code(code)
4621                 code.put_goto(orig_continue_label)
4622             code.set_loop_labels(old_loop_labels)
4623
4624         if code.label_used(break_label):
4625             code.put_label(break_label)
4626         self.iterator.release_counter_temp(code)
4627         self.iterator.generate_disposal_code(code)
4628         self.iterator.free_temps(code)
4629
4630     def generate_function_definitions(self, env, code):
4631         self.target.generate_function_definitions(env, code)
4632         self.iterator.generate_function_definitions(env, code)
4633         self.body.generate_function_definitions(env, code)
4634         if self.else_clause is not None:
4635             self.else_clause.generate_function_definitions(env, code)
4636
4637     def annotate(self, code):
4638         self.target.annotate(code)
4639         self.iterator.annotate(code)
4640         self.body.annotate(code)
4641         if self.else_clause:
4642             self.else_clause.annotate(code)
4643         self.item.annotate(code)
4644
4645
4646 class ForFromStatNode(LoopNode, StatNode):
4647     #  for name from expr rel name rel expr
4648     #
4649     #  target        NameNode
4650     #  bound1        ExprNode
4651     #  relation1     string
4652     #  relation2     string
4653     #  bound2        ExprNode
4654     #  step          ExprNode or None
4655     #  body          StatNode
4656     #  else_clause   StatNode or None
4657     #
4658     #  Used internally:
4659     #
4660     #  from_range         bool
4661     #  is_py_target       bool
4662     #  loopvar_node       ExprNode (usually a NameNode or temp node)
4663     #  py_loopvar_node    PyTempNode or None
4664     child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4665
4666     is_py_target = False
4667     loopvar_node = None
4668     py_loopvar_node = None
4669     from_range = False
4670
4671     gil_message = "For-loop using object bounds or target"
4672
4673     def nogil_check(self, env):
4674         for x in (self.target, self.bound1, self.bound2):
4675             if x.type.is_pyobject:
4676                 self.gil_error()
4677
4678     def analyse_declarations(self, env):
4679         self.target.analyse_target_declaration(env)
4680         self.body.analyse_declarations(env)
4681         if self.else_clause:
4682             self.else_clause.analyse_declarations(env)
4683
4684     def analyse_expressions(self, env):
4685         import ExprNodes
4686         self.target.analyse_target_types(env)
4687         self.bound1.analyse_types(env)
4688         self.bound2.analyse_types(env)
4689         if self.step is not None:
4690             if isinstance(self.step, ExprNodes.UnaryMinusNode):
4691                 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4692             self.step.analyse_types(env)
4693
4694         target_type = self.target.type
4695         if self.target.type.is_numeric:
4696             loop_type = self.target.type
4697         else:
4698             loop_type = PyrexTypes.c_int_type
4699             if not self.bound1.type.is_pyobject:
4700                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4701             if not self.bound2.type.is_pyobject:
4702                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4703             if self.step is not None and not self.step.type.is_pyobject:
4704                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4705         self.bound1 = self.bound1.coerce_to(loop_type, env)
4706         self.bound2 = self.bound2.coerce_to(loop_type, env)
4707         if not self.bound2.is_literal:
4708             self.bound2 = self.bound2.coerce_to_temp(env)
4709         if self.step is not None:
4710             self.step = self.step.coerce_to(loop_type, env)
4711             if not self.step.is_literal:
4712                 self.step = self.step.coerce_to_temp(env)
4713
4714         target_type = self.target.type
4715         if not (target_type.is_pyobject or target_type.is_numeric):
4716             error(self.target.pos,
4717                 "for-from loop variable must be c numeric type or Python object")
4718         if target_type.is_numeric:
4719             self.is_py_target = False
4720             if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4721                 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4722             self.loopvar_node = self.target
4723             self.py_loopvar_node = None
4724         else:
4725             self.is_py_target = True
4726             c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4727             self.loopvar_node = c_loopvar_node
4728             self.py_loopvar_node = \
4729                 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4730         self.body.analyse_expressions(env)
4731         if self.else_clause:
4732             self.else_clause.analyse_expressions(env)
4733
4734     def generate_execution_code(self, code):
4735         old_loop_labels = code.new_loop_labels()
4736         from_range = self.from_range
4737         self.bound1.generate_evaluation_code(code)
4738         self.bound2.generate_evaluation_code(code)
4739         offset, incop = self.relation_table[self.relation1]
4740         if self.step is not None:
4741             self.step.generate_evaluation_code(code)
4742             step = self.step.result()
4743             incop = "%s=%s" % (incop[0], step)
4744         import ExprNodes
4745         if isinstance(self.loopvar_node, ExprNodes.TempNode):
4746             self.loopvar_node.allocate(code)
4747         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4748             self.py_loopvar_node.allocate(code)
4749         if from_range:
4750             loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4751         else:
4752             loopvar_name = self.loopvar_node.result()
4753         code.putln(
4754             "for (%s = %s%s; %s %s %s; %s%s) {" % (
4755                 loopvar_name,
4756                 self.bound1.result(), offset,
4757                 loopvar_name, self.relation2, self.bound2.result(),
4758                 loopvar_name, incop))
4759         if self.py_loopvar_node:
4760             self.py_loopvar_node.generate_evaluation_code(code)
4761             self.target.generate_assignment_code(self.py_loopvar_node, code)
4762         elif from_range:
4763             code.putln("%s = %s;" % (
4764                             self.target.result(), loopvar_name))
4765         self.body.generate_execution_code(code)
4766         code.put_label(code.continue_label)
4767         if self.py_loopvar_node:
4768             # This mess is to make for..from loops with python targets behave
4769             # exactly like those with C targets with regards to re-assignment
4770             # of the loop variable.
4771             import ExprNodes
4772             if self.target.entry.is_pyglobal:
4773                 # We know target is a NameNode, this is the only ugly case.
4774                 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4775                 target_node.allocate(code)
4776                 interned_cname = code.intern_identifier(self.target.entry.name)
4777                 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4778                 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4779                                 target_node.result(),
4780                                 Naming.module_cname,
4781                                 interned_cname,
4782                                 code.error_goto_if_null(target_node.result(), self.target.pos)))
4783                 code.put_gotref(target_node.result())
4784             else:
4785                 target_node = self.target
4786             from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4787             from_py_node.temp_code = loopvar_name
4788             from_py_node.generate_result_code(code)
4789             if self.target.entry.is_pyglobal:
4790                 code.put_decref(target_node.result(), target_node.type)
4791                 target_node.release(code)
4792         code.putln("}")
4793         if self.py_loopvar_node:
4794             # This is potentially wasteful, but we don't want the semantics to
4795             # depend on whether or not the loop is a python type.
4796             self.py_loopvar_node.generate_evaluation_code(code)
4797             self.target.generate_assignment_code(self.py_loopvar_node, code)
4798         if from_range:
4799             code.funcstate.release_temp(loopvar_name)
4800         break_label = code.break_label
4801         code.set_loop_labels(old_loop_labels)
4802         if self.else_clause:
4803             code.putln("/*else*/ {")
4804             self.else_clause.generate_execution_code(code)
4805             code.putln("}")
4806         code.put_label(break_label)
4807         self.bound1.generate_disposal_code(code)
4808         self.bound1.free_temps(code)
4809         self.bound2.generate_disposal_code(code)
4810         self.bound2.free_temps(code)
4811         if isinstance(self.loopvar_node, ExprNodes.TempNode):
4812             self.loopvar_node.release(code)
4813         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4814             self.py_loopvar_node.release(code)
4815         if self.step is not None:
4816             self.step.generate_disposal_code(code)
4817             self.step.free_temps(code)
4818
4819     relation_table = {
4820         # {relop : (initial offset, increment op)}
4821         '<=': ("",   "++"),
4822         '<' : ("+1", "++"),
4823         '>=': ("",   "--"),
4824         '>' : ("-1", "--")
4825     }
4826
4827     def generate_function_definitions(self, env, code):
4828         self.target.generate_function_definitions(env, code)
4829         self.bound1.generate_function_definitions(env, code)
4830         self.bound2.generate_function_definitions(env, code)
4831         if self.step is not None:
4832             self.step.generate_function_definitions(env, code)
4833         self.body.generate_function_definitions(env, code)
4834         if self.else_clause is not None:
4835             self.else_clause.generate_function_definitions(env, code)
4836
4837     def annotate(self, code):
4838         self.target.annotate(code)
4839         self.bound1.annotate(code)
4840         self.bound2.annotate(code)
4841         if self.step:
4842             self.step.annotate(code)
4843         self.body.annotate(code)
4844         if self.else_clause:
4845             self.else_clause.annotate(code)
4846
4847
4848 class WithStatNode(StatNode):
4849     """
4850     Represents a Python with statement.
4851
4852     Implemented by the WithTransform as follows:
4853
4854         MGR = EXPR
4855         EXIT = MGR.__exit__
4856         VALUE = MGR.__enter__()
4857         EXC = True
4858         try:
4859             try:
4860                 TARGET = VALUE  # optional
4861                 BODY
4862             except:
4863                 EXC = False
4864                 if not EXIT(*EXCINFO):
4865                     raise
4866         finally:
4867             if EXC:
4868                 EXIT(None, None, None)
4869             MGR = EXIT = VALUE = None
4870     """
4871     #  manager          The with statement manager object
4872     #  target           ExprNode  the target lhs of the __enter__() call
4873     #  body             StatNode
4874
4875     child_attrs = ["manager", "target", "body"]
4876
4877     has_target = False
4878
4879     def analyse_declarations(self, env):
4880         self.manager.analyse_declarations(env)
4881         self.body.analyse_declarations(env)
4882
4883     def analyse_expressions(self, env):
4884         self.manager.analyse_types(env)
4885         self.body.analyse_expressions(env)
4886
4887     def generate_function_definitions(self, env, code):
4888         self.manager.generate_function_definitions(env, code)
4889         self.body.generate_function_definitions(env, code)
4890
4891     def generate_execution_code(self, code):
4892         code.putln("/*with:*/ {")
4893         self.manager.generate_evaluation_code(code)
4894         self.exit_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
4895         code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
4896             self.exit_var,
4897             self.manager.py_result(),
4898             code.get_py_string_const(EncodedString('__exit__'), identifier=True),
4899             code.error_goto_if_null(self.exit_var, self.pos),
4900             ))
4901         code.put_gotref(self.exit_var)
4902
4903         # need to free exit_var in the face of exceptions during setup
4904         old_error_label = code.new_error_label()
4905         intermediate_error_label = code.error_label
4906
4907         enter_func = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
4908         code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
4909             enter_func,
4910             self.manager.py_result(),
4911             code.get_py_string_const(EncodedString('__enter__'), identifier=True),
4912             code.error_goto_if_null(enter_func, self.pos),
4913             ))
4914         code.put_gotref(enter_func)
4915         self.manager.generate_disposal_code(code)
4916         self.manager.free_temps(code)
4917         self.target_temp.allocate(code)
4918         code.putln('%s = PyObject_Call(%s, ((PyObject *)%s), NULL); %s' % (
4919             self.target_temp.result(),
4920             enter_func,
4921             Naming.empty_tuple,
4922             code.error_goto_if_null(self.target_temp.result(), self.pos),
4923             ))
4924         code.put_gotref(self.target_temp.result())
4925         code.put_decref_clear(enter_func, py_object_type)
4926         code.funcstate.release_temp(enter_func)
4927         if not self.has_target:
4928             code.put_decref_clear(self.target_temp.result(), type=py_object_type)
4929             self.target_temp.release(code)
4930             # otherwise, WithTargetAssignmentStatNode will do it for us
4931
4932         code.error_label = old_error_label
4933         self.body.generate_execution_code(code)
4934
4935         step_over_label = code.new_label()
4936         code.put_goto(step_over_label)
4937         code.put_label(intermediate_error_label)
4938         code.put_decref_clear(self.exit_var, py_object_type)
4939         code.put_goto(old_error_label)
4940         code.put_label(step_over_label)
4941
4942         code.funcstate.release_temp(self.exit_var)
4943         code.putln('}')
4944
4945 class WithTargetAssignmentStatNode(AssignmentNode):
4946     # The target assignment of the 'with' statement value (return
4947     # value of the __enter__() call).
4948     #
4949     # This is a special cased assignment that steals the RHS reference
4950     # and frees its temp.
4951     #
4952     # lhs  ExprNode  the assignment target
4953     # rhs  TempNode  the return value of the __enter__() call
4954
4955     child_attrs = ["lhs", "rhs"]
4956
4957     def analyse_declarations(self, env):
4958         self.lhs.analyse_target_declaration(env)
4959
4960     def analyse_types(self, env):
4961         self.rhs.analyse_types(env)
4962         self.lhs.analyse_target_types(env)
4963         self.lhs.gil_assignment_check(env)
4964         self.orig_rhs = self.rhs
4965         self.rhs = self.rhs.coerce_to(self.lhs.type, env)
4966
4967     def generate_execution_code(self, code):
4968         self.rhs.generate_evaluation_code(code)
4969         self.lhs.generate_assignment_code(self.rhs, code)
4970         self.orig_rhs.release(code)
4971
4972     def generate_function_definitions(self, env, code):
4973         self.rhs.generate_function_definitions(env, code)
4974
4975     def annotate(self, code):
4976         self.lhs.annotate(code)
4977         self.rhs.annotate(code)
4978
4979
4980 class TryExceptStatNode(StatNode):
4981     #  try .. except statement
4982     #
4983     #  body             StatNode
4984     #  except_clauses   [ExceptClauseNode]
4985     #  else_clause      StatNode or None
4986
4987     child_attrs = ["body", "except_clauses", "else_clause"]
4988
4989     def analyse_control_flow(self, env):
4990         env.start_branching(self.pos)
4991         self.body.analyse_control_flow(env)
4992         successful_try = env.control_flow # grab this for later
4993         env.next_branch(self.body.end_pos())
4994         env.finish_branching(self.body.end_pos())
4995
4996         env.start_branching(self.except_clauses[0].pos)
4997         for except_clause in self.except_clauses:
4998             except_clause.analyse_control_flow(env)
4999             env.next_branch(except_clause.end_pos())
5000
5001         # the else cause it executed only when the try clause finishes
5002         env.control_flow.incoming = successful_try
5003         if self.else_clause:
5004             self.else_clause.analyse_control_flow(env)
5005         env.finish_branching(self.end_pos())
5006
5007     def analyse_declarations(self, env):
5008         self.body.analyse_declarations(env)
5009         for except_clause in self.except_clauses:
5010             except_clause.analyse_declarations(env)
5011         if self.else_clause:
5012             self.else_clause.analyse_declarations(env)
5013         env.use_utility_code(reset_exception_utility_code)
5014
5015     def analyse_expressions(self, env):
5016         self.body.analyse_expressions(env)
5017         default_clause_seen = 0
5018         for except_clause in self.except_clauses:
5019             except_clause.analyse_expressions(env)
5020             if default_clause_seen:
5021                 error(except_clause.pos, "default 'except:' must be last")
5022             if not except_clause.pattern:
5023                 default_clause_seen = 1
5024         self.has_default_clause = default_clause_seen
5025         if self.else_clause:
5026             self.else_clause.analyse_expressions(env)
5027
5028     nogil_check = Node.gil_error
5029     gil_message = "Try-except statement"
5030
5031     def generate_execution_code(self, code):
5032         old_return_label = code.return_label
5033         old_break_label = code.break_label
5034         old_continue_label = code.continue_label
5035         old_error_label = code.new_error_label()
5036         our_error_label = code.error_label
5037         except_end_label = code.new_label('exception_handled')
5038         except_error_label = code.new_label('except_error')
5039         except_return_label = code.new_label('except_return')
5040         try_return_label = code.new_label('try_return')
5041         try_break_label = code.new_label('try_break')
5042         try_continue_label = code.new_label('try_continue')
5043         try_end_label = code.new_label('try_end')
5044
5045         exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
5046                          for i in xrange(3)]
5047         code.putln("{")
5048         code.putln("__Pyx_ExceptionSave(%s);" %
5049                    ', '.join(['&%s' % var for var in exc_save_vars]))
5050         for var in exc_save_vars:
5051             code.put_xgotref(var)
5052         code.putln(
5053             "/*try:*/ {")
5054         code.return_label = try_return_label
5055         code.break_label = try_break_label
5056         code.continue_label = try_continue_label
5057         self.body.generate_execution_code(code)
5058         code.putln(
5059             "}")
5060         temps_to_clean_up = code.funcstate.all_free_managed_temps()
5061         code.error_label = except_error_label
5062         code.return_label = except_return_label
5063         if self.else_clause:
5064             code.putln(
5065                 "/*else:*/ {")
5066             self.else_clause.generate_execution_code(code)
5067             code.putln(
5068                 "}")
5069         for var in exc_save_vars:
5070             code.put_xdecref_clear(var, py_object_type)
5071         code.put_goto(try_end_label)
5072         if code.label_used(try_return_label):
5073             code.put_label(try_return_label)
5074             for var in exc_save_vars:
5075                 code.put_xgiveref(var)
5076             code.putln("__Pyx_ExceptionReset(%s);" %
5077                        ', '.join(exc_save_vars))
5078             code.put_goto(old_return_label)
5079         code.put_label(our_error_label)
5080         for temp_name, type in temps_to_clean_up:
5081             code.put_xdecref_clear(temp_name, type)
5082         for except_clause in self.except_clauses:
5083             except_clause.generate_handling_code(code, except_end_label)
5084
5085         error_label_used = code.label_used(except_error_label)
5086         if error_label_used or not self.has_default_clause:
5087             if error_label_used:
5088                 code.put_label(except_error_label)
5089             for var in exc_save_vars:
5090                 code.put_xgiveref(var)
5091             code.putln("__Pyx_ExceptionReset(%s);" %
5092                        ', '.join(exc_save_vars))
5093             code.put_goto(old_error_label)
5094
5095         for exit_label, old_label in zip(
5096             [try_break_label, try_continue_label, except_return_label],
5097             [old_break_label, old_continue_label, old_return_label]):
5098
5099             if code.label_used(exit_label):
5100                 code.put_label(exit_label)
5101                 for var in exc_save_vars:
5102                     code.put_xgiveref(var)
5103                 code.putln("__Pyx_ExceptionReset(%s);" %
5104                            ', '.join(exc_save_vars))
5105                 code.put_goto(old_label)
5106
5107         if code.label_used(except_end_label):
5108             code.put_label(except_end_label)
5109             for var in exc_save_vars:
5110                 code.put_xgiveref(var)
5111             code.putln("__Pyx_ExceptionReset(%s);" %
5112                        ', '.join(exc_save_vars))
5113         code.put_label(try_end_label)
5114         code.putln("}")
5115
5116         for cname in exc_save_vars:
5117             code.funcstate.release_temp(cname)
5118
5119         code.return_label = old_return_label
5120         code.break_label = old_break_label
5121         code.continue_label = old_continue_label
5122         code.error_label = old_error_label
5123
5124     def generate_function_definitions(self, env, code):
5125         self.body.generate_function_definitions(env, code)
5126         for except_clause in self.except_clauses:
5127             except_clause.generate_function_definitions(env, code)
5128         if self.else_clause is not None:
5129             self.else_clause.generate_function_definitions(env, code)
5130
5131     def annotate(self, code):
5132         self.body.annotate(code)
5133         for except_node in self.except_clauses:
5134             except_node.annotate(code)
5135         if self.else_clause:
5136             self.else_clause.annotate(code)
5137
5138
5139 class ExceptClauseNode(Node):
5140     #  Part of try ... except statement.
5141     #
5142     #  pattern        [ExprNode]
5143     #  target         ExprNode or None
5144     #  body           StatNode
5145     #  excinfo_target ResultRefNode or None   optional target for exception info
5146     #  match_flag     string             result of exception match
5147     #  exc_value      ExcValueNode       used internally
5148     #  function_name  string             qualified name of enclosing function
5149     #  exc_vars       (string * 3)       local exception variables
5150
5151     # excinfo_target is never set by the parser, but can be set by a transform
5152     # in order to extract more extensive information about the exception as a
5153     # sys.exc_info()-style tuple into a target variable
5154
5155     child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
5156
5157     exc_value = None
5158     excinfo_target = None
5159
5160     def analyse_declarations(self, env):
5161         if self.target:
5162             self.target.analyse_target_declaration(env)
5163         self.body.analyse_declarations(env)
5164
5165     def analyse_expressions(self, env):
5166         import ExprNodes
5167         genv = env.global_scope()
5168         self.function_name = env.qualified_name
5169         if self.pattern:
5170             # normalise/unpack self.pattern into a list
5171             for i, pattern in enumerate(self.pattern):
5172                 pattern.analyse_expressions(env)
5173                 self.pattern[i] = pattern.coerce_to_pyobject(env)
5174
5175         if self.target:
5176             self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
5177             self.target.analyse_target_expression(env, self.exc_value)
5178         if self.excinfo_target is not None:
5179             import ExprNodes
5180             self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
5181                 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
5182             self.excinfo_tuple.analyse_expressions(env)
5183
5184         self.body.analyse_expressions(env)
5185
5186     def generate_handling_code(self, code, end_label):
5187         code.mark_pos(self.pos)
5188         if self.pattern:
5189             exc_tests = []
5190             for pattern in self.pattern:
5191                 pattern.generate_evaluation_code(code)
5192                 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
5193
5194             match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
5195             code.putln(
5196                 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
5197             for pattern in self.pattern:
5198                 pattern.generate_disposal_code(code)
5199                 pattern.free_temps(code)
5200             code.putln(
5201                 "if (%s) {" %
5202                     match_flag)
5203             code.funcstate.release_temp(match_flag)
5204         else:
5205             code.putln("/*except:*/ {")
5206
5207         if not getattr(self.body, 'stats', True) and \
5208                 self.excinfo_target is None and self.target is None:
5209             # most simple case: no exception variable, empty body (pass)
5210             # => reset the exception state, done
5211             code.putln("PyErr_Restore(0,0,0);")
5212             code.put_goto(end_label)
5213             code.putln("}")
5214             return
5215
5216         exc_vars = [code.funcstate.allocate_temp(py_object_type,
5217                                                  manage_ref=True)
5218                     for i in xrange(3)]
5219         code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
5220         # We always have to fetch the exception value even if
5221         # there is no target, because this also normalises the
5222         # exception and stores it in the thread state.
5223         code.globalstate.use_utility_code(get_exception_utility_code)
5224         exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
5225         code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
5226             code.error_goto(self.pos)))
5227         for x in exc_vars:
5228             code.put_gotref(x)
5229         if self.target:
5230             self.exc_value.set_var(exc_vars[1])
5231             self.exc_value.generate_evaluation_code(code)
5232             self.target.generate_assignment_code(self.exc_value, code)
5233         if self.excinfo_target is not None:
5234             for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
5235                 node.set_var(tempvar)
5236             self.excinfo_tuple.generate_evaluation_code(code)
5237             self.excinfo_target.result_code = self.excinfo_tuple.result()
5238
5239         old_break_label, old_continue_label = code.break_label, code.continue_label
5240         code.break_label = code.new_label('except_break')
5241         code.continue_label = code.new_label('except_continue')
5242
5243         old_exc_vars = code.funcstate.exc_vars
5244         code.funcstate.exc_vars = exc_vars
5245         self.body.generate_execution_code(code)
5246         code.funcstate.exc_vars = old_exc_vars
5247         if self.excinfo_target is not None:
5248             self.excinfo_tuple.generate_disposal_code(code)
5249         for var in exc_vars:
5250             code.put_decref_clear(var, py_object_type)
5251         code.put_goto(end_label)
5252
5253         if code.label_used(code.break_label):
5254             code.put_label(code.break_label)
5255             if self.excinfo_target is not None:
5256                 self.excinfo_tuple.generate_disposal_code(code)
5257             for var in exc_vars:
5258                 code.put_decref_clear(var, py_object_type)
5259             code.put_goto(old_break_label)
5260         code.break_label = old_break_label
5261
5262         if code.label_used(code.continue_label):
5263             code.put_label(code.continue_label)
5264             if self.excinfo_target is not None:
5265                 self.excinfo_tuple.generate_disposal_code(code)
5266             for var in exc_vars:
5267                 code.put_decref_clear(var, py_object_type)
5268             code.put_goto(old_continue_label)
5269         code.continue_label = old_continue_label
5270
5271         if self.excinfo_target is not None:
5272             self.excinfo_tuple.free_temps(code)
5273         for temp in exc_vars:
5274             code.funcstate.release_temp(temp)
5275
5276         code.putln(
5277             "}")
5278
5279     def generate_function_definitions(self, env, code):
5280         if self.target is not None:
5281             self.target.generate_function_definitions(env, code)
5282         self.body.generate_function_definitions(env, code)
5283
5284     def annotate(self, code):
5285         if self.pattern:
5286             for pattern in self.pattern:
5287                 pattern.annotate(code)
5288         if self.target:
5289             self.target.annotate(code)
5290         self.body.annotate(code)
5291
5292
5293 class TryFinallyStatNode(StatNode):
5294     #  try ... finally statement
5295     #
5296     #  body             StatNode
5297     #  finally_clause   StatNode
5298     #
5299     #  The plan is that we funnel all continue, break
5300     #  return and error gotos into the beginning of the
5301     #  finally block, setting a variable to remember which
5302     #  one we're doing. At the end of the finally block, we
5303     #  switch on the variable to figure out where to go.
5304     #  In addition, if we're doing an error, we save the
5305     #  exception on entry to the finally block and restore
5306     #  it on exit.
5307
5308     child_attrs = ["body", "finally_clause"]
5309
5310     preserve_exception = 1
5311
5312     # handle exception case, in addition to return/break/continue
5313     handle_error_case = True
5314
5315     disallow_continue_in_try_finally = 0
5316     # There doesn't seem to be any point in disallowing
5317     # continue in the try block, since we have no problem
5318     # handling it.
5319
5320     def create_analysed(pos, env, body, finally_clause):
5321         node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5322         return node
5323     create_analysed = staticmethod(create_analysed)
5324
5325     def analyse_control_flow(self, env):
5326         env.start_branching(self.pos)
5327         self.body.analyse_control_flow(env)
5328         env.next_branch(self.body.end_pos())
5329         env.finish_branching(self.body.end_pos())
5330         self.finally_clause.analyse_control_flow(env)
5331
5332     def analyse_declarations(self, env):
5333         self.body.analyse_declarations(env)
5334         self.finally_clause.analyse_declarations(env)
5335
5336     def analyse_expressions(self, env):
5337         self.body.analyse_expressions(env)
5338         self.finally_clause.analyse_expressions(env)
5339
5340     nogil_check = Node.gil_error
5341     gil_message = "Try-finally statement"
5342
5343     def generate_execution_code(self, code):
5344         old_error_label = code.error_label
5345         old_labels = code.all_new_labels()
5346         new_labels = code.get_all_labels()
5347         new_error_label = code.error_label
5348         if not self.handle_error_case:
5349             code.error_label = old_error_label
5350         catch_label = code.new_label()
5351         code.putln(
5352             "/*try:*/ {")
5353         if self.disallow_continue_in_try_finally:
5354             was_in_try_finally = code.funcstate.in_try_finally
5355             code.funcstate.in_try_finally = 1
5356         self.body.generate_execution_code(code)
5357         if self.disallow_continue_in_try_finally:
5358             code.funcstate.in_try_finally = was_in_try_finally
5359         code.putln(
5360             "}")
5361         temps_to_clean_up = code.funcstate.all_free_managed_temps()
5362         code.mark_pos(self.finally_clause.pos)
5363         code.putln(
5364             "/*finally:*/ {")
5365         cases_used = []
5366         error_label_used = 0
5367         for i, new_label in enumerate(new_labels):
5368             if new_label in code.labels_used:
5369                 cases_used.append(i)
5370                 if new_label == new_error_label:
5371                     error_label_used = 1
5372                     error_label_case = i
5373         if cases_used:
5374             code.putln(
5375                     "int __pyx_why;")
5376             if error_label_used and self.preserve_exception:
5377                 code.putln(
5378                     "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5379                 code.putln(
5380                     "int %s;" % Naming.exc_lineno_name)
5381                 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5382                 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5383                 code.putln(exc_var_init_zero)
5384             else:
5385                 exc_var_init_zero = None
5386             code.use_label(catch_label)
5387             code.putln(
5388                     "__pyx_why = 0; goto %s;" % catch_label)
5389             for i in cases_used:
5390                 new_label = new_labels[i]
5391                 #if new_label and new_label != "<try>":
5392                 if new_label == new_error_label and self.preserve_exception:
5393                     self.put_error_catcher(code,
5394                         new_error_label, i+1, catch_label, temps_to_clean_up)
5395                 else:
5396                     code.put('%s: ' % new_label)
5397                     if exc_var_init_zero:
5398                         code.putln(exc_var_init_zero)
5399                     code.putln("__pyx_why = %s; goto %s;" % (
5400                             i+1,
5401                             catch_label))
5402             code.put_label(catch_label)
5403         code.set_all_labels(old_labels)
5404         if error_label_used:
5405             code.new_error_label()
5406             finally_error_label = code.error_label
5407         self.finally_clause.generate_execution_code(code)
5408         if error_label_used:
5409             if finally_error_label in code.labels_used and self.preserve_exception:
5410                 over_label = code.new_label()
5411                 code.put_goto(over_label);
5412                 code.put_label(finally_error_label)
5413                 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5414                 for var in Naming.exc_vars:
5415                     code.putln("Py_XDECREF(%s);" % var)
5416                 code.putln("}")
5417                 code.put_goto(old_error_label)
5418                 code.put_label(over_label)
5419             code.error_label = old_error_label
5420         if cases_used:
5421             code.putln(
5422                 "switch (__pyx_why) {")
5423             for i in cases_used:
5424                 old_label = old_labels[i]
5425                 if old_label == old_error_label and self.preserve_exception:
5426                     self.put_error_uncatcher(code, i+1, old_error_label)
5427                 else:
5428                     code.use_label(old_label)
5429                     code.putln(
5430                         "case %s: goto %s;" % (
5431                             i+1,
5432                             old_label))
5433             code.putln(
5434                 "}")
5435         code.putln(
5436             "}")
5437
5438     def generate_function_definitions(self, env, code):
5439         self.body.generate_function_definitions(env, code)
5440         self.finally_clause.generate_function_definitions(env, code)
5441
5442     def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5443         code.globalstate.use_utility_code(restore_exception_utility_code)
5444         code.putln(
5445             "%s: {" %
5446                 error_label)
5447         code.putln(
5448                 "__pyx_why = %s;" %
5449                     i)
5450         for temp_name, type in temps_to_clean_up:
5451             code.put_xdecref_clear(temp_name, type)
5452         code.putln(
5453                 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5454                     Naming.exc_vars)
5455         code.putln(
5456                 "%s = %s;" % (
5457                     Naming.exc_lineno_name, Naming.lineno_cname))
5458         code.put_goto(catch_label)
5459         code.putln("}")
5460
5461     def put_error_uncatcher(self, code, i, error_label):
5462         code.globalstate.use_utility_code(restore_exception_utility_code)
5463         code.putln(
5464             "case %s: {" %
5465                 i)
5466         code.putln(
5467                 "__Pyx_ErrRestore(%s, %s, %s);" %
5468                     Naming.exc_vars)
5469         code.putln(
5470                 "%s = %s;" % (
5471                     Naming.lineno_cname, Naming.exc_lineno_name))
5472         for var in Naming.exc_vars:
5473             code.putln(
5474                 "%s = 0;" %
5475                     var)
5476         code.put_goto(error_label)
5477         code.putln(
5478             "}")
5479
5480     def annotate(self, code):
5481         self.body.annotate(code)
5482         self.finally_clause.annotate(code)
5483
5484
5485 class GILStatNode(TryFinallyStatNode):
5486     #  'with gil' or 'with nogil' statement
5487     #
5488     #   state   string   'gil' or 'nogil'
5489
5490 #    child_attrs = []
5491
5492     preserve_exception = 0
5493
5494     def __init__(self, pos, state, body):
5495         self.state = state
5496         TryFinallyStatNode.__init__(self, pos,
5497             body = body,
5498             finally_clause = GILExitNode(pos, state = state))
5499
5500     def analyse_expressions(self, env):
5501         env.use_utility_code(force_init_threads_utility_code)
5502         was_nogil = env.nogil
5503         env.nogil = 1
5504         TryFinallyStatNode.analyse_expressions(self, env)
5505         env.nogil = was_nogil
5506
5507     nogil_check = None
5508
5509     def generate_execution_code(self, code):
5510         code.mark_pos(self.pos)
5511         code.putln("{")
5512         if self.state == 'gil':
5513             code.putln("#ifdef WITH_THREAD")
5514             code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5515             code.putln("#endif")
5516         else:
5517             code.putln("#ifdef WITH_THREAD")
5518             code.putln("PyThreadState *_save = NULL;")
5519             code.putln("#endif")
5520             code.putln("Py_UNBLOCK_THREADS")
5521         TryFinallyStatNode.generate_execution_code(self, code)
5522         code.putln("}")
5523
5524
5525 class GILExitNode(StatNode):
5526     #  Used as the 'finally' block in a GILStatNode
5527     #
5528     #  state   string   'gil' or 'nogil'
5529
5530     child_attrs = []
5531
5532     def analyse_expressions(self, env):
5533         pass
5534
5535     def generate_execution_code(self, code):
5536         if self.state == 'gil':
5537             code.putln("#ifdef WITH_THREAD")
5538             code.putln("PyGILState_Release(_save);")
5539             code.putln("#endif")
5540         else:
5541             code.putln("Py_BLOCK_THREADS")
5542
5543
5544 class CImportStatNode(StatNode):
5545     #  cimport statement
5546     #
5547     #  module_name   string           Qualified name of module being imported
5548     #  as_name       string or None   Name specified in "as" clause, if any
5549
5550     child_attrs = []
5551
5552     def analyse_declarations(self, env):
5553         if not env.is_module_scope:
5554             error(self.pos, "cimport only allowed at module level")
5555             return
5556         module_scope = env.find_module(self.module_name, self.pos)
5557         if "." in self.module_name:
5558             names = [EncodedString(name) for name in self.module_name.split(".")]
5559             top_name = names[0]
5560             top_module_scope = env.context.find_submodule(top_name)
5561             module_scope = top_module_scope
5562             for name in names[1:]:
5563                 submodule_scope = module_scope.find_submodule(name)
5564                 module_scope.declare_module(name, submodule_scope, self.pos)
5565                 module_scope = submodule_scope
5566             if self.as_name:
5567                 env.declare_module(self.as_name, module_scope, self.pos)
5568             else:
5569                 env.declare_module(top_name, top_module_scope, self.pos)
5570         else:
5571             name = self.as_name or self.module_name
5572             env.declare_module(name, module_scope, self.pos)
5573
5574     def analyse_expressions(self, env):
5575         pass
5576
5577     def generate_execution_code(self, code):
5578         pass
5579
5580
5581 class FromCImportStatNode(StatNode):
5582     #  from ... cimport statement
5583     #
5584     #  module_name     string                        Qualified name of module
5585     #  imported_names  [(pos, name, as_name, kind)]  Names to be imported
5586
5587     child_attrs = []
5588
5589     def analyse_declarations(self, env):
5590         if not env.is_module_scope:
5591             error(self.pos, "cimport only allowed at module level")
5592             return
5593         module_scope = env.find_module(self.module_name, self.pos)
5594         env.add_imported_module(module_scope)
5595         for pos, name, as_name, kind in self.imported_names:
5596             if name == "*":
5597                 for local_name, entry in module_scope.entries.items():
5598                     env.add_imported_entry(local_name, entry, pos)
5599             else:
5600                 entry = module_scope.lookup(name)
5601                 if entry:
5602                     if kind and not self.declaration_matches(entry, kind):
5603                         entry.redeclared(pos)
5604                 else:
5605                     if kind == 'struct' or kind == 'union':
5606                         entry = module_scope.declare_struct_or_union(name,
5607                             kind = kind, scope = None, typedef_flag = 0, pos = pos)
5608                     elif kind == 'class':
5609                         entry = module_scope.declare_c_class(name, pos = pos,
5610                             module_name = self.module_name)
5611                     else:
5612                         submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5613                         if submodule_scope.parent_module is module_scope:
5614                             env.declare_module(as_name or name, submodule_scope, self.pos)
5615                         else:
5616                             error(pos, "Name '%s' not declared in module '%s'"
5617                                 % (name, self.module_name))
5618
5619                 if entry:
5620                     local_name = as_name or name
5621                     env.add_imported_entry(local_name, entry, pos)
5622
5623     def declaration_matches(self, entry, kind):
5624         if not entry.is_type:
5625             return 0
5626         type = entry.type
5627         if kind == 'class':
5628             if not type.is_extension_type:
5629                 return 0
5630         else:
5631             if not type.is_struct_or_union:
5632                 return 0
5633             if kind != type.kind:
5634                 return 0
5635         return 1
5636
5637     def analyse_expressions(self, env):
5638         pass
5639
5640     def generate_execution_code(self, code):
5641         pass
5642
5643
5644 class FromImportStatNode(StatNode):
5645     #  from ... import statement
5646     #
5647     #  module           ImportNode
5648     #  items            [(string, NameNode)]
5649     #  interned_items   [(string, NameNode, ExprNode)]
5650     #  item             PyTempNode            used internally
5651     #  import_star      boolean               used internally
5652
5653     child_attrs = ["module"]
5654     import_star = 0
5655
5656     def analyse_declarations(self, env):
5657         for name, target in self.items:
5658             if name == "*":
5659                 if not env.is_module_scope:
5660                     error(self.pos, "import * only allowed at module level")
5661                     return
5662                 env.has_import_star = 1
5663                 self.import_star = 1
5664             else:
5665                 target.analyse_target_declaration(env)
5666
5667     def analyse_expressions(self, env):
5668         import ExprNodes
5669         self.module.analyse_expressions(env)
5670         self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5671         self.interned_items = []
5672         for name, target in self.items:
5673             if name == '*':
5674                 for _, entry in env.entries.items():
5675                     if not entry.is_type and entry.type.is_extension_type:
5676                         env.use_utility_code(ExprNodes.type_test_utility_code)
5677                         break
5678             else:
5679                 entry =  env.lookup(target.name)
5680                 # check whether or not entry is already cimported
5681                 if (entry.is_type and entry.type.name == name
5682                     and hasattr(entry.type, 'module_name')):
5683                     if entry.type.module_name == self.module.module_name.value:
5684                         # cimported with absolute name
5685                         continue
5686                     try:
5687                         # cimported with relative name
5688                         module = env.find_module(self.module.module_name.value,
5689                                                  pos=None)
5690                         if entry.type.module_name == module.qualified_name:
5691                             continue
5692                     except AttributeError:
5693                         pass
5694                 target.analyse_target_expression(env, None)
5695                 if target.type is py_object_type:
5696                     coerced_item = None
5697                 else:
5698                     coerced_item = self.item.coerce_to(target.type, env)
5699                 self.interned_items.append((name, target, coerced_item))
5700
5701     def generate_execution_code(self, code):
5702         self.module.generate_evaluation_code(code)
5703         if self.import_star:
5704             code.putln(
5705                 'if (%s(%s) < 0) %s;' % (
5706                     Naming.import_star,
5707                     self.module.py_result(),
5708                     code.error_goto(self.pos)))
5709         item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5710         self.item.set_cname(item_temp)
5711         for name, target, coerced_item in self.interned_items:
5712             cname = code.intern_identifier(name)
5713             code.putln(
5714                 '%s = PyObject_GetAttr(%s, %s); %s' % (
5715                     item_temp,
5716                     self.module.py_result(),
5717                     cname,
5718                     code.error_goto_if_null(item_temp, self.pos)))
5719             code.put_gotref(item_temp)
5720             if coerced_item is None:
5721                 target.generate_assignment_code(self.item, code)
5722             else:
5723                 coerced_item.allocate_temp_result(code)
5724                 coerced_item.generate_result_code(code)
5725                 target.generate_assignment_code(coerced_item, code)
5726             code.put_decref_clear(item_temp, py_object_type)
5727         code.funcstate.release_temp(item_temp)
5728         self.module.generate_disposal_code(code)
5729         self.module.free_temps(code)
5730
5731
5732
5733 #------------------------------------------------------------------------------------
5734 #
5735 #  Runtime support code
5736 #
5737 #------------------------------------------------------------------------------------
5738
5739 utility_function_predeclarations = \
5740 """
5741 /* inline attribute */
5742 #ifndef CYTHON_INLINE
5743   #if defined(__GNUC__)
5744     #define CYTHON_INLINE __inline__
5745   #elif defined(_MSC_VER)
5746     #define CYTHON_INLINE __inline
5747   #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5748     #define CYTHON_INLINE inline
5749   #else
5750     #define CYTHON_INLINE
5751   #endif
5752 #endif
5753
5754 /* unused attribute */
5755 #ifndef CYTHON_UNUSED
5756 # if defined(__GNUC__)
5757 #   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5758 #     define CYTHON_UNUSED __attribute__ ((__unused__))
5759 #   else
5760 #     define CYTHON_UNUSED
5761 #   endif
5762 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5763 #   define CYTHON_UNUSED __attribute__ ((__unused__))
5764 # else
5765 #   define CYTHON_UNUSED
5766 # endif
5767 #endif
5768
5769 typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
5770
5771 """
5772
5773 if Options.gcc_branch_hints:
5774     branch_prediction_macros = \
5775     """
5776 #ifdef __GNUC__
5777 /* Test for GCC > 2.95 */
5778 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5779 #define likely(x)   __builtin_expect(!!(x), 1)
5780 #define unlikely(x) __builtin_expect(!!(x), 0)
5781 #else /* __GNUC__ > 2 ... */
5782 #define likely(x)   (x)
5783 #define unlikely(x) (x)
5784 #endif /* __GNUC__ > 2 ... */
5785 #else /* __GNUC__ */
5786 #define likely(x)   (x)
5787 #define unlikely(x) (x)
5788 #endif /* __GNUC__ */
5789     """
5790 else:
5791     branch_prediction_macros = \
5792     """
5793 #define likely(x)   (x)
5794 #define unlikely(x) (x)
5795     """
5796
5797 #get_name_predeclaration = \
5798 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5799
5800 #get_name_interned_predeclaration = \
5801 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5802
5803 #------------------------------------------------------------------------------------
5804
5805 printing_utility_code = UtilityCode(
5806 proto = """
5807 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5808 #if PY_MAJOR_VERSION >= 3
5809 static PyObject* %s = 0;
5810 static PyObject* %s = 0;
5811 #endif
5812 """ % (Naming.print_function, Naming.print_function_kwargs),
5813 cleanup = """
5814 #if PY_MAJOR_VERSION >= 3
5815 Py_CLEAR(%s);
5816 Py_CLEAR(%s);
5817 #endif
5818 """ % (Naming.print_function, Naming.print_function_kwargs),
5819 impl = r"""
5820 #if PY_MAJOR_VERSION < 3
5821 static PyObject *__Pyx_GetStdout(void) {
5822     PyObject *f = PySys_GetObject((char *)"stdout");
5823     if (!f) {
5824         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5825     }
5826     return f;
5827 }
5828
5829 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5830     PyObject* v;
5831     int i;
5832
5833     if (!f) {
5834         if (!(f = __Pyx_GetStdout()))
5835             return -1;
5836     }
5837     for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5838         if (PyFile_SoftSpace(f, 1)) {
5839             if (PyFile_WriteString(" ", f) < 0)
5840                 return -1;
5841         }
5842         v = PyTuple_GET_ITEM(arg_tuple, i);
5843         if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5844             return -1;
5845         if (PyString_Check(v)) {
5846             char *s = PyString_AsString(v);
5847             Py_ssize_t len = PyString_Size(v);
5848             if (len > 0 &&
5849                 isspace(Py_CHARMASK(s[len-1])) &&
5850                 s[len-1] != ' ')
5851                     PyFile_SoftSpace(f, 0);
5852         }
5853     }
5854     if (newline) {
5855         if (PyFile_WriteString("\n", f) < 0)
5856             return -1;
5857         PyFile_SoftSpace(f, 0);
5858     }
5859     return 0;
5860 }
5861
5862 #else /* Python 3 has a print function */
5863
5864 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5865     PyObject* kwargs = 0;
5866     PyObject* result = 0;
5867     PyObject* end_string;
5868     if (unlikely(!%(PRINT_FUNCTION)s)) {
5869         %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5870         if (!%(PRINT_FUNCTION)s)
5871             return -1;
5872     }
5873     if (stream) {
5874         kwargs = PyDict_New();
5875         if (unlikely(!kwargs))
5876             return -1;
5877         if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5878             goto bad;
5879         if (!newline) {
5880             end_string = PyUnicode_FromStringAndSize(" ", 1);
5881             if (unlikely(!end_string))
5882                 goto bad;
5883             if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5884                 Py_DECREF(end_string);
5885                 goto bad;
5886             }
5887             Py_DECREF(end_string);
5888         }
5889     } else if (!newline) {
5890         if (unlikely(!%(PRINT_KWARGS)s)) {
5891             %(PRINT_KWARGS)s = PyDict_New();
5892             if (unlikely(!%(PRINT_KWARGS)s))
5893                 return -1;
5894             end_string = PyUnicode_FromStringAndSize(" ", 1);
5895             if (unlikely(!end_string))
5896                 return -1;
5897             if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5898                 Py_DECREF(end_string);
5899                 return -1;
5900             }
5901             Py_DECREF(end_string);
5902         }
5903         kwargs = %(PRINT_KWARGS)s;
5904     }
5905     result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5906     if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5907         Py_DECREF(kwargs);
5908     if (!result)
5909         return -1;
5910     Py_DECREF(result);
5911     return 0;
5912 bad:
5913     if (kwargs != %(PRINT_KWARGS)s)
5914         Py_XDECREF(kwargs);
5915     return -1;
5916 }
5917
5918 #endif
5919 """ % {'BUILTINS'       : Naming.builtins_cname,
5920        'PRINT_FUNCTION' : Naming.print_function,
5921        'PRINT_KWARGS'   : Naming.print_function_kwargs}
5922 )
5923
5924
5925 printing_one_utility_code = UtilityCode(
5926 proto = """
5927 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5928 """,
5929 impl = r"""
5930 #if PY_MAJOR_VERSION < 3
5931
5932 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5933     if (!f) {
5934         if (!(f = __Pyx_GetStdout()))
5935             return -1;
5936     }
5937     if (PyFile_SoftSpace(f, 0)) {
5938         if (PyFile_WriteString(" ", f) < 0)
5939             return -1;
5940     }
5941     if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5942         return -1;
5943     if (PyFile_WriteString("\n", f) < 0)
5944         return -1;
5945     return 0;
5946     /* the line below is just to avoid compiler
5947      * compiler warnings about unused functions */
5948     return __Pyx_Print(f, NULL, 0);
5949 }
5950
5951 #else /* Python 3 has a print function */
5952
5953 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5954     int res;
5955     PyObject* arg_tuple = PyTuple_New(1);
5956     if (unlikely(!arg_tuple))
5957         return -1;
5958     Py_INCREF(o);
5959     PyTuple_SET_ITEM(arg_tuple, 0, o);
5960     res = __Pyx_Print(stream, arg_tuple, 1);
5961     Py_DECREF(arg_tuple);
5962     return res;
5963 }
5964
5965 #endif
5966 """,
5967 requires=[printing_utility_code])
5968
5969
5970
5971 #------------------------------------------------------------------------------------
5972
5973 # Exception raising code
5974 #
5975 # Exceptions are raised by __Pyx_Raise() and stored as plain
5976 # type/value/tb in PyThreadState->curexc_*.  When being caught by an
5977 # 'except' statement, curexc_* is moved over to exc_* by
5978 # __Pyx_GetException()
5979
5980 restore_exception_utility_code = UtilityCode(
5981 proto = """
5982 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5983 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5984 """,
5985 impl = """
5986 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5987     PyObject *tmp_type, *tmp_value, *tmp_tb;
5988     PyThreadState *tstate = PyThreadState_GET();
5989
5990     tmp_type = tstate->curexc_type;
5991     tmp_value = tstate->curexc_value;
5992     tmp_tb = tstate->curexc_traceback;
5993     tstate->curexc_type = type;
5994     tstate->curexc_value = value;
5995     tstate->curexc_traceback = tb;
5996     Py_XDECREF(tmp_type);
5997     Py_XDECREF(tmp_value);
5998     Py_XDECREF(tmp_tb);
5999 }
6000
6001 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
6002     PyThreadState *tstate = PyThreadState_GET();
6003     *type = tstate->curexc_type;
6004     *value = tstate->curexc_value;
6005     *tb = tstate->curexc_traceback;
6006
6007     tstate->curexc_type = 0;
6008     tstate->curexc_value = 0;
6009     tstate->curexc_traceback = 0;
6010 }
6011
6012 """)
6013
6014 # The following function is based on do_raise() from ceval.c. There
6015 # are separate versions for Python2 and Python3 as exception handling
6016 # has changed quite a lot between the two versions.
6017
6018 raise_utility_code = UtilityCode(
6019 proto = """
6020 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
6021 """,
6022 impl = """
6023 #if PY_MAJOR_VERSION < 3
6024 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
6025     /* cause is unused */
6026     Py_XINCREF(type);
6027     Py_XINCREF(value);
6028     Py_XINCREF(tb);
6029     /* First, check the traceback argument, replacing None with NULL. */
6030     if (tb == Py_None) {
6031         Py_DECREF(tb);
6032         tb = 0;
6033     }
6034     else if (tb != NULL && !PyTraceBack_Check(tb)) {
6035         PyErr_SetString(PyExc_TypeError,
6036             "raise: arg 3 must be a traceback or None");
6037         goto raise_error;
6038     }
6039     /* Next, replace a missing value with None */
6040     if (value == NULL) {
6041         value = Py_None;
6042         Py_INCREF(value);
6043     }
6044     #if PY_VERSION_HEX < 0x02050000
6045     if (!PyClass_Check(type))
6046     #else
6047     if (!PyType_Check(type))
6048     #endif
6049     {
6050         /* Raising an instance.  The value should be a dummy. */
6051         if (value != Py_None) {
6052             PyErr_SetString(PyExc_TypeError,
6053                 "instance exception may not have a separate value");
6054             goto raise_error;
6055         }
6056         /* Normalize to raise <class>, <instance> */
6057         Py_DECREF(value);
6058         value = type;
6059         #if PY_VERSION_HEX < 0x02050000
6060             if (PyInstance_Check(type)) {
6061                 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
6062                 Py_INCREF(type);
6063             }
6064             else {
6065                 type = 0;
6066                 PyErr_SetString(PyExc_TypeError,
6067                     "raise: exception must be an old-style class or instance");
6068                 goto raise_error;
6069             }
6070         #else
6071             type = (PyObject*) Py_TYPE(type);
6072             Py_INCREF(type);
6073             if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
6074                 PyErr_SetString(PyExc_TypeError,
6075                     "raise: exception class must be a subclass of BaseException");
6076                 goto raise_error;
6077             }
6078         #endif
6079     }
6080
6081     __Pyx_ErrRestore(type, value, tb);
6082     return;
6083 raise_error:
6084     Py_XDECREF(value);
6085     Py_XDECREF(type);
6086     Py_XDECREF(tb);
6087     return;
6088 }
6089
6090 #else /* Python 3+ */
6091
6092 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
6093     if (tb == Py_None) {
6094         tb = 0;
6095     } else if (tb && !PyTraceBack_Check(tb)) {
6096         PyErr_SetString(PyExc_TypeError,
6097             "raise: arg 3 must be a traceback or None");
6098         goto bad;
6099     }
6100     if (value == Py_None)
6101         value = 0;
6102
6103     if (PyExceptionInstance_Check(type)) {
6104         if (value) {
6105             PyErr_SetString(PyExc_TypeError,
6106                 "instance exception may not have a separate value");
6107             goto bad;
6108         }
6109         value = type;
6110         type = (PyObject*) Py_TYPE(value);
6111     } else if (!PyExceptionClass_Check(type)) {
6112         PyErr_SetString(PyExc_TypeError,
6113             "raise: exception class must be a subclass of BaseException");
6114         goto bad;
6115     }
6116
6117     if (cause) {
6118         PyObject *fixed_cause;
6119         if (PyExceptionClass_Check(cause)) {
6120             fixed_cause = PyObject_CallObject(cause, NULL);
6121             if (fixed_cause == NULL)
6122                 goto bad;
6123         }
6124         else if (PyExceptionInstance_Check(cause)) {
6125             fixed_cause = cause;
6126             Py_INCREF(fixed_cause);
6127         }
6128         else {
6129             PyErr_SetString(PyExc_TypeError,
6130                             "exception causes must derive from "
6131                             "BaseException");
6132             goto bad;
6133         }
6134         if (!value) {
6135             value = PyObject_CallObject(type, NULL);
6136         }
6137         PyException_SetCause(value, fixed_cause);
6138     }
6139
6140     PyErr_SetObject(type, value);
6141
6142     if (tb) {
6143         PyThreadState *tstate = PyThreadState_GET();
6144         PyObject* tmp_tb = tstate->curexc_traceback;
6145         if (tb != tmp_tb) {
6146             Py_INCREF(tb);
6147             tstate->curexc_traceback = tb;
6148             Py_XDECREF(tmp_tb);
6149         }
6150     }
6151
6152 bad:
6153     return;
6154 }
6155 #endif
6156 """,
6157 requires=[restore_exception_utility_code])
6158
6159 #------------------------------------------------------------------------------------
6160
6161 get_exception_utility_code = UtilityCode(
6162 proto = """
6163 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6164 """,
6165 impl = """
6166 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
6167     PyObject *local_type, *local_value, *local_tb;
6168     PyObject *tmp_type, *tmp_value, *tmp_tb;
6169     PyThreadState *tstate = PyThreadState_GET();
6170     local_type = tstate->curexc_type;
6171     local_value = tstate->curexc_value;
6172     local_tb = tstate->curexc_traceback;
6173     tstate->curexc_type = 0;
6174     tstate->curexc_value = 0;
6175     tstate->curexc_traceback = 0;
6176     PyErr_NormalizeException(&local_type, &local_value, &local_tb);
6177     if (unlikely(tstate->curexc_type))
6178         goto bad;
6179     #if PY_MAJOR_VERSION >= 3
6180     if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
6181         goto bad;
6182     #endif
6183     *type = local_type;
6184     *value = local_value;
6185     *tb = local_tb;
6186     Py_INCREF(local_type);
6187     Py_INCREF(local_value);
6188     Py_INCREF(local_tb);
6189     tmp_type = tstate->exc_type;
6190     tmp_value = tstate->exc_value;
6191     tmp_tb = tstate->exc_traceback;
6192     tstate->exc_type = local_type;
6193     tstate->exc_value = local_value;
6194     tstate->exc_traceback = local_tb;
6195     /* Make sure tstate is in a consistent state when we XDECREF
6196        these objects (XDECREF may run arbitrary code). */
6197     Py_XDECREF(tmp_type);
6198     Py_XDECREF(tmp_value);
6199     Py_XDECREF(tmp_tb);
6200     return 0;
6201 bad:
6202     *type = 0;
6203     *value = 0;
6204     *tb = 0;
6205     Py_XDECREF(local_type);
6206     Py_XDECREF(local_value);
6207     Py_XDECREF(local_tb);
6208     return -1;
6209 }
6210
6211 """)
6212
6213 #------------------------------------------------------------------------------------
6214
6215 get_exception_tuple_utility_code = UtilityCode(proto="""
6216 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
6217 """,
6218 # I doubt that calling __Pyx_GetException() here is correct as it moves
6219 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
6220 # exception handlers later on from receiving it.
6221 impl = """
6222 static PyObject *__Pyx_GetExceptionTuple(void) {
6223     PyObject *type = NULL, *value = NULL, *tb = NULL;
6224     if (__Pyx_GetException(&type, &value, &tb) == 0) {
6225         PyObject* exc_info = PyTuple_New(3);
6226         if (exc_info) {
6227             Py_INCREF(type);
6228             Py_INCREF(value);
6229             Py_INCREF(tb);
6230             PyTuple_SET_ITEM(exc_info, 0, type);
6231             PyTuple_SET_ITEM(exc_info, 1, value);
6232             PyTuple_SET_ITEM(exc_info, 2, tb);
6233             return exc_info;
6234         }
6235     }
6236     return NULL;
6237 }
6238 """,
6239 requires=[get_exception_utility_code])
6240
6241 #------------------------------------------------------------------------------------
6242
6243 reset_exception_utility_code = UtilityCode(
6244 proto = """
6245 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6246 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
6247 """,
6248 impl = """
6249 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
6250     PyThreadState *tstate = PyThreadState_GET();
6251     *type = tstate->exc_type;
6252     *value = tstate->exc_value;
6253     *tb = tstate->exc_traceback;
6254     Py_XINCREF(*type);
6255     Py_XINCREF(*value);
6256     Py_XINCREF(*tb);
6257 }
6258
6259 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
6260     PyObject *tmp_type, *tmp_value, *tmp_tb;
6261     PyThreadState *tstate = PyThreadState_GET();
6262     tmp_type = tstate->exc_type;
6263     tmp_value = tstate->exc_value;
6264     tmp_tb = tstate->exc_traceback;
6265     tstate->exc_type = type;
6266     tstate->exc_value = value;
6267     tstate->exc_traceback = tb;
6268     Py_XDECREF(tmp_type);
6269     Py_XDECREF(tmp_value);
6270     Py_XDECREF(tmp_tb);
6271 }
6272 """)
6273
6274 #------------------------------------------------------------------------------------
6275
6276 swap_exception_utility_code = UtilityCode(
6277 proto = """
6278 static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6279 """,
6280 impl = """
6281 static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
6282     PyObject *tmp_type, *tmp_value, *tmp_tb;
6283     PyThreadState *tstate = PyThreadState_GET();
6284
6285     tmp_type = tstate->exc_type;
6286     tmp_value = tstate->exc_value;
6287     tmp_tb = tstate->exc_traceback;
6288
6289     tstate->exc_type = *type;
6290     tstate->exc_value = *value;
6291     tstate->exc_traceback = *tb;
6292
6293     *type = tmp_type;
6294     *value = tmp_value;
6295     *tb = tmp_tb;
6296 }
6297 """)
6298
6299 #------------------------------------------------------------------------------------
6300
6301 arg_type_test_utility_code = UtilityCode(
6302 proto = """
6303 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6304     const char *name, int exact); /*proto*/
6305 """,
6306 impl = """
6307 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6308     const char *name, int exact)
6309 {
6310     if (!type) {
6311         PyErr_Format(PyExc_SystemError, "Missing type object");
6312         return 0;
6313     }
6314     if (none_allowed && obj == Py_None) return 1;
6315     else if (exact) {
6316         if (Py_TYPE(obj) == type) return 1;
6317     }
6318     else {
6319         if (PyObject_TypeCheck(obj, type)) return 1;
6320     }
6321     PyErr_Format(PyExc_TypeError,
6322         "Argument '%s' has incorrect type (expected %s, got %s)",
6323         name, type->tp_name, Py_TYPE(obj)->tp_name);
6324     return 0;
6325 }
6326 """)
6327
6328 #------------------------------------------------------------------------------------
6329 #
6330 #  __Pyx_RaiseArgtupleInvalid raises the correct exception when too
6331 #  many or too few positional arguments were found.  This handles
6332 #  Py_ssize_t formatting correctly.
6333
6334 raise_argtuple_invalid_utility_code = UtilityCode(
6335 proto = """
6336 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
6337     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
6338 """,
6339 impl = """
6340 static void __Pyx_RaiseArgtupleInvalid(
6341     const char* func_name,
6342     int exact,
6343     Py_ssize_t num_min,
6344     Py_ssize_t num_max,
6345     Py_ssize_t num_found)
6346 {
6347     Py_ssize_t num_expected;
6348     const char *number, *more_or_less;
6349
6350     if (num_found < num_min) {
6351         num_expected = num_min;
6352         more_or_less = "at least";
6353     } else {
6354         num_expected = num_max;
6355         more_or_less = "at most";
6356     }
6357     if (exact) {
6358         more_or_less = "exactly";
6359     }
6360     number = (num_expected == 1) ? "" : "s";
6361     PyErr_Format(PyExc_TypeError,
6362         #if PY_VERSION_HEX < 0x02050000
6363             "%s() takes %s %d positional argument%s (%d given)",
6364         #else
6365             "%s() takes %s %zd positional argument%s (%zd given)",
6366         #endif
6367         func_name, more_or_less, num_expected, number, num_found);
6368 }
6369 """)
6370
6371 raise_keyword_required_utility_code = UtilityCode(
6372 proto = """
6373 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6374 """,
6375 impl = """
6376 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6377     const char* func_name,
6378     PyObject* kw_name)
6379 {
6380     PyErr_Format(PyExc_TypeError,
6381         #if PY_MAJOR_VERSION >= 3
6382         "%s() needs keyword-only argument %U", func_name, kw_name);
6383         #else
6384         "%s() needs keyword-only argument %s", func_name,
6385         PyString_AS_STRING(kw_name));
6386         #endif
6387 }
6388 """)
6389
6390 raise_double_keywords_utility_code = UtilityCode(
6391 proto = """
6392 static void __Pyx_RaiseDoubleKeywordsError(
6393     const char* func_name, PyObject* kw_name); /*proto*/
6394 """,
6395 impl = """
6396 static void __Pyx_RaiseDoubleKeywordsError(
6397     const char* func_name,
6398     PyObject* kw_name)
6399 {
6400     PyErr_Format(PyExc_TypeError,
6401         #if PY_MAJOR_VERSION >= 3
6402         "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6403         #else
6404         "%s() got multiple values for keyword argument '%s'", func_name,
6405         PyString_AS_STRING(kw_name));
6406         #endif
6407 }
6408 """)
6409
6410 #------------------------------------------------------------------------------------
6411 #
6412 #  __Pyx_CheckKeywordStrings raises an error if non-string keywords
6413 #  were passed to a function, or if any keywords were passed to a
6414 #  function that does not accept them.
6415
6416 keyword_string_check_utility_code = UtilityCode(
6417 proto = """
6418 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6419     const char* function_name, int kw_allowed); /*proto*/
6420 """,
6421 impl = """
6422 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6423     PyObject *kwdict,
6424     const char* function_name,
6425     int kw_allowed)
6426 {
6427     PyObject* key = 0;
6428     Py_ssize_t pos = 0;
6429     while (PyDict_Next(kwdict, &pos, &key, 0)) {
6430         #if PY_MAJOR_VERSION < 3
6431         if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6432         #else
6433         if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6434         #endif
6435             goto invalid_keyword_type;
6436     }
6437     if ((!kw_allowed) && unlikely(key))
6438         goto invalid_keyword;
6439     return 1;
6440 invalid_keyword_type:
6441     PyErr_Format(PyExc_TypeError,
6442         "%s() keywords must be strings", function_name);
6443     return 0;
6444 invalid_keyword:
6445     PyErr_Format(PyExc_TypeError,
6446     #if PY_MAJOR_VERSION < 3
6447         "%s() got an unexpected keyword argument '%s'",
6448         function_name, PyString_AsString(key));
6449     #else
6450         "%s() got an unexpected keyword argument '%U'",
6451         function_name, key);
6452     #endif
6453     return 0;
6454 }
6455 """)
6456
6457 #------------------------------------------------------------------------------------
6458 #
6459 #  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6460 #  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
6461 #  keywords will raise an invalid keyword error.
6462 #
6463 #  Three kinds of errors are checked: 1) non-string keywords, 2)
6464 #  unexpected keywords and 3) overlap with positional arguments.
6465 #
6466 #  If num_posargs is greater 0, it denotes the number of positional
6467 #  arguments that were passed and that must therefore not appear
6468 #  amongst the keywords as well.
6469 #
6470 #  This method does not check for required keyword arguments.
6471 #
6472
6473 parse_keywords_utility_code = UtilityCode(
6474 proto = """
6475 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6476     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6477     const char* function_name); /*proto*/
6478 """,
6479 impl = """
6480 static int __Pyx_ParseOptionalKeywords(
6481     PyObject *kwds,
6482     PyObject **argnames[],
6483     PyObject *kwds2,
6484     PyObject *values[],
6485     Py_ssize_t num_pos_args,
6486     const char* function_name)
6487 {
6488     PyObject *key = 0, *value = 0;
6489     Py_ssize_t pos = 0;
6490     PyObject*** name;
6491     PyObject*** first_kw_arg = argnames + num_pos_args;
6492
6493     while (PyDict_Next(kwds, &pos, &key, &value)) {
6494         name = first_kw_arg;
6495         while (*name && (**name != key)) name++;
6496         if (*name) {
6497             values[name-argnames] = value;
6498         } else {
6499             #if PY_MAJOR_VERSION < 3
6500             if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6501             #else
6502             if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6503             #endif
6504                 goto invalid_keyword_type;
6505             } else {
6506                 for (name = first_kw_arg; *name; name++) {
6507                     #if PY_MAJOR_VERSION >= 3
6508                     if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6509                         PyUnicode_Compare(**name, key) == 0) break;
6510                     #else
6511                     if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6512                         _PyString_Eq(**name, key)) break;
6513                     #endif
6514                 }
6515                 if (*name) {
6516                     values[name-argnames] = value;
6517                 } else {
6518                     /* unexpected keyword found */
6519                     for (name=argnames; name != first_kw_arg; name++) {
6520                         if (**name == key) goto arg_passed_twice;
6521                         #if PY_MAJOR_VERSION >= 3
6522                         if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6523                             PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6524                         #else
6525                         if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6526                             _PyString_Eq(**name, key)) goto arg_passed_twice;
6527                         #endif
6528                     }
6529                     if (kwds2) {
6530                         if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6531                     } else {
6532                         goto invalid_keyword;
6533                     }
6534                 }
6535             }
6536         }
6537     }
6538     return 0;
6539 arg_passed_twice:
6540     __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6541     goto bad;
6542 invalid_keyword_type:
6543     PyErr_Format(PyExc_TypeError,
6544         "%s() keywords must be strings", function_name);
6545     goto bad;
6546 invalid_keyword:
6547     PyErr_Format(PyExc_TypeError,
6548     #if PY_MAJOR_VERSION < 3
6549         "%s() got an unexpected keyword argument '%s'",
6550         function_name, PyString_AsString(key));
6551     #else
6552         "%s() got an unexpected keyword argument '%U'",
6553         function_name, key);
6554     #endif
6555 bad:
6556     return -1;
6557 }
6558 """,
6559 requires=[raise_double_keywords_utility_code])
6560
6561 #------------------------------------------------------------------------------------
6562
6563 traceback_utility_code = UtilityCode(
6564 proto = """
6565 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6566 """,
6567 impl = """
6568 #include "compile.h"
6569 #include "frameobject.h"
6570 #include "traceback.h"
6571
6572 static void __Pyx_AddTraceback(const char *funcname) {
6573     PyObject *py_srcfile = 0;
6574     PyObject *py_funcname = 0;
6575     PyObject *py_globals = 0;
6576     PyCodeObject *py_code = 0;
6577     PyFrameObject *py_frame = 0;
6578
6579     #if PY_MAJOR_VERSION < 3
6580     py_srcfile = PyString_FromString(%(FILENAME)s);
6581     #else
6582     py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6583     #endif
6584     if (!py_srcfile) goto bad;
6585     if (%(CLINENO)s) {
6586         #if PY_MAJOR_VERSION < 3
6587         py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6588         #else
6589         py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6590         #endif
6591     }
6592     else {
6593         #if PY_MAJOR_VERSION < 3
6594         py_funcname = PyString_FromString(funcname);
6595         #else
6596         py_funcname = PyUnicode_FromString(funcname);
6597         #endif
6598     }
6599     if (!py_funcname) goto bad;
6600     py_globals = PyModule_GetDict(%(GLOBALS)s);
6601     if (!py_globals) goto bad;
6602     py_code = PyCode_New(
6603         0,            /*int argcount,*/
6604         #if PY_MAJOR_VERSION >= 3
6605         0,            /*int kwonlyargcount,*/
6606         #endif
6607         0,            /*int nlocals,*/
6608         0,            /*int stacksize,*/
6609         0,            /*int flags,*/
6610         %(EMPTY_BYTES)s, /*PyObject *code,*/
6611         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6612         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6613         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6614         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6615         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6616         py_srcfile,   /*PyObject *filename,*/
6617         py_funcname,  /*PyObject *name,*/
6618         %(LINENO)s,   /*int firstlineno,*/
6619         %(EMPTY_BYTES)s  /*PyObject *lnotab*/
6620     );
6621     if (!py_code) goto bad;
6622     py_frame = PyFrame_New(
6623         PyThreadState_GET(), /*PyThreadState *tstate,*/
6624         py_code,             /*PyCodeObject *code,*/
6625         py_globals,          /*PyObject *globals,*/
6626         0                    /*PyObject *locals*/
6627     );
6628     if (!py_frame) goto bad;
6629     py_frame->f_lineno = %(LINENO)s;
6630     PyTraceBack_Here(py_frame);
6631 bad:
6632     Py_XDECREF(py_srcfile);
6633     Py_XDECREF(py_funcname);
6634     Py_XDECREF(py_code);
6635     Py_XDECREF(py_frame);
6636 }
6637 """ % {
6638     'FILENAME': Naming.filename_cname,
6639     'LINENO':  Naming.lineno_cname,
6640     'CFILENAME': Naming.cfilenm_cname,
6641     'CLINENO':  Naming.clineno_cname,
6642     'GLOBALS': Naming.module_cname,
6643     'EMPTY_TUPLE' : Naming.empty_tuple,
6644     'EMPTY_BYTES' : Naming.empty_bytes,
6645 })
6646
6647 #------------------------------------------------------------------------------------
6648
6649 unraisable_exception_utility_code = UtilityCode(
6650 proto = """
6651 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6652 """,
6653 impl = """
6654 static void __Pyx_WriteUnraisable(const char *name) {
6655     PyObject *old_exc, *old_val, *old_tb;
6656     PyObject *ctx;
6657     __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6658     #if PY_MAJOR_VERSION < 3
6659     ctx = PyString_FromString(name);
6660     #else
6661     ctx = PyUnicode_FromString(name);
6662     #endif
6663     __Pyx_ErrRestore(old_exc, old_val, old_tb);
6664     if (!ctx) {
6665         PyErr_WriteUnraisable(Py_None);
6666     } else {
6667         PyErr_WriteUnraisable(ctx);
6668         Py_DECREF(ctx);
6669     }
6670 }
6671 """,
6672 requires=[restore_exception_utility_code])
6673
6674 #------------------------------------------------------------------------------------
6675
6676 set_vtable_utility_code = UtilityCode(
6677 proto = """
6678 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6679 """,
6680 impl = """
6681 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6682 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6683     PyObject *ob = PyCapsule_New(vtable, 0, 0);
6684 #else
6685     PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6686 #endif
6687     if (!ob)
6688         goto bad;
6689     if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6690         goto bad;
6691     Py_DECREF(ob);
6692     return 0;
6693 bad:
6694     Py_XDECREF(ob);
6695     return -1;
6696 }
6697 """)
6698
6699 #------------------------------------------------------------------------------------
6700
6701 get_vtable_utility_code = UtilityCode(
6702 proto = """
6703 static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
6704 """,
6705 impl = r"""
6706 static void* __Pyx_GetVtable(PyObject *dict) {
6707     void* ptr;
6708     PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6709     if (!ob)
6710         goto bad;
6711 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6712     ptr = PyCapsule_GetPointer(ob, 0);
6713 #else
6714     ptr = PyCObject_AsVoidPtr(ob);
6715 #endif
6716     if (!ptr && !PyErr_Occurred())
6717         PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
6718     Py_DECREF(ob);
6719     return ptr;
6720 bad:
6721     Py_XDECREF(ob);
6722     return NULL;
6723 }
6724 """)
6725
6726 #------------------------------------------------------------------------------------
6727
6728 init_string_tab_utility_code = UtilityCode(
6729 proto = """
6730 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6731 """,
6732 impl = """
6733 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6734     while (t->p) {
6735         #if PY_MAJOR_VERSION < 3
6736         if (t->is_unicode) {
6737             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6738         } else if (t->intern) {
6739             *t->p = PyString_InternFromString(t->s);
6740         } else {
6741             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6742         }
6743         #else  /* Python 3+ has unicode identifiers */
6744         if (t->is_unicode | t->is_str) {
6745             if (t->intern) {
6746                 *t->p = PyUnicode_InternFromString(t->s);
6747             } else if (t->encoding) {
6748                 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6749             } else {
6750                 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6751             }
6752         } else {
6753             *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6754         }
6755         #endif
6756         if (!*t->p)
6757             return -1;
6758         ++t;
6759     }
6760     return 0;
6761 }
6762 """)
6763
6764 #------------------------------------------------------------------------------------
6765
6766 force_init_threads_utility_code = UtilityCode(
6767 proto="""
6768 #ifndef __PYX_FORCE_INIT_THREADS
6769   #if PY_VERSION_HEX < 0x02040200
6770     #define __PYX_FORCE_INIT_THREADS 1
6771   #else
6772     #define __PYX_FORCE_INIT_THREADS 0
6773   #endif
6774 #endif
6775 """)
6776
6777 #------------------------------------------------------------------------------------
6778
6779 # Note that cPython ignores PyTrace_EXCEPTION,
6780 # but maybe some other profilers don't.
6781
6782 profile_utility_code = UtilityCode(proto="""
6783 #ifndef CYTHON_PROFILE
6784   #define CYTHON_PROFILE 1
6785 #endif
6786
6787 #ifndef CYTHON_PROFILE_REUSE_FRAME
6788   #define CYTHON_PROFILE_REUSE_FRAME 0
6789 #endif
6790
6791 #if CYTHON_PROFILE
6792
6793   #include "compile.h"
6794   #include "frameobject.h"
6795   #include "traceback.h"
6796
6797   #if CYTHON_PROFILE_REUSE_FRAME
6798     #define CYTHON_FRAME_MODIFIER static
6799     #define CYTHON_FRAME_DEL
6800   #else
6801     #define CYTHON_FRAME_MODIFIER
6802     #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6803   #endif
6804
6805   #define __Pyx_TraceDeclarations                                  \\
6806   static PyCodeObject *%(FRAME_CODE)s = NULL;                      \\
6807   CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL;           \\
6808   int __Pyx_use_tracing = 0;
6809
6810   #define __Pyx_TraceCall(funcname, srcfile, firstlineno)                            \\
6811   if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) {      \\
6812       __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno);  \\
6813   }
6814
6815   #define __Pyx_TraceException()                                                           \\
6816   if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6817       PyObject *exc_info = __Pyx_GetExceptionTuple();                                      \\
6818       if (exc_info) {                                                                      \\
6819           PyThreadState_GET()->c_profilefunc(                                              \\
6820               PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info);  \\
6821           Py_DECREF(exc_info);                                                             \\
6822       }                                                                                    \\
6823   }
6824
6825   #define __Pyx_TraceReturn(result)                                                  \\
6826   if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6827       PyThreadState_GET()->c_profilefunc(                                            \\
6828           PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result);     \\
6829       CYTHON_FRAME_DEL;                                                               \\
6830   }
6831
6832   static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6833   static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6834
6835 #else
6836
6837   #define __Pyx_TraceDeclarations
6838   #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6839   #define __Pyx_TraceException()
6840   #define __Pyx_TraceReturn(result)
6841
6842 #endif /* CYTHON_PROFILE */
6843 """
6844 % {
6845     "FRAME": Naming.frame_cname,
6846     "FRAME_CODE": Naming.frame_code_cname,
6847 },
6848 impl = """
6849
6850 #if CYTHON_PROFILE
6851
6852 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6853                                    PyFrameObject** frame,
6854                                    const char *funcname,
6855                                    const char *srcfile,
6856                                    int firstlineno) {
6857     if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6858         if (*code == NULL) {
6859             *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6860             if (*code == NULL) return 0;
6861         }
6862         *frame = PyFrame_New(
6863             PyThreadState_GET(),            /*PyThreadState *tstate*/
6864             *code,                          /*PyCodeObject *code*/
6865             PyModule_GetDict(%(MODULE)s),      /*PyObject *globals*/
6866             0                               /*PyObject *locals*/
6867         );
6868         if (*frame == NULL) return 0;
6869     }
6870     else {
6871         (*frame)->f_tstate = PyThreadState_GET();
6872     }
6873     return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6874 }
6875
6876 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6877     PyObject *py_srcfile = 0;
6878     PyObject *py_funcname = 0;
6879     PyCodeObject *py_code = 0;
6880
6881     #if PY_MAJOR_VERSION < 3
6882     py_funcname = PyString_FromString(funcname);
6883     py_srcfile = PyString_FromString(srcfile);
6884     #else
6885     py_funcname = PyUnicode_FromString(funcname);
6886     py_srcfile = PyUnicode_FromString(srcfile);
6887     #endif
6888     if (!py_funcname | !py_srcfile) goto bad;
6889
6890     py_code = PyCode_New(
6891         0,                /*int argcount,*/
6892         #if PY_MAJOR_VERSION >= 3
6893         0,                /*int kwonlyargcount,*/
6894         #endif
6895         0,                /*int nlocals,*/
6896         0,                /*int stacksize,*/
6897         0,                /*int flags,*/
6898         %(EMPTY_BYTES)s,  /*PyObject *code,*/
6899         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6900         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6901         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6902         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6903         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6904         py_srcfile,       /*PyObject *filename,*/
6905         py_funcname,      /*PyObject *name,*/
6906         firstlineno,      /*int firstlineno,*/
6907         %(EMPTY_BYTES)s   /*PyObject *lnotab*/
6908     );
6909
6910 bad:
6911     Py_XDECREF(py_srcfile);
6912     Py_XDECREF(py_funcname);
6913
6914     return py_code;
6915 }
6916
6917 #endif /* CYTHON_PROFILE */
6918 """ % {
6919     'EMPTY_TUPLE' : Naming.empty_tuple,
6920     'EMPTY_BYTES' : Naming.empty_bytes,
6921     "MODULE": Naming.module_cname,
6922 })