move 'with' statement implementation back into WithTransform to fix 'with' statement...
[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
4158     child_attrs = ["exc_type", "exc_value", "exc_tb"]
4159
4160     def analyse_expressions(self, env):
4161         if self.exc_type:
4162             self.exc_type.analyse_types(env)
4163             self.exc_type = self.exc_type.coerce_to_pyobject(env)
4164         if self.exc_value:
4165             self.exc_value.analyse_types(env)
4166             self.exc_value = self.exc_value.coerce_to_pyobject(env)
4167         if self.exc_tb:
4168             self.exc_tb.analyse_types(env)
4169             self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4170         # special cases for builtin exceptions
4171         self.builtin_exc_name = None
4172         if self.exc_type and not self.exc_value and not self.exc_tb:
4173             exc = self.exc_type
4174             import ExprNodes
4175             if (isinstance(exc, ExprNodes.SimpleCallNode) and
4176                 not (exc.args or (exc.arg_tuple is not None and
4177                                   exc.arg_tuple.args))):
4178                 exc = exc.function # extract the exception type
4179             if exc.is_name and exc.entry.is_builtin:
4180                 self.builtin_exc_name = exc.name
4181                 if self.builtin_exc_name == 'MemoryError':
4182                     self.exc_type = None # has a separate implementation
4183
4184     nogil_check = Node.gil_error
4185     gil_message = "Raising exception"
4186
4187     def generate_execution_code(self, code):
4188         if self.builtin_exc_name == 'MemoryError':
4189             code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos))
4190             return
4191
4192         if self.exc_type:
4193             self.exc_type.generate_evaluation_code(code)
4194             type_code = self.exc_type.py_result()
4195         else:
4196             type_code = "0"
4197         if self.exc_value:
4198             self.exc_value.generate_evaluation_code(code)
4199             value_code = self.exc_value.py_result()
4200         else:
4201             value_code = "0"
4202         if self.exc_tb:
4203             self.exc_tb.generate_evaluation_code(code)
4204             tb_code = self.exc_tb.py_result()
4205         else:
4206             tb_code = "0"
4207         code.globalstate.use_utility_code(raise_utility_code)
4208         code.putln(
4209             "__Pyx_Raise(%s, %s, %s);" % (
4210                 type_code,
4211                 value_code,
4212                 tb_code))
4213         for obj in (self.exc_type, self.exc_value, self.exc_tb):
4214             if obj:
4215                 obj.generate_disposal_code(code)
4216                 obj.free_temps(code)
4217         code.putln(
4218             code.error_goto(self.pos))
4219
4220     def generate_function_definitions(self, env, code):
4221         if self.exc_type is not None:
4222             self.exc_type.generate_function_definitions(env, code)
4223         if self.exc_value is not None:
4224             self.exc_value.generate_function_definitions(env, code)
4225         if self.exc_tb is not None:
4226             self.exc_tb.generate_function_definitions(env, code)
4227
4228     def annotate(self, code):
4229         if self.exc_type:
4230             self.exc_type.annotate(code)
4231         if self.exc_value:
4232             self.exc_value.annotate(code)
4233         if self.exc_tb:
4234             self.exc_tb.annotate(code)
4235
4236
4237 class ReraiseStatNode(StatNode):
4238
4239     child_attrs = []
4240
4241     def analyse_expressions(self, env):
4242         env.use_utility_code(restore_exception_utility_code)
4243
4244     nogil_check = Node.gil_error
4245     gil_message = "Raising exception"
4246
4247     def generate_execution_code(self, code):
4248         vars = code.funcstate.exc_vars
4249         if vars:
4250             for varname in vars:
4251                 code.put_giveref(varname)
4252             code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4253             for varname in vars:
4254                 code.put("%s = 0; " % varname)
4255             code.putln()
4256             code.putln(code.error_goto(self.pos))
4257         else:
4258             error(self.pos, "Reraise not inside except clause")
4259
4260
4261 class AssertStatNode(StatNode):
4262     #  assert statement
4263     #
4264     #  cond    ExprNode
4265     #  value   ExprNode or None
4266
4267     child_attrs = ["cond", "value"]
4268
4269     def analyse_expressions(self, env):
4270         self.cond = self.cond.analyse_boolean_expression(env)
4271         if self.value:
4272             self.value.analyse_types(env)
4273             self.value = self.value.coerce_to_pyobject(env)
4274
4275     nogil_check = Node.gil_error
4276     gil_message = "Raising exception"
4277
4278     def generate_execution_code(self, code):
4279         code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4280         self.cond.generate_evaluation_code(code)
4281         code.putln(
4282             "if (unlikely(!%s)) {" %
4283                 self.cond.result())
4284         if self.value:
4285             self.value.generate_evaluation_code(code)
4286             code.putln(
4287                 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4288                     self.value.py_result())
4289             self.value.generate_disposal_code(code)
4290             self.value.free_temps(code)
4291         else:
4292             code.putln(
4293                 "PyErr_SetNone(PyExc_AssertionError);")
4294         code.putln(
4295                 code.error_goto(self.pos))
4296         code.putln(
4297             "}")
4298         self.cond.generate_disposal_code(code)
4299         self.cond.free_temps(code)
4300         code.putln("#endif")
4301
4302     def generate_function_definitions(self, env, code):
4303         self.cond.generate_function_definitions(env, code)
4304         if self.value is not None:
4305             self.value.generate_function_definitions(env, code)
4306
4307     def annotate(self, code):
4308         self.cond.annotate(code)
4309         if self.value:
4310             self.value.annotate(code)
4311
4312
4313 class IfStatNode(StatNode):
4314     #  if statement
4315     #
4316     #  if_clauses   [IfClauseNode]
4317     #  else_clause  StatNode or None
4318
4319     child_attrs = ["if_clauses", "else_clause"]
4320
4321     def analyse_control_flow(self, env):
4322         env.start_branching(self.pos)
4323         for if_clause in self.if_clauses:
4324             if_clause.analyse_control_flow(env)
4325             env.next_branch(if_clause.end_pos())
4326         if self.else_clause:
4327             self.else_clause.analyse_control_flow(env)
4328         env.finish_branching(self.end_pos())
4329
4330     def analyse_declarations(self, env):
4331         for if_clause in self.if_clauses:
4332             if_clause.analyse_declarations(env)
4333         if self.else_clause:
4334             self.else_clause.analyse_declarations(env)
4335
4336     def analyse_expressions(self, env):
4337         for if_clause in self.if_clauses:
4338             if_clause.analyse_expressions(env)
4339         if self.else_clause:
4340             self.else_clause.analyse_expressions(env)
4341
4342     def generate_execution_code(self, code):
4343         code.mark_pos(self.pos)
4344         end_label = code.new_label()
4345         for if_clause in self.if_clauses:
4346             if_clause.generate_execution_code(code, end_label)
4347         if self.else_clause:
4348             code.putln("/*else*/ {")
4349             self.else_clause.generate_execution_code(code)
4350             code.putln("}")
4351         code.put_label(end_label)
4352
4353     def generate_function_definitions(self, env, code):
4354         for clause in self.if_clauses:
4355             clause.generate_function_definitions(env, code)
4356         if self.else_clause is not None:
4357             self.else_clause.generate_function_definitions(env, code)
4358
4359     def annotate(self, code):
4360         for if_clause in self.if_clauses:
4361             if_clause.annotate(code)
4362         if self.else_clause:
4363             self.else_clause.annotate(code)
4364
4365
4366 class IfClauseNode(Node):
4367     #  if or elif clause in an if statement
4368     #
4369     #  condition   ExprNode
4370     #  body        StatNode
4371
4372     child_attrs = ["condition", "body"]
4373
4374     def analyse_control_flow(self, env):
4375         self.body.analyse_control_flow(env)
4376
4377     def analyse_declarations(self, env):
4378         self.body.analyse_declarations(env)
4379
4380     def analyse_expressions(self, env):
4381         self.condition = \
4382             self.condition.analyse_temp_boolean_expression(env)
4383         self.body.analyse_expressions(env)
4384
4385     def get_constant_condition_result(self):
4386         if self.condition.has_constant_result():
4387             return bool(self.condition.constant_result)
4388         else:
4389             return None
4390
4391     def generate_execution_code(self, code, end_label):
4392         self.condition.generate_evaluation_code(code)
4393         code.putln(
4394             "if (%s) {" %
4395                 self.condition.result())
4396         self.condition.generate_disposal_code(code)
4397         self.condition.free_temps(code)
4398         self.body.generate_execution_code(code)
4399         code.put_goto(end_label)
4400         code.putln("}")
4401
4402     def generate_function_definitions(self, env, code):
4403         self.condition.generate_function_definitions(env, code)
4404         self.body.generate_function_definitions(env, code)
4405
4406     def annotate(self, code):
4407         self.condition.annotate(code)
4408         self.body.annotate(code)
4409
4410
4411 class SwitchCaseNode(StatNode):
4412     # Generated in the optimization of an if-elif-else node
4413     #
4414     # conditions    [ExprNode]
4415     # body          StatNode
4416
4417     child_attrs = ['conditions', 'body']
4418
4419     def generate_execution_code(self, code):
4420         for cond in self.conditions:
4421             code.mark_pos(cond.pos)
4422             cond.generate_evaluation_code(code)
4423             code.putln("case %s:" % cond.result())
4424         self.body.generate_execution_code(code)
4425         code.putln("break;")
4426
4427     def generate_function_definitions(self, env, code):
4428         for cond in self.conditions:
4429             cond.generate_function_definitions(env, code)
4430         self.body.generate_function_definitions(env, code)
4431
4432     def annotate(self, code):
4433         for cond in self.conditions:
4434             cond.annotate(code)
4435         self.body.annotate(code)
4436
4437 class SwitchStatNode(StatNode):
4438     # Generated in the optimization of an if-elif-else node
4439     #
4440     # test          ExprNode
4441     # cases         [SwitchCaseNode]
4442     # else_clause   StatNode or None
4443
4444     child_attrs = ['test', 'cases', 'else_clause']
4445
4446     def generate_execution_code(self, code):
4447         self.test.generate_evaluation_code(code)
4448         code.putln("switch (%s) {" % self.test.result())
4449         for case in self.cases:
4450             case.generate_execution_code(code)
4451         if self.else_clause is not None:
4452             code.putln("default:")
4453             self.else_clause.generate_execution_code(code)
4454             code.putln("break;")
4455         code.putln("}")
4456
4457     def generate_function_definitions(self, env, code):
4458         self.test.generate_function_definitions(env, code)
4459         for case in self.cases:
4460             case.generate_function_definitions(env, code)
4461         if self.else_clause is not None:
4462             self.else_clause.generate_function_definitions(env, code)
4463
4464     def annotate(self, code):
4465         self.test.annotate(code)
4466         for case in self.cases:
4467             case.annotate(code)
4468         if self.else_clause is not None:
4469             self.else_clause.annotate(code)
4470
4471 class LoopNode(object):
4472
4473     def analyse_control_flow(self, env):
4474         env.start_branching(self.pos)
4475         self.body.analyse_control_flow(env)
4476         env.next_branch(self.body.end_pos())
4477         if self.else_clause:
4478             self.else_clause.analyse_control_flow(env)
4479         env.finish_branching(self.end_pos())
4480
4481
4482 class WhileStatNode(LoopNode, StatNode):
4483     #  while statement
4484     #
4485     #  condition    ExprNode
4486     #  body         StatNode
4487     #  else_clause  StatNode
4488
4489     child_attrs = ["condition", "body", "else_clause"]
4490
4491     def analyse_declarations(self, env):
4492         self.body.analyse_declarations(env)
4493         if self.else_clause:
4494             self.else_clause.analyse_declarations(env)
4495
4496     def analyse_expressions(self, env):
4497         self.condition = \
4498             self.condition.analyse_temp_boolean_expression(env)
4499         self.body.analyse_expressions(env)
4500         if self.else_clause:
4501             self.else_clause.analyse_expressions(env)
4502
4503     def generate_execution_code(self, code):
4504         old_loop_labels = code.new_loop_labels()
4505         code.putln(
4506             "while (1) {")
4507         self.condition.generate_evaluation_code(code)
4508         self.condition.generate_disposal_code(code)
4509         code.putln(
4510             "if (!%s) break;" %
4511                 self.condition.result())
4512         self.condition.free_temps(code)
4513         self.body.generate_execution_code(code)
4514         code.put_label(code.continue_label)
4515         code.putln("}")
4516         break_label = code.break_label
4517         code.set_loop_labels(old_loop_labels)
4518         if self.else_clause:
4519             code.putln("/*else*/ {")
4520             self.else_clause.generate_execution_code(code)
4521             code.putln("}")
4522         code.put_label(break_label)
4523
4524     def generate_function_definitions(self, env, code):
4525         self.condition.generate_function_definitions(env, code)
4526         self.body.generate_function_definitions(env, code)
4527         if self.else_clause is not None:
4528             self.else_clause.generate_function_definitions(env, code)
4529
4530     def annotate(self, code):
4531         self.condition.annotate(code)
4532         self.body.annotate(code)
4533         if self.else_clause:
4534             self.else_clause.annotate(code)
4535
4536
4537 def ForStatNode(pos, **kw):
4538     if 'iterator' in kw:
4539         return ForInStatNode(pos, **kw)
4540     else:
4541         return ForFromStatNode(pos, **kw)
4542
4543 class ForInStatNode(LoopNode, StatNode):
4544     #  for statement
4545     #
4546     #  target        ExprNode
4547     #  iterator      IteratorNode
4548     #  body          StatNode
4549     #  else_clause   StatNode
4550     #  item          NextNode       used internally
4551
4552     child_attrs = ["target", "iterator", "body", "else_clause"]
4553     item = None
4554
4555     def analyse_declarations(self, env):
4556         self.target.analyse_target_declaration(env)
4557         self.body.analyse_declarations(env)
4558         if self.else_clause:
4559             self.else_clause.analyse_declarations(env)
4560
4561     def analyse_expressions(self, env):
4562         import ExprNodes
4563         self.target.analyse_target_types(env)
4564         self.iterator.analyse_expressions(env)
4565         self.item = ExprNodes.NextNode(self.iterator, env)
4566         if (self.iterator.type.is_ptr or self.iterator.type.is_array) and \
4567             self.target.type.assignable_from(self.iterator.type):
4568             # C array slice optimization.
4569             pass
4570         else:
4571             self.item = self.item.coerce_to(self.target.type, env)
4572         self.body.analyse_expressions(env)
4573         if self.else_clause:
4574             self.else_clause.analyse_expressions(env)
4575
4576     def generate_execution_code(self, code):
4577         old_loop_labels = code.new_loop_labels()
4578         self.iterator.allocate_counter_temp(code)
4579         self.iterator.generate_evaluation_code(code)
4580         code.putln(
4581             "for (;;) {")
4582         self.item.generate_evaluation_code(code)
4583         self.target.generate_assignment_code(self.item, code)
4584         self.body.generate_execution_code(code)
4585         code.put_label(code.continue_label)
4586         code.putln(
4587             "}")
4588         break_label = code.break_label
4589         code.set_loop_labels(old_loop_labels)
4590
4591         if self.else_clause:
4592             # in nested loops, the 'else' block can contain a
4593             # 'continue' statement for the outer loop, but we may need
4594             # to generate cleanup code before taking that path, so we
4595             # intercept it here
4596             orig_continue_label = code.continue_label
4597             code.continue_label = code.new_label('outer_continue')
4598
4599             code.putln("/*else*/ {")
4600             self.else_clause.generate_execution_code(code)
4601             code.putln("}")
4602
4603             if code.label_used(code.continue_label):
4604                 code.put_goto(break_label)
4605                 code.put_label(code.continue_label)
4606                 self.iterator.generate_disposal_code(code)
4607                 code.put_goto(orig_continue_label)
4608             code.set_loop_labels(old_loop_labels)
4609
4610         if code.label_used(break_label):
4611             code.put_label(break_label)
4612         self.iterator.release_counter_temp(code)
4613         self.iterator.generate_disposal_code(code)
4614         self.iterator.free_temps(code)
4615
4616     def generate_function_definitions(self, env, code):
4617         self.target.generate_function_definitions(env, code)
4618         self.iterator.generate_function_definitions(env, code)
4619         self.body.generate_function_definitions(env, code)
4620         if self.else_clause is not None:
4621             self.else_clause.generate_function_definitions(env, code)
4622
4623     def annotate(self, code):
4624         self.target.annotate(code)
4625         self.iterator.annotate(code)
4626         self.body.annotate(code)
4627         if self.else_clause:
4628             self.else_clause.annotate(code)
4629         self.item.annotate(code)
4630
4631
4632 class ForFromStatNode(LoopNode, StatNode):
4633     #  for name from expr rel name rel expr
4634     #
4635     #  target        NameNode
4636     #  bound1        ExprNode
4637     #  relation1     string
4638     #  relation2     string
4639     #  bound2        ExprNode
4640     #  step          ExprNode or None
4641     #  body          StatNode
4642     #  else_clause   StatNode or None
4643     #
4644     #  Used internally:
4645     #
4646     #  from_range         bool
4647     #  is_py_target       bool
4648     #  loopvar_node       ExprNode (usually a NameNode or temp node)
4649     #  py_loopvar_node    PyTempNode or None
4650     child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4651
4652     is_py_target = False
4653     loopvar_node = None
4654     py_loopvar_node = None
4655     from_range = False
4656
4657     gil_message = "For-loop using object bounds or target"
4658
4659     def nogil_check(self, env):
4660         for x in (self.target, self.bound1, self.bound2):
4661             if x.type.is_pyobject:
4662                 self.gil_error()
4663
4664     def analyse_declarations(self, env):
4665         self.target.analyse_target_declaration(env)
4666         self.body.analyse_declarations(env)
4667         if self.else_clause:
4668             self.else_clause.analyse_declarations(env)
4669
4670     def analyse_expressions(self, env):
4671         import ExprNodes
4672         self.target.analyse_target_types(env)
4673         self.bound1.analyse_types(env)
4674         self.bound2.analyse_types(env)
4675         if self.step is not None:
4676             if isinstance(self.step, ExprNodes.UnaryMinusNode):
4677                 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4678             self.step.analyse_types(env)
4679
4680         target_type = self.target.type
4681         if self.target.type.is_numeric:
4682             loop_type = self.target.type
4683         else:
4684             loop_type = PyrexTypes.c_int_type
4685             if not self.bound1.type.is_pyobject:
4686                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4687             if not self.bound2.type.is_pyobject:
4688                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4689             if self.step is not None and not self.step.type.is_pyobject:
4690                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4691         self.bound1 = self.bound1.coerce_to(loop_type, env)
4692         self.bound2 = self.bound2.coerce_to(loop_type, env)
4693         if not self.bound2.is_literal:
4694             self.bound2 = self.bound2.coerce_to_temp(env)
4695         if self.step is not None:
4696             self.step = self.step.coerce_to(loop_type, env)
4697             if not self.step.is_literal:
4698                 self.step = self.step.coerce_to_temp(env)
4699
4700         target_type = self.target.type
4701         if not (target_type.is_pyobject or target_type.is_numeric):
4702             error(self.target.pos,
4703                 "for-from loop variable must be c numeric type or Python object")
4704         if target_type.is_numeric:
4705             self.is_py_target = False
4706             if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4707                 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4708             self.loopvar_node = self.target
4709             self.py_loopvar_node = None
4710         else:
4711             self.is_py_target = True
4712             c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4713             self.loopvar_node = c_loopvar_node
4714             self.py_loopvar_node = \
4715                 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4716         self.body.analyse_expressions(env)
4717         if self.else_clause:
4718             self.else_clause.analyse_expressions(env)
4719
4720     def generate_execution_code(self, code):
4721         old_loop_labels = code.new_loop_labels()
4722         from_range = self.from_range
4723         self.bound1.generate_evaluation_code(code)
4724         self.bound2.generate_evaluation_code(code)
4725         offset, incop = self.relation_table[self.relation1]
4726         if self.step is not None:
4727             self.step.generate_evaluation_code(code)
4728             step = self.step.result()
4729             incop = "%s=%s" % (incop[0], step)
4730         import ExprNodes
4731         if isinstance(self.loopvar_node, ExprNodes.TempNode):
4732             self.loopvar_node.allocate(code)
4733         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4734             self.py_loopvar_node.allocate(code)
4735         if from_range:
4736             loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4737         else:
4738             loopvar_name = self.loopvar_node.result()
4739         code.putln(
4740             "for (%s = %s%s; %s %s %s; %s%s) {" % (
4741                 loopvar_name,
4742                 self.bound1.result(), offset,
4743                 loopvar_name, self.relation2, self.bound2.result(),
4744                 loopvar_name, incop))
4745         if self.py_loopvar_node:
4746             self.py_loopvar_node.generate_evaluation_code(code)
4747             self.target.generate_assignment_code(self.py_loopvar_node, code)
4748         elif from_range:
4749             code.putln("%s = %s;" % (
4750                             self.target.result(), loopvar_name))
4751         self.body.generate_execution_code(code)
4752         code.put_label(code.continue_label)
4753         if self.py_loopvar_node:
4754             # This mess is to make for..from loops with python targets behave
4755             # exactly like those with C targets with regards to re-assignment
4756             # of the loop variable.
4757             import ExprNodes
4758             if self.target.entry.is_pyglobal:
4759                 # We know target is a NameNode, this is the only ugly case.
4760                 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4761                 target_node.allocate(code)
4762                 interned_cname = code.intern_identifier(self.target.entry.name)
4763                 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4764                 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4765                                 target_node.result(),
4766                                 Naming.module_cname,
4767                                 interned_cname,
4768                                 code.error_goto_if_null(target_node.result(), self.target.pos)))
4769                 code.put_gotref(target_node.result())
4770             else:
4771                 target_node = self.target
4772             from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4773             from_py_node.temp_code = loopvar_name
4774             from_py_node.generate_result_code(code)
4775             if self.target.entry.is_pyglobal:
4776                 code.put_decref(target_node.result(), target_node.type)
4777                 target_node.release(code)
4778         code.putln("}")
4779         if self.py_loopvar_node:
4780             # This is potentially wasteful, but we don't want the semantics to
4781             # depend on whether or not the loop is a python type.
4782             self.py_loopvar_node.generate_evaluation_code(code)
4783             self.target.generate_assignment_code(self.py_loopvar_node, code)
4784         if from_range:
4785             code.funcstate.release_temp(loopvar_name)
4786         break_label = code.break_label
4787         code.set_loop_labels(old_loop_labels)
4788         if self.else_clause:
4789             code.putln("/*else*/ {")
4790             self.else_clause.generate_execution_code(code)
4791             code.putln("}")
4792         code.put_label(break_label)
4793         self.bound1.generate_disposal_code(code)
4794         self.bound1.free_temps(code)
4795         self.bound2.generate_disposal_code(code)
4796         self.bound2.free_temps(code)
4797         if isinstance(self.loopvar_node, ExprNodes.TempNode):
4798             self.loopvar_node.release(code)
4799         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4800             self.py_loopvar_node.release(code)
4801         if self.step is not None:
4802             self.step.generate_disposal_code(code)
4803             self.step.free_temps(code)
4804
4805     relation_table = {
4806         # {relop : (initial offset, increment op)}
4807         '<=': ("",   "++"),
4808         '<' : ("+1", "++"),
4809         '>=': ("",   "--"),
4810         '>' : ("-1", "--")
4811     }
4812
4813     def generate_function_definitions(self, env, code):
4814         self.target.generate_function_definitions(env, code)
4815         self.bound1.generate_function_definitions(env, code)
4816         self.bound2.generate_function_definitions(env, code)
4817         if self.step is not None:
4818             self.step.generate_function_definitions(env, code)
4819         self.body.generate_function_definitions(env, code)
4820         if self.else_clause is not None:
4821             self.else_clause.generate_function_definitions(env, code)
4822
4823     def annotate(self, code):
4824         self.target.annotate(code)
4825         self.bound1.annotate(code)
4826         self.bound2.annotate(code)
4827         if self.step:
4828             self.step.annotate(code)
4829         self.body.annotate(code)
4830         if self.else_clause:
4831             self.else_clause.annotate(code)
4832
4833
4834 class WithStatNode(StatNode):
4835     """
4836     Represents a Python with statement.
4837
4838     Implemented by the WithTransform as follows:
4839
4840         MGR = EXPR
4841         EXIT = MGR.__exit__
4842         VALUE = MGR.__enter__()
4843         EXC = True
4844         try:
4845             try:
4846                 TARGET = VALUE  # optional
4847                 BODY
4848             except:
4849                 EXC = False
4850                 if not EXIT(*EXCINFO):
4851                     raise
4852         finally:
4853             if EXC:
4854                 EXIT(None, None, None)
4855             MGR = EXIT = VALUE = None
4856     """
4857     #  manager          The with statement manager object
4858     #  target           ExprNode  the target lhs of the __enter__() call
4859     #  body             StatNode
4860
4861     child_attrs = ["manager", "target", "body"]
4862
4863     has_target = False
4864
4865     def analyse_declarations(self, env):
4866         self.manager.analyse_declarations(env)
4867         self.body.analyse_declarations(env)
4868
4869     def analyse_expressions(self, env):
4870         self.manager.analyse_types(env)
4871         self.body.analyse_expressions(env)
4872
4873     def generate_execution_code(self, code):
4874         code.putln("/*with:*/ {")
4875         self.manager.generate_evaluation_code(code)
4876         self.exit_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
4877         code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
4878             self.exit_var,
4879             self.manager.py_result(),
4880             code.get_py_string_const(EncodedString('__exit__'), identifier=True),
4881             code.error_goto_if_null(self.exit_var, self.pos),
4882             ))
4883         code.put_gotref(self.exit_var)
4884
4885         # need to free exit_var in the face of exceptions during setup
4886         old_error_label = code.new_error_label()
4887         intermediate_error_label = code.error_label
4888
4889         enter_func = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
4890         code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
4891             enter_func,
4892             self.manager.py_result(),
4893             code.get_py_string_const(EncodedString('__enter__'), identifier=True),
4894             code.error_goto_if_null(enter_func, self.pos),
4895             ))
4896         code.put_gotref(enter_func)
4897         self.manager.generate_disposal_code(code)
4898         self.manager.free_temps(code)
4899         self.target_temp.allocate(code)
4900         code.putln('%s = PyObject_Call(%s, ((PyObject *)%s), NULL); %s' % (
4901             self.target_temp.result(),
4902             enter_func,
4903             Naming.empty_tuple,
4904             code.error_goto_if_null(self.target_temp.result(), self.pos),
4905             ))
4906         code.put_gotref(self.target_temp.result())
4907         code.put_decref_clear(enter_func, py_object_type)
4908         code.funcstate.release_temp(enter_func)
4909         if not self.has_target:
4910             code.put_decref_clear(self.target_temp.result(), type=py_object_type)
4911             self.target_temp.release(code)
4912             # otherwise, WithTargetAssignmentStatNode will do it for us
4913
4914         code.error_label = old_error_label
4915         self.body.generate_execution_code(code)
4916
4917         step_over_label = code.new_label()
4918         code.put_goto(step_over_label)
4919         code.put_label(intermediate_error_label)
4920         code.put_decref_clear(self.exit_var, py_object_type)
4921         code.put_goto(old_error_label)
4922         code.put_label(step_over_label)
4923
4924         code.funcstate.release_temp(self.exit_var)
4925         code.putln('}')
4926
4927 class WithTargetAssignmentStatNode(AssignmentNode):
4928     # The target assignment of the 'with' statement value (return
4929     # value of the __enter__() call).
4930     #
4931     # This is a special cased assignment that steals the RHS reference
4932     # and frees its temp.
4933     #
4934     # lhs  ExprNode  the assignment target
4935     # rhs  TempNode  the return value of the __enter__() call
4936
4937     child_attrs = ["lhs", "rhs"]
4938
4939     def analyse_declarations(self, env):
4940         self.lhs.analyse_target_declaration(env)
4941
4942     def analyse_types(self, env):
4943         self.rhs.analyse_types(env)
4944         self.lhs.analyse_target_types(env)
4945         self.lhs.gil_assignment_check(env)
4946         self.orig_rhs = self.rhs
4947         self.rhs = self.rhs.coerce_to(self.lhs.type, env)
4948
4949     def generate_execution_code(self, code):
4950         self.rhs.generate_evaluation_code(code)
4951         self.lhs.generate_assignment_code(self.rhs, code)
4952         self.orig_rhs.release(code)
4953
4954     def generate_function_definitions(self, env, code):
4955         self.rhs.generate_function_definitions(env, code)
4956
4957     def annotate(self, code):
4958         self.lhs.annotate(code)
4959         self.rhs.annotate(code)
4960
4961
4962 class TryExceptStatNode(StatNode):
4963     #  try .. except statement
4964     #
4965     #  body             StatNode
4966     #  except_clauses   [ExceptClauseNode]
4967     #  else_clause      StatNode or None
4968
4969     child_attrs = ["body", "except_clauses", "else_clause"]
4970
4971     def analyse_control_flow(self, env):
4972         env.start_branching(self.pos)
4973         self.body.analyse_control_flow(env)
4974         successful_try = env.control_flow # grab this for later
4975         env.next_branch(self.body.end_pos())
4976         env.finish_branching(self.body.end_pos())
4977
4978         env.start_branching(self.except_clauses[0].pos)
4979         for except_clause in self.except_clauses:
4980             except_clause.analyse_control_flow(env)
4981             env.next_branch(except_clause.end_pos())
4982
4983         # the else cause it executed only when the try clause finishes
4984         env.control_flow.incoming = successful_try
4985         if self.else_clause:
4986             self.else_clause.analyse_control_flow(env)
4987         env.finish_branching(self.end_pos())
4988
4989     def analyse_declarations(self, env):
4990         self.body.analyse_declarations(env)
4991         for except_clause in self.except_clauses:
4992             except_clause.analyse_declarations(env)
4993         if self.else_clause:
4994             self.else_clause.analyse_declarations(env)
4995         env.use_utility_code(reset_exception_utility_code)
4996
4997     def analyse_expressions(self, env):
4998         self.body.analyse_expressions(env)
4999         default_clause_seen = 0
5000         for except_clause in self.except_clauses:
5001             except_clause.analyse_expressions(env)
5002             if default_clause_seen:
5003                 error(except_clause.pos, "default 'except:' must be last")
5004             if not except_clause.pattern:
5005                 default_clause_seen = 1
5006         self.has_default_clause = default_clause_seen
5007         if self.else_clause:
5008             self.else_clause.analyse_expressions(env)
5009
5010     nogil_check = Node.gil_error
5011     gil_message = "Try-except statement"
5012
5013     def generate_execution_code(self, code):
5014         old_return_label = code.return_label
5015         old_break_label = code.break_label
5016         old_continue_label = code.continue_label
5017         old_error_label = code.new_error_label()
5018         our_error_label = code.error_label
5019         except_end_label = code.new_label('exception_handled')
5020         except_error_label = code.new_label('except_error')
5021         except_return_label = code.new_label('except_return')
5022         try_return_label = code.new_label('try_return')
5023         try_break_label = code.new_label('try_break')
5024         try_continue_label = code.new_label('try_continue')
5025         try_end_label = code.new_label('try_end')
5026
5027         exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
5028                          for i in xrange(3)]
5029         code.putln("{")
5030         code.putln("__Pyx_ExceptionSave(%s);" %
5031                    ', '.join(['&%s' % var for var in exc_save_vars]))
5032         for var in exc_save_vars:
5033             code.put_xgotref(var)
5034         code.putln(
5035             "/*try:*/ {")
5036         code.return_label = try_return_label
5037         code.break_label = try_break_label
5038         code.continue_label = try_continue_label
5039         self.body.generate_execution_code(code)
5040         code.putln(
5041             "}")
5042         temps_to_clean_up = code.funcstate.all_free_managed_temps()
5043         code.error_label = except_error_label
5044         code.return_label = except_return_label
5045         if self.else_clause:
5046             code.putln(
5047                 "/*else:*/ {")
5048             self.else_clause.generate_execution_code(code)
5049             code.putln(
5050                 "}")
5051         for var in exc_save_vars:
5052             code.put_xdecref_clear(var, py_object_type)
5053         code.put_goto(try_end_label)
5054         if code.label_used(try_return_label):
5055             code.put_label(try_return_label)
5056             for var in exc_save_vars:
5057                 code.put_xgiveref(var)
5058             code.putln("__Pyx_ExceptionReset(%s);" %
5059                        ', '.join(exc_save_vars))
5060             code.put_goto(old_return_label)
5061         code.put_label(our_error_label)
5062         for temp_name, type in temps_to_clean_up:
5063             code.put_xdecref_clear(temp_name, type)
5064         for except_clause in self.except_clauses:
5065             except_clause.generate_handling_code(code, except_end_label)
5066
5067         error_label_used = code.label_used(except_error_label)
5068         if error_label_used or not self.has_default_clause:
5069             if error_label_used:
5070                 code.put_label(except_error_label)
5071             for var in exc_save_vars:
5072                 code.put_xgiveref(var)
5073             code.putln("__Pyx_ExceptionReset(%s);" %
5074                        ', '.join(exc_save_vars))
5075             code.put_goto(old_error_label)
5076
5077         for exit_label, old_label in zip(
5078             [try_break_label, try_continue_label, except_return_label],
5079             [old_break_label, old_continue_label, old_return_label]):
5080
5081             if code.label_used(exit_label):
5082                 code.put_label(exit_label)
5083                 for var in exc_save_vars:
5084                     code.put_xgiveref(var)
5085                 code.putln("__Pyx_ExceptionReset(%s);" %
5086                            ', '.join(exc_save_vars))
5087                 code.put_goto(old_label)
5088
5089         if code.label_used(except_end_label):
5090             code.put_label(except_end_label)
5091             for var in exc_save_vars:
5092                 code.put_xgiveref(var)
5093             code.putln("__Pyx_ExceptionReset(%s);" %
5094                        ', '.join(exc_save_vars))
5095         code.put_label(try_end_label)
5096         code.putln("}")
5097
5098         for cname in exc_save_vars:
5099             code.funcstate.release_temp(cname)
5100
5101         code.return_label = old_return_label
5102         code.break_label = old_break_label
5103         code.continue_label = old_continue_label
5104         code.error_label = old_error_label
5105
5106     def generate_function_definitions(self, env, code):
5107         self.body.generate_function_definitions(env, code)
5108         for except_clause in self.except_clauses:
5109             except_clause.generate_function_definitions(env, code)
5110         if self.else_clause is not None:
5111             self.else_clause.generate_function_definitions(env, code)
5112
5113     def annotate(self, code):
5114         self.body.annotate(code)
5115         for except_node in self.except_clauses:
5116             except_node.annotate(code)
5117         if self.else_clause:
5118             self.else_clause.annotate(code)
5119
5120
5121 class ExceptClauseNode(Node):
5122     #  Part of try ... except statement.
5123     #
5124     #  pattern        [ExprNode]
5125     #  target         ExprNode or None
5126     #  body           StatNode
5127     #  excinfo_target ResultRefNode or None   optional target for exception info
5128     #  match_flag     string             result of exception match
5129     #  exc_value      ExcValueNode       used internally
5130     #  function_name  string             qualified name of enclosing function
5131     #  exc_vars       (string * 3)       local exception variables
5132
5133     # excinfo_target is never set by the parser, but can be set by a transform
5134     # in order to extract more extensive information about the exception as a
5135     # sys.exc_info()-style tuple into a target variable
5136
5137     child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
5138
5139     exc_value = None
5140     excinfo_target = None
5141
5142     def analyse_declarations(self, env):
5143         if self.target:
5144             self.target.analyse_target_declaration(env)
5145         self.body.analyse_declarations(env)
5146
5147     def analyse_expressions(self, env):
5148         import ExprNodes
5149         genv = env.global_scope()
5150         self.function_name = env.qualified_name
5151         if self.pattern:
5152             # normalise/unpack self.pattern into a list
5153             for i, pattern in enumerate(self.pattern):
5154                 pattern.analyse_expressions(env)
5155                 self.pattern[i] = pattern.coerce_to_pyobject(env)
5156
5157         if self.target:
5158             self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
5159             self.target.analyse_target_expression(env, self.exc_value)
5160         if self.excinfo_target is not None:
5161             import ExprNodes
5162             self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
5163                 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
5164             self.excinfo_tuple.analyse_expressions(env)
5165
5166         self.body.analyse_expressions(env)
5167
5168     def generate_handling_code(self, code, end_label):
5169         code.mark_pos(self.pos)
5170         if self.pattern:
5171             exc_tests = []
5172             for pattern in self.pattern:
5173                 pattern.generate_evaluation_code(code)
5174                 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
5175
5176             match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
5177             code.putln(
5178                 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
5179             for pattern in self.pattern:
5180                 pattern.generate_disposal_code(code)
5181                 pattern.free_temps(code)
5182             code.putln(
5183                 "if (%s) {" %
5184                     match_flag)
5185             code.funcstate.release_temp(match_flag)
5186         else:
5187             code.putln("/*except:*/ {")
5188
5189         if not getattr(self.body, 'stats', True) and \
5190                 self.excinfo_target is None and self.target is None:
5191             # most simple case: no exception variable, empty body (pass)
5192             # => reset the exception state, done
5193             code.putln("PyErr_Restore(0,0,0);")
5194             code.put_goto(end_label)
5195             code.putln("}")
5196             return
5197
5198         exc_vars = [code.funcstate.allocate_temp(py_object_type,
5199                                                  manage_ref=True)
5200                     for i in xrange(3)]
5201         code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
5202         # We always have to fetch the exception value even if
5203         # there is no target, because this also normalises the
5204         # exception and stores it in the thread state.
5205         code.globalstate.use_utility_code(get_exception_utility_code)
5206         exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
5207         code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
5208             code.error_goto(self.pos)))
5209         for x in exc_vars:
5210             code.put_gotref(x)
5211         if self.target:
5212             self.exc_value.set_var(exc_vars[1])
5213             self.exc_value.generate_evaluation_code(code)
5214             self.target.generate_assignment_code(self.exc_value, code)
5215         if self.excinfo_target is not None:
5216             for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
5217                 node.set_var(tempvar)
5218             self.excinfo_tuple.generate_evaluation_code(code)
5219             self.excinfo_target.result_code = self.excinfo_tuple.result()
5220
5221         old_break_label, old_continue_label = code.break_label, code.continue_label
5222         code.break_label = code.new_label('except_break')
5223         code.continue_label = code.new_label('except_continue')
5224
5225         old_exc_vars = code.funcstate.exc_vars
5226         code.funcstate.exc_vars = exc_vars
5227         self.body.generate_execution_code(code)
5228         code.funcstate.exc_vars = old_exc_vars
5229         if self.excinfo_target is not None:
5230             self.excinfo_tuple.generate_disposal_code(code)
5231         for var in exc_vars:
5232             code.put_decref_clear(var, py_object_type)
5233         code.put_goto(end_label)
5234
5235         if code.label_used(code.break_label):
5236             code.put_label(code.break_label)
5237             if self.excinfo_target is not None:
5238                 self.excinfo_tuple.generate_disposal_code(code)
5239             for var in exc_vars:
5240                 code.put_decref_clear(var, py_object_type)
5241             code.put_goto(old_break_label)
5242         code.break_label = old_break_label
5243
5244         if code.label_used(code.continue_label):
5245             code.put_label(code.continue_label)
5246             if self.excinfo_target is not None:
5247                 self.excinfo_tuple.generate_disposal_code(code)
5248             for var in exc_vars:
5249                 code.put_decref_clear(var, py_object_type)
5250             code.put_goto(old_continue_label)
5251         code.continue_label = old_continue_label
5252
5253         if self.excinfo_target is not None:
5254             self.excinfo_tuple.free_temps(code)
5255         for temp in exc_vars:
5256             code.funcstate.release_temp(temp)
5257
5258         code.putln(
5259             "}")
5260
5261     def generate_function_definitions(self, env, code):
5262         if self.target is not None:
5263             self.target.generate_function_definitions(env, code)
5264         self.body.generate_function_definitions(env, code)
5265
5266     def annotate(self, code):
5267         if self.pattern:
5268             for pattern in self.pattern:
5269                 pattern.annotate(code)
5270         if self.target:
5271             self.target.annotate(code)
5272         self.body.annotate(code)
5273
5274
5275 class TryFinallyStatNode(StatNode):
5276     #  try ... finally statement
5277     #
5278     #  body             StatNode
5279     #  finally_clause   StatNode
5280     #
5281     #  The plan is that we funnel all continue, break
5282     #  return and error gotos into the beginning of the
5283     #  finally block, setting a variable to remember which
5284     #  one we're doing. At the end of the finally block, we
5285     #  switch on the variable to figure out where to go.
5286     #  In addition, if we're doing an error, we save the
5287     #  exception on entry to the finally block and restore
5288     #  it on exit.
5289
5290     child_attrs = ["body", "finally_clause"]
5291
5292     preserve_exception = 1
5293
5294     # handle exception case, in addition to return/break/continue
5295     handle_error_case = True
5296
5297     disallow_continue_in_try_finally = 0
5298     # There doesn't seem to be any point in disallowing
5299     # continue in the try block, since we have no problem
5300     # handling it.
5301
5302     def create_analysed(pos, env, body, finally_clause):
5303         node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5304         return node
5305     create_analysed = staticmethod(create_analysed)
5306
5307     def analyse_control_flow(self, env):
5308         env.start_branching(self.pos)
5309         self.body.analyse_control_flow(env)
5310         env.next_branch(self.body.end_pos())
5311         env.finish_branching(self.body.end_pos())
5312         self.finally_clause.analyse_control_flow(env)
5313
5314     def analyse_declarations(self, env):
5315         self.body.analyse_declarations(env)
5316         self.finally_clause.analyse_declarations(env)
5317
5318     def analyse_expressions(self, env):
5319         self.body.analyse_expressions(env)
5320         self.finally_clause.analyse_expressions(env)
5321
5322     nogil_check = Node.gil_error
5323     gil_message = "Try-finally statement"
5324
5325     def generate_execution_code(self, code):
5326         old_error_label = code.error_label
5327         old_labels = code.all_new_labels()
5328         new_labels = code.get_all_labels()
5329         new_error_label = code.error_label
5330         if not self.handle_error_case:
5331             code.error_label = old_error_label
5332         catch_label = code.new_label()
5333         code.putln(
5334             "/*try:*/ {")
5335         if self.disallow_continue_in_try_finally:
5336             was_in_try_finally = code.funcstate.in_try_finally
5337             code.funcstate.in_try_finally = 1
5338         self.body.generate_execution_code(code)
5339         if self.disallow_continue_in_try_finally:
5340             code.funcstate.in_try_finally = was_in_try_finally
5341         code.putln(
5342             "}")
5343         temps_to_clean_up = code.funcstate.all_free_managed_temps()
5344         code.mark_pos(self.finally_clause.pos)
5345         code.putln(
5346             "/*finally:*/ {")
5347         cases_used = []
5348         error_label_used = 0
5349         for i, new_label in enumerate(new_labels):
5350             if new_label in code.labels_used:
5351                 cases_used.append(i)
5352                 if new_label == new_error_label:
5353                     error_label_used = 1
5354                     error_label_case = i
5355         if cases_used:
5356             code.putln(
5357                     "int __pyx_why;")
5358             if error_label_used and self.preserve_exception:
5359                 code.putln(
5360                     "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5361                 code.putln(
5362                     "int %s;" % Naming.exc_lineno_name)
5363                 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5364                 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5365                 code.putln(exc_var_init_zero)
5366             else:
5367                 exc_var_init_zero = None
5368             code.use_label(catch_label)
5369             code.putln(
5370                     "__pyx_why = 0; goto %s;" % catch_label)
5371             for i in cases_used:
5372                 new_label = new_labels[i]
5373                 #if new_label and new_label != "<try>":
5374                 if new_label == new_error_label and self.preserve_exception:
5375                     self.put_error_catcher(code,
5376                         new_error_label, i+1, catch_label, temps_to_clean_up)
5377                 else:
5378                     code.put('%s: ' % new_label)
5379                     if exc_var_init_zero:
5380                         code.putln(exc_var_init_zero)
5381                     code.putln("__pyx_why = %s; goto %s;" % (
5382                             i+1,
5383                             catch_label))
5384             code.put_label(catch_label)
5385         code.set_all_labels(old_labels)
5386         if error_label_used:
5387             code.new_error_label()
5388             finally_error_label = code.error_label
5389         self.finally_clause.generate_execution_code(code)
5390         if error_label_used:
5391             if finally_error_label in code.labels_used and self.preserve_exception:
5392                 over_label = code.new_label()
5393                 code.put_goto(over_label);
5394                 code.put_label(finally_error_label)
5395                 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5396                 for var in Naming.exc_vars:
5397                     code.putln("Py_XDECREF(%s);" % var)
5398                 code.putln("}")
5399                 code.put_goto(old_error_label)
5400                 code.put_label(over_label)
5401             code.error_label = old_error_label
5402         if cases_used:
5403             code.putln(
5404                 "switch (__pyx_why) {")
5405             for i in cases_used:
5406                 old_label = old_labels[i]
5407                 if old_label == old_error_label and self.preserve_exception:
5408                     self.put_error_uncatcher(code, i+1, old_error_label)
5409                 else:
5410                     code.use_label(old_label)
5411                     code.putln(
5412                         "case %s: goto %s;" % (
5413                             i+1,
5414                             old_label))
5415             code.putln(
5416                 "}")
5417         code.putln(
5418             "}")
5419
5420     def generate_function_definitions(self, env, code):
5421         self.body.generate_function_definitions(env, code)
5422         self.finally_clause.generate_function_definitions(env, code)
5423
5424     def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5425         code.globalstate.use_utility_code(restore_exception_utility_code)
5426         code.putln(
5427             "%s: {" %
5428                 error_label)
5429         code.putln(
5430                 "__pyx_why = %s;" %
5431                     i)
5432         for temp_name, type in temps_to_clean_up:
5433             code.put_xdecref_clear(temp_name, type)
5434         code.putln(
5435                 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5436                     Naming.exc_vars)
5437         code.putln(
5438                 "%s = %s;" % (
5439                     Naming.exc_lineno_name, Naming.lineno_cname))
5440         code.put_goto(catch_label)
5441         code.putln("}")
5442
5443     def put_error_uncatcher(self, code, i, error_label):
5444         code.globalstate.use_utility_code(restore_exception_utility_code)
5445         code.putln(
5446             "case %s: {" %
5447                 i)
5448         code.putln(
5449                 "__Pyx_ErrRestore(%s, %s, %s);" %
5450                     Naming.exc_vars)
5451         code.putln(
5452                 "%s = %s;" % (
5453                     Naming.lineno_cname, Naming.exc_lineno_name))
5454         for var in Naming.exc_vars:
5455             code.putln(
5456                 "%s = 0;" %
5457                     var)
5458         code.put_goto(error_label)
5459         code.putln(
5460             "}")
5461
5462     def annotate(self, code):
5463         self.body.annotate(code)
5464         self.finally_clause.annotate(code)
5465
5466
5467 class GILStatNode(TryFinallyStatNode):
5468     #  'with gil' or 'with nogil' statement
5469     #
5470     #   state   string   'gil' or 'nogil'
5471
5472 #    child_attrs = []
5473
5474     preserve_exception = 0
5475
5476     def __init__(self, pos, state, body):
5477         self.state = state
5478         TryFinallyStatNode.__init__(self, pos,
5479             body = body,
5480             finally_clause = GILExitNode(pos, state = state))
5481
5482     def analyse_expressions(self, env):
5483         env.use_utility_code(force_init_threads_utility_code)
5484         was_nogil = env.nogil
5485         env.nogil = 1
5486         TryFinallyStatNode.analyse_expressions(self, env)
5487         env.nogil = was_nogil
5488
5489     nogil_check = None
5490
5491     def generate_execution_code(self, code):
5492         code.mark_pos(self.pos)
5493         code.putln("{")
5494         if self.state == 'gil':
5495             code.putln("#ifdef WITH_THREAD")
5496             code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5497             code.putln("#endif")
5498         else:
5499             code.putln("#ifdef WITH_THREAD")
5500             code.putln("PyThreadState *_save = NULL;")
5501             code.putln("#endif")
5502             code.putln("Py_UNBLOCK_THREADS")
5503         TryFinallyStatNode.generate_execution_code(self, code)
5504         code.putln("}")
5505
5506
5507 class GILExitNode(StatNode):
5508     #  Used as the 'finally' block in a GILStatNode
5509     #
5510     #  state   string   'gil' or 'nogil'
5511
5512     child_attrs = []
5513
5514     def analyse_expressions(self, env):
5515         pass
5516
5517     def generate_execution_code(self, code):
5518         if self.state == 'gil':
5519             code.putln("#ifdef WITH_THREAD")
5520             code.putln("PyGILState_Release(_save);")
5521             code.putln("#endif")
5522         else:
5523             code.putln("Py_BLOCK_THREADS")
5524
5525
5526 class CImportStatNode(StatNode):
5527     #  cimport statement
5528     #
5529     #  module_name   string           Qualified name of module being imported
5530     #  as_name       string or None   Name specified in "as" clause, if any
5531
5532     child_attrs = []
5533
5534     def analyse_declarations(self, env):
5535         if not env.is_module_scope:
5536             error(self.pos, "cimport only allowed at module level")
5537             return
5538         module_scope = env.find_module(self.module_name, self.pos)
5539         if "." in self.module_name:
5540             names = [EncodedString(name) for name in self.module_name.split(".")]
5541             top_name = names[0]
5542             top_module_scope = env.context.find_submodule(top_name)
5543             module_scope = top_module_scope
5544             for name in names[1:]:
5545                 submodule_scope = module_scope.find_submodule(name)
5546                 module_scope.declare_module(name, submodule_scope, self.pos)
5547                 module_scope = submodule_scope
5548             if self.as_name:
5549                 env.declare_module(self.as_name, module_scope, self.pos)
5550             else:
5551                 env.declare_module(top_name, top_module_scope, self.pos)
5552         else:
5553             name = self.as_name or self.module_name
5554             env.declare_module(name, module_scope, self.pos)
5555
5556     def analyse_expressions(self, env):
5557         pass
5558
5559     def generate_execution_code(self, code):
5560         pass
5561
5562
5563 class FromCImportStatNode(StatNode):
5564     #  from ... cimport statement
5565     #
5566     #  module_name     string                        Qualified name of module
5567     #  imported_names  [(pos, name, as_name, kind)]  Names to be imported
5568
5569     child_attrs = []
5570
5571     def analyse_declarations(self, env):
5572         if not env.is_module_scope:
5573             error(self.pos, "cimport only allowed at module level")
5574             return
5575         module_scope = env.find_module(self.module_name, self.pos)
5576         env.add_imported_module(module_scope)
5577         for pos, name, as_name, kind in self.imported_names:
5578             if name == "*":
5579                 for local_name, entry in module_scope.entries.items():
5580                     env.add_imported_entry(local_name, entry, pos)
5581             else:
5582                 entry = module_scope.lookup(name)
5583                 if entry:
5584                     if kind and not self.declaration_matches(entry, kind):
5585                         entry.redeclared(pos)
5586                 else:
5587                     if kind == 'struct' or kind == 'union':
5588                         entry = module_scope.declare_struct_or_union(name,
5589                             kind = kind, scope = None, typedef_flag = 0, pos = pos)
5590                     elif kind == 'class':
5591                         entry = module_scope.declare_c_class(name, pos = pos,
5592                             module_name = self.module_name)
5593                     else:
5594                         submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5595                         if submodule_scope.parent_module is module_scope:
5596                             env.declare_module(as_name or name, submodule_scope, self.pos)
5597                         else:
5598                             error(pos, "Name '%s' not declared in module '%s'"
5599                                 % (name, self.module_name))
5600
5601                 if entry:
5602                     local_name = as_name or name
5603                     env.add_imported_entry(local_name, entry, pos)
5604
5605     def declaration_matches(self, entry, kind):
5606         if not entry.is_type:
5607             return 0
5608         type = entry.type
5609         if kind == 'class':
5610             if not type.is_extension_type:
5611                 return 0
5612         else:
5613             if not type.is_struct_or_union:
5614                 return 0
5615             if kind != type.kind:
5616                 return 0
5617         return 1
5618
5619     def analyse_expressions(self, env):
5620         pass
5621
5622     def generate_execution_code(self, code):
5623         pass
5624
5625
5626 class FromImportStatNode(StatNode):
5627     #  from ... import statement
5628     #
5629     #  module           ImportNode
5630     #  items            [(string, NameNode)]
5631     #  interned_items   [(string, NameNode, ExprNode)]
5632     #  item             PyTempNode            used internally
5633     #  import_star      boolean               used internally
5634
5635     child_attrs = ["module"]
5636     import_star = 0
5637
5638     def analyse_declarations(self, env):
5639         for name, target in self.items:
5640             if name == "*":
5641                 if not env.is_module_scope:
5642                     error(self.pos, "import * only allowed at module level")
5643                     return
5644                 env.has_import_star = 1
5645                 self.import_star = 1
5646             else:
5647                 target.analyse_target_declaration(env)
5648
5649     def analyse_expressions(self, env):
5650         import ExprNodes
5651         self.module.analyse_expressions(env)
5652         self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5653         self.interned_items = []
5654         for name, target in self.items:
5655             if name == '*':
5656                 for _, entry in env.entries.items():
5657                     if not entry.is_type and entry.type.is_extension_type:
5658                         env.use_utility_code(ExprNodes.type_test_utility_code)
5659                         break
5660             else:
5661                 entry =  env.lookup(target.name)
5662                 # check whether or not entry is already cimported
5663                 if (entry.is_type and entry.type.name == name
5664                     and hasattr(entry.type, 'module_name')):
5665                     if entry.type.module_name == self.module.module_name.value:
5666                         # cimported with absolute name
5667                         continue
5668                     try:
5669                         # cimported with relative name
5670                         module = env.find_module(self.module.module_name.value,
5671                                                  pos=None)
5672                         if entry.type.module_name == module.qualified_name:
5673                             continue
5674                     except AttributeError:
5675                         pass
5676                 target.analyse_target_expression(env, None)
5677                 if target.type is py_object_type:
5678                     coerced_item = None
5679                 else:
5680                     coerced_item = self.item.coerce_to(target.type, env)
5681                 self.interned_items.append((name, target, coerced_item))
5682
5683     def generate_execution_code(self, code):
5684         self.module.generate_evaluation_code(code)
5685         if self.import_star:
5686             code.putln(
5687                 'if (%s(%s) < 0) %s;' % (
5688                     Naming.import_star,
5689                     self.module.py_result(),
5690                     code.error_goto(self.pos)))
5691         item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5692         self.item.set_cname(item_temp)
5693         for name, target, coerced_item in self.interned_items:
5694             cname = code.intern_identifier(name)
5695             code.putln(
5696                 '%s = PyObject_GetAttr(%s, %s); %s' % (
5697                     item_temp,
5698                     self.module.py_result(),
5699                     cname,
5700                     code.error_goto_if_null(item_temp, self.pos)))
5701             code.put_gotref(item_temp)
5702             if coerced_item is None:
5703                 target.generate_assignment_code(self.item, code)
5704             else:
5705                 coerced_item.allocate_temp_result(code)
5706                 coerced_item.generate_result_code(code)
5707                 target.generate_assignment_code(coerced_item, code)
5708             code.put_decref_clear(item_temp, py_object_type)
5709         code.funcstate.release_temp(item_temp)
5710         self.module.generate_disposal_code(code)
5711         self.module.free_temps(code)
5712
5713
5714
5715 #------------------------------------------------------------------------------------
5716 #
5717 #  Runtime support code
5718 #
5719 #------------------------------------------------------------------------------------
5720
5721 utility_function_predeclarations = \
5722 """
5723 /* inline attribute */
5724 #ifndef CYTHON_INLINE
5725   #if defined(__GNUC__)
5726     #define CYTHON_INLINE __inline__
5727   #elif defined(_MSC_VER)
5728     #define CYTHON_INLINE __inline
5729   #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5730     #define CYTHON_INLINE inline
5731   #else
5732     #define CYTHON_INLINE
5733   #endif
5734 #endif
5735
5736 /* unused attribute */
5737 #ifndef CYTHON_UNUSED
5738 # if defined(__GNUC__)
5739 #   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5740 #     define CYTHON_UNUSED __attribute__ ((__unused__))
5741 #   else
5742 #     define CYTHON_UNUSED
5743 #   endif
5744 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5745 #   define CYTHON_UNUSED __attribute__ ((__unused__))
5746 # else
5747 #   define CYTHON_UNUSED
5748 # endif
5749 #endif
5750
5751 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*/
5752
5753 """
5754
5755 if Options.gcc_branch_hints:
5756     branch_prediction_macros = \
5757     """
5758 #ifdef __GNUC__
5759 /* Test for GCC > 2.95 */
5760 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5761 #define likely(x)   __builtin_expect(!!(x), 1)
5762 #define unlikely(x) __builtin_expect(!!(x), 0)
5763 #else /* __GNUC__ > 2 ... */
5764 #define likely(x)   (x)
5765 #define unlikely(x) (x)
5766 #endif /* __GNUC__ > 2 ... */
5767 #else /* __GNUC__ */
5768 #define likely(x)   (x)
5769 #define unlikely(x) (x)
5770 #endif /* __GNUC__ */
5771     """
5772 else:
5773     branch_prediction_macros = \
5774     """
5775 #define likely(x)   (x)
5776 #define unlikely(x) (x)
5777     """
5778
5779 #get_name_predeclaration = \
5780 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5781
5782 #get_name_interned_predeclaration = \
5783 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5784
5785 #------------------------------------------------------------------------------------
5786
5787 printing_utility_code = UtilityCode(
5788 proto = """
5789 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5790 #if PY_MAJOR_VERSION >= 3
5791 static PyObject* %s = 0;
5792 static PyObject* %s = 0;
5793 #endif
5794 """ % (Naming.print_function, Naming.print_function_kwargs),
5795 cleanup = """
5796 #if PY_MAJOR_VERSION >= 3
5797 Py_CLEAR(%s);
5798 Py_CLEAR(%s);
5799 #endif
5800 """ % (Naming.print_function, Naming.print_function_kwargs),
5801 impl = r"""
5802 #if PY_MAJOR_VERSION < 3
5803 static PyObject *__Pyx_GetStdout(void) {
5804     PyObject *f = PySys_GetObject((char *)"stdout");
5805     if (!f) {
5806         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5807     }
5808     return f;
5809 }
5810
5811 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5812     PyObject* v;
5813     int i;
5814
5815     if (!f) {
5816         if (!(f = __Pyx_GetStdout()))
5817             return -1;
5818     }
5819     for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5820         if (PyFile_SoftSpace(f, 1)) {
5821             if (PyFile_WriteString(" ", f) < 0)
5822                 return -1;
5823         }
5824         v = PyTuple_GET_ITEM(arg_tuple, i);
5825         if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5826             return -1;
5827         if (PyString_Check(v)) {
5828             char *s = PyString_AsString(v);
5829             Py_ssize_t len = PyString_Size(v);
5830             if (len > 0 &&
5831                 isspace(Py_CHARMASK(s[len-1])) &&
5832                 s[len-1] != ' ')
5833                     PyFile_SoftSpace(f, 0);
5834         }
5835     }
5836     if (newline) {
5837         if (PyFile_WriteString("\n", f) < 0)
5838             return -1;
5839         PyFile_SoftSpace(f, 0);
5840     }
5841     return 0;
5842 }
5843
5844 #else /* Python 3 has a print function */
5845
5846 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5847     PyObject* kwargs = 0;
5848     PyObject* result = 0;
5849     PyObject* end_string;
5850     if (unlikely(!%(PRINT_FUNCTION)s)) {
5851         %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5852         if (!%(PRINT_FUNCTION)s)
5853             return -1;
5854     }
5855     if (stream) {
5856         kwargs = PyDict_New();
5857         if (unlikely(!kwargs))
5858             return -1;
5859         if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5860             goto bad;
5861         if (!newline) {
5862             end_string = PyUnicode_FromStringAndSize(" ", 1);
5863             if (unlikely(!end_string))
5864                 goto bad;
5865             if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5866                 Py_DECREF(end_string);
5867                 goto bad;
5868             }
5869             Py_DECREF(end_string);
5870         }
5871     } else if (!newline) {
5872         if (unlikely(!%(PRINT_KWARGS)s)) {
5873             %(PRINT_KWARGS)s = PyDict_New();
5874             if (unlikely(!%(PRINT_KWARGS)s))
5875                 return -1;
5876             end_string = PyUnicode_FromStringAndSize(" ", 1);
5877             if (unlikely(!end_string))
5878                 return -1;
5879             if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5880                 Py_DECREF(end_string);
5881                 return -1;
5882             }
5883             Py_DECREF(end_string);
5884         }
5885         kwargs = %(PRINT_KWARGS)s;
5886     }
5887     result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5888     if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5889         Py_DECREF(kwargs);
5890     if (!result)
5891         return -1;
5892     Py_DECREF(result);
5893     return 0;
5894 bad:
5895     if (kwargs != %(PRINT_KWARGS)s)
5896         Py_XDECREF(kwargs);
5897     return -1;
5898 }
5899
5900 #endif
5901 """ % {'BUILTINS'       : Naming.builtins_cname,
5902        'PRINT_FUNCTION' : Naming.print_function,
5903        'PRINT_KWARGS'   : Naming.print_function_kwargs}
5904 )
5905
5906
5907 printing_one_utility_code = UtilityCode(
5908 proto = """
5909 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5910 """,
5911 impl = r"""
5912 #if PY_MAJOR_VERSION < 3
5913
5914 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5915     if (!f) {
5916         if (!(f = __Pyx_GetStdout()))
5917             return -1;
5918     }
5919     if (PyFile_SoftSpace(f, 0)) {
5920         if (PyFile_WriteString(" ", f) < 0)
5921             return -1;
5922     }
5923     if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5924         return -1;
5925     if (PyFile_WriteString("\n", f) < 0)
5926         return -1;
5927     return 0;
5928     /* the line below is just to avoid compiler
5929      * compiler warnings about unused functions */
5930     return __Pyx_Print(f, NULL, 0);
5931 }
5932
5933 #else /* Python 3 has a print function */
5934
5935 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5936     int res;
5937     PyObject* arg_tuple = PyTuple_New(1);
5938     if (unlikely(!arg_tuple))
5939         return -1;
5940     Py_INCREF(o);
5941     PyTuple_SET_ITEM(arg_tuple, 0, o);
5942     res = __Pyx_Print(stream, arg_tuple, 1);
5943     Py_DECREF(arg_tuple);
5944     return res;
5945 }
5946
5947 #endif
5948 """,
5949 requires=[printing_utility_code])
5950
5951
5952
5953 #------------------------------------------------------------------------------------
5954
5955 # Exception raising code
5956 #
5957 # Exceptions are raised by __Pyx_Raise() and stored as plain
5958 # type/value/tb in PyThreadState->curexc_*.  When being caught by an
5959 # 'except' statement, curexc_* is moved over to exc_* by
5960 # __Pyx_GetException()
5961
5962 restore_exception_utility_code = UtilityCode(
5963 proto = """
5964 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5965 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5966 """,
5967 impl = """
5968 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5969     PyObject *tmp_type, *tmp_value, *tmp_tb;
5970     PyThreadState *tstate = PyThreadState_GET();
5971
5972     tmp_type = tstate->curexc_type;
5973     tmp_value = tstate->curexc_value;
5974     tmp_tb = tstate->curexc_traceback;
5975     tstate->curexc_type = type;
5976     tstate->curexc_value = value;
5977     tstate->curexc_traceback = tb;
5978     Py_XDECREF(tmp_type);
5979     Py_XDECREF(tmp_value);
5980     Py_XDECREF(tmp_tb);
5981 }
5982
5983 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5984     PyThreadState *tstate = PyThreadState_GET();
5985     *type = tstate->curexc_type;
5986     *value = tstate->curexc_value;
5987     *tb = tstate->curexc_traceback;
5988
5989     tstate->curexc_type = 0;
5990     tstate->curexc_value = 0;
5991     tstate->curexc_traceback = 0;
5992 }
5993
5994 """)
5995
5996 # The following function is based on do_raise() from ceval.c. There
5997 # are separate versions for Python2 and Python3 as exception handling
5998 # has changed quite a lot between the two versions.
5999
6000 raise_utility_code = UtilityCode(
6001 proto = """
6002 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
6003 """,
6004 impl = """
6005 #if PY_MAJOR_VERSION < 3
6006 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
6007     Py_XINCREF(type);
6008     Py_XINCREF(value);
6009     Py_XINCREF(tb);
6010     /* First, check the traceback argument, replacing None with NULL. */
6011     if (tb == Py_None) {
6012         Py_DECREF(tb);
6013         tb = 0;
6014     }
6015     else if (tb != NULL && !PyTraceBack_Check(tb)) {
6016         PyErr_SetString(PyExc_TypeError,
6017             "raise: arg 3 must be a traceback or None");
6018         goto raise_error;
6019     }
6020     /* Next, replace a missing value with None */
6021     if (value == NULL) {
6022         value = Py_None;
6023         Py_INCREF(value);
6024     }
6025     #if PY_VERSION_HEX < 0x02050000
6026     if (!PyClass_Check(type))
6027     #else
6028     if (!PyType_Check(type))
6029     #endif
6030     {
6031         /* Raising an instance.  The value should be a dummy. */
6032         if (value != Py_None) {
6033             PyErr_SetString(PyExc_TypeError,
6034                 "instance exception may not have a separate value");
6035             goto raise_error;
6036         }
6037         /* Normalize to raise <class>, <instance> */
6038         Py_DECREF(value);
6039         value = type;
6040         #if PY_VERSION_HEX < 0x02050000
6041             if (PyInstance_Check(type)) {
6042                 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
6043                 Py_INCREF(type);
6044             }
6045             else {
6046                 type = 0;
6047                 PyErr_SetString(PyExc_TypeError,
6048                     "raise: exception must be an old-style class or instance");
6049                 goto raise_error;
6050             }
6051         #else
6052             type = (PyObject*) Py_TYPE(type);
6053             Py_INCREF(type);
6054             if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
6055                 PyErr_SetString(PyExc_TypeError,
6056                     "raise: exception class must be a subclass of BaseException");
6057                 goto raise_error;
6058             }
6059         #endif
6060     }
6061
6062     __Pyx_ErrRestore(type, value, tb);
6063     return;
6064 raise_error:
6065     Py_XDECREF(value);
6066     Py_XDECREF(type);
6067     Py_XDECREF(tb);
6068     return;
6069 }
6070
6071 #else /* Python 3+ */
6072
6073 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
6074     if (tb == Py_None) {
6075         tb = 0;
6076     } else if (tb && !PyTraceBack_Check(tb)) {
6077         PyErr_SetString(PyExc_TypeError,
6078             "raise: arg 3 must be a traceback or None");
6079         goto bad;
6080     }
6081     if (value == Py_None)
6082         value = 0;
6083
6084     if (PyExceptionInstance_Check(type)) {
6085         if (value) {
6086             PyErr_SetString(PyExc_TypeError,
6087                 "instance exception may not have a separate value");
6088             goto bad;
6089         }
6090         value = type;
6091         type = (PyObject*) Py_TYPE(value);
6092     } else if (!PyExceptionClass_Check(type)) {
6093         PyErr_SetString(PyExc_TypeError,
6094             "raise: exception class must be a subclass of BaseException");
6095         goto bad;
6096     }
6097
6098     PyErr_SetObject(type, value);
6099
6100     if (tb) {
6101         PyThreadState *tstate = PyThreadState_GET();
6102         PyObject* tmp_tb = tstate->curexc_traceback;
6103         if (tb != tmp_tb) {
6104             Py_INCREF(tb);
6105             tstate->curexc_traceback = tb;
6106             Py_XDECREF(tmp_tb);
6107         }
6108     }
6109
6110 bad:
6111     return;
6112 }
6113 #endif
6114 """,
6115 requires=[restore_exception_utility_code])
6116
6117 #------------------------------------------------------------------------------------
6118
6119 get_exception_utility_code = UtilityCode(
6120 proto = """
6121 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6122 """,
6123 impl = """
6124 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
6125     PyObject *local_type, *local_value, *local_tb;
6126     PyObject *tmp_type, *tmp_value, *tmp_tb;
6127     PyThreadState *tstate = PyThreadState_GET();
6128     local_type = tstate->curexc_type;
6129     local_value = tstate->curexc_value;
6130     local_tb = tstate->curexc_traceback;
6131     tstate->curexc_type = 0;
6132     tstate->curexc_value = 0;
6133     tstate->curexc_traceback = 0;
6134     PyErr_NormalizeException(&local_type, &local_value, &local_tb);
6135     if (unlikely(tstate->curexc_type))
6136         goto bad;
6137     #if PY_MAJOR_VERSION >= 3
6138     if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
6139         goto bad;
6140     #endif
6141     *type = local_type;
6142     *value = local_value;
6143     *tb = local_tb;
6144     Py_INCREF(local_type);
6145     Py_INCREF(local_value);
6146     Py_INCREF(local_tb);
6147     tmp_type = tstate->exc_type;
6148     tmp_value = tstate->exc_value;
6149     tmp_tb = tstate->exc_traceback;
6150     tstate->exc_type = local_type;
6151     tstate->exc_value = local_value;
6152     tstate->exc_traceback = local_tb;
6153     /* Make sure tstate is in a consistent state when we XDECREF
6154        these objects (XDECREF may run arbitrary code). */
6155     Py_XDECREF(tmp_type);
6156     Py_XDECREF(tmp_value);
6157     Py_XDECREF(tmp_tb);
6158     return 0;
6159 bad:
6160     *type = 0;
6161     *value = 0;
6162     *tb = 0;
6163     Py_XDECREF(local_type);
6164     Py_XDECREF(local_value);
6165     Py_XDECREF(local_tb);
6166     return -1;
6167 }
6168
6169 """)
6170
6171 #------------------------------------------------------------------------------------
6172
6173 get_exception_tuple_utility_code = UtilityCode(proto="""
6174 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
6175 """,
6176 # I doubt that calling __Pyx_GetException() here is correct as it moves
6177 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
6178 # exception handlers later on from receiving it.
6179 impl = """
6180 static PyObject *__Pyx_GetExceptionTuple(void) {
6181     PyObject *type = NULL, *value = NULL, *tb = NULL;
6182     if (__Pyx_GetException(&type, &value, &tb) == 0) {
6183         PyObject* exc_info = PyTuple_New(3);
6184         if (exc_info) {
6185             Py_INCREF(type);
6186             Py_INCREF(value);
6187             Py_INCREF(tb);
6188             PyTuple_SET_ITEM(exc_info, 0, type);
6189             PyTuple_SET_ITEM(exc_info, 1, value);
6190             PyTuple_SET_ITEM(exc_info, 2, tb);
6191             return exc_info;
6192         }
6193     }
6194     return NULL;
6195 }
6196 """,
6197 requires=[get_exception_utility_code])
6198
6199 #------------------------------------------------------------------------------------
6200
6201 reset_exception_utility_code = UtilityCode(
6202 proto = """
6203 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6204 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
6205 """,
6206 impl = """
6207 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
6208     PyThreadState *tstate = PyThreadState_GET();
6209     *type = tstate->exc_type;
6210     *value = tstate->exc_value;
6211     *tb = tstate->exc_traceback;
6212     Py_XINCREF(*type);
6213     Py_XINCREF(*value);
6214     Py_XINCREF(*tb);
6215 }
6216
6217 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
6218     PyObject *tmp_type, *tmp_value, *tmp_tb;
6219     PyThreadState *tstate = PyThreadState_GET();
6220     tmp_type = tstate->exc_type;
6221     tmp_value = tstate->exc_value;
6222     tmp_tb = tstate->exc_traceback;
6223     tstate->exc_type = type;
6224     tstate->exc_value = value;
6225     tstate->exc_traceback = tb;
6226     Py_XDECREF(tmp_type);
6227     Py_XDECREF(tmp_value);
6228     Py_XDECREF(tmp_tb);
6229 }
6230 """)
6231
6232 #------------------------------------------------------------------------------------
6233
6234 swap_exception_utility_code = UtilityCode(
6235 proto = """
6236 static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6237 """,
6238 impl = """
6239 static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
6240     PyObject *tmp_type, *tmp_value, *tmp_tb;
6241     PyThreadState *tstate = PyThreadState_GET();
6242
6243     tmp_type = tstate->exc_type;
6244     tmp_value = tstate->exc_value;
6245     tmp_tb = tstate->exc_traceback;
6246
6247     tstate->exc_type = *type;
6248     tstate->exc_value = *value;
6249     tstate->exc_traceback = *tb;
6250
6251     *type = tmp_type;
6252     *value = tmp_value;
6253     *tb = tmp_tb;
6254 }
6255 """)
6256
6257 #------------------------------------------------------------------------------------
6258
6259 arg_type_test_utility_code = UtilityCode(
6260 proto = """
6261 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6262     const char *name, int exact); /*proto*/
6263 """,
6264 impl = """
6265 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6266     const char *name, int exact)
6267 {
6268     if (!type) {
6269         PyErr_Format(PyExc_SystemError, "Missing type object");
6270         return 0;
6271     }
6272     if (none_allowed && obj == Py_None) return 1;
6273     else if (exact) {
6274         if (Py_TYPE(obj) == type) return 1;
6275     }
6276     else {
6277         if (PyObject_TypeCheck(obj, type)) return 1;
6278     }
6279     PyErr_Format(PyExc_TypeError,
6280         "Argument '%s' has incorrect type (expected %s, got %s)",
6281         name, type->tp_name, Py_TYPE(obj)->tp_name);
6282     return 0;
6283 }
6284 """)
6285
6286 #------------------------------------------------------------------------------------
6287 #
6288 #  __Pyx_RaiseArgtupleInvalid raises the correct exception when too
6289 #  many or too few positional arguments were found.  This handles
6290 #  Py_ssize_t formatting correctly.
6291
6292 raise_argtuple_invalid_utility_code = UtilityCode(
6293 proto = """
6294 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
6295     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
6296 """,
6297 impl = """
6298 static void __Pyx_RaiseArgtupleInvalid(
6299     const char* func_name,
6300     int exact,
6301     Py_ssize_t num_min,
6302     Py_ssize_t num_max,
6303     Py_ssize_t num_found)
6304 {
6305     Py_ssize_t num_expected;
6306     const char *number, *more_or_less;
6307
6308     if (num_found < num_min) {
6309         num_expected = num_min;
6310         more_or_less = "at least";
6311     } else {
6312         num_expected = num_max;
6313         more_or_less = "at most";
6314     }
6315     if (exact) {
6316         more_or_less = "exactly";
6317     }
6318     number = (num_expected == 1) ? "" : "s";
6319     PyErr_Format(PyExc_TypeError,
6320         #if PY_VERSION_HEX < 0x02050000
6321             "%s() takes %s %d positional argument%s (%d given)",
6322         #else
6323             "%s() takes %s %zd positional argument%s (%zd given)",
6324         #endif
6325         func_name, more_or_less, num_expected, number, num_found);
6326 }
6327 """)
6328
6329 raise_keyword_required_utility_code = UtilityCode(
6330 proto = """
6331 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6332 """,
6333 impl = """
6334 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6335     const char* func_name,
6336     PyObject* kw_name)
6337 {
6338     PyErr_Format(PyExc_TypeError,
6339         #if PY_MAJOR_VERSION >= 3
6340         "%s() needs keyword-only argument %U", func_name, kw_name);
6341         #else
6342         "%s() needs keyword-only argument %s", func_name,
6343         PyString_AS_STRING(kw_name));
6344         #endif
6345 }
6346 """)
6347
6348 raise_double_keywords_utility_code = UtilityCode(
6349 proto = """
6350 static void __Pyx_RaiseDoubleKeywordsError(
6351     const char* func_name, PyObject* kw_name); /*proto*/
6352 """,
6353 impl = """
6354 static void __Pyx_RaiseDoubleKeywordsError(
6355     const char* func_name,
6356     PyObject* kw_name)
6357 {
6358     PyErr_Format(PyExc_TypeError,
6359         #if PY_MAJOR_VERSION >= 3
6360         "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6361         #else
6362         "%s() got multiple values for keyword argument '%s'", func_name,
6363         PyString_AS_STRING(kw_name));
6364         #endif
6365 }
6366 """)
6367
6368 #------------------------------------------------------------------------------------
6369 #
6370 #  __Pyx_CheckKeywordStrings raises an error if non-string keywords
6371 #  were passed to a function, or if any keywords were passed to a
6372 #  function that does not accept them.
6373
6374 keyword_string_check_utility_code = UtilityCode(
6375 proto = """
6376 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6377     const char* function_name, int kw_allowed); /*proto*/
6378 """,
6379 impl = """
6380 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6381     PyObject *kwdict,
6382     const char* function_name,
6383     int kw_allowed)
6384 {
6385     PyObject* key = 0;
6386     Py_ssize_t pos = 0;
6387     while (PyDict_Next(kwdict, &pos, &key, 0)) {
6388         #if PY_MAJOR_VERSION < 3
6389         if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6390         #else
6391         if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6392         #endif
6393             goto invalid_keyword_type;
6394     }
6395     if ((!kw_allowed) && unlikely(key))
6396         goto invalid_keyword;
6397     return 1;
6398 invalid_keyword_type:
6399     PyErr_Format(PyExc_TypeError,
6400         "%s() keywords must be strings", function_name);
6401     return 0;
6402 invalid_keyword:
6403     PyErr_Format(PyExc_TypeError,
6404     #if PY_MAJOR_VERSION < 3
6405         "%s() got an unexpected keyword argument '%s'",
6406         function_name, PyString_AsString(key));
6407     #else
6408         "%s() got an unexpected keyword argument '%U'",
6409         function_name, key);
6410     #endif
6411     return 0;
6412 }
6413 """)
6414
6415 #------------------------------------------------------------------------------------
6416 #
6417 #  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6418 #  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
6419 #  keywords will raise an invalid keyword error.
6420 #
6421 #  Three kinds of errors are checked: 1) non-string keywords, 2)
6422 #  unexpected keywords and 3) overlap with positional arguments.
6423 #
6424 #  If num_posargs is greater 0, it denotes the number of positional
6425 #  arguments that were passed and that must therefore not appear
6426 #  amongst the keywords as well.
6427 #
6428 #  This method does not check for required keyword arguments.
6429 #
6430
6431 parse_keywords_utility_code = UtilityCode(
6432 proto = """
6433 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6434     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6435     const char* function_name); /*proto*/
6436 """,
6437 impl = """
6438 static int __Pyx_ParseOptionalKeywords(
6439     PyObject *kwds,
6440     PyObject **argnames[],
6441     PyObject *kwds2,
6442     PyObject *values[],
6443     Py_ssize_t num_pos_args,
6444     const char* function_name)
6445 {
6446     PyObject *key = 0, *value = 0;
6447     Py_ssize_t pos = 0;
6448     PyObject*** name;
6449     PyObject*** first_kw_arg = argnames + num_pos_args;
6450
6451     while (PyDict_Next(kwds, &pos, &key, &value)) {
6452         name = first_kw_arg;
6453         while (*name && (**name != key)) name++;
6454         if (*name) {
6455             values[name-argnames] = value;
6456         } else {
6457             #if PY_MAJOR_VERSION < 3
6458             if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6459             #else
6460             if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6461             #endif
6462                 goto invalid_keyword_type;
6463             } else {
6464                 for (name = first_kw_arg; *name; name++) {
6465                     #if PY_MAJOR_VERSION >= 3
6466                     if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6467                         PyUnicode_Compare(**name, key) == 0) break;
6468                     #else
6469                     if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6470                         _PyString_Eq(**name, key)) break;
6471                     #endif
6472                 }
6473                 if (*name) {
6474                     values[name-argnames] = value;
6475                 } else {
6476                     /* unexpected keyword found */
6477                     for (name=argnames; name != first_kw_arg; name++) {
6478                         if (**name == key) goto arg_passed_twice;
6479                         #if PY_MAJOR_VERSION >= 3
6480                         if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6481                             PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6482                         #else
6483                         if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6484                             _PyString_Eq(**name, key)) goto arg_passed_twice;
6485                         #endif
6486                     }
6487                     if (kwds2) {
6488                         if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6489                     } else {
6490                         goto invalid_keyword;
6491                     }
6492                 }
6493             }
6494         }
6495     }
6496     return 0;
6497 arg_passed_twice:
6498     __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6499     goto bad;
6500 invalid_keyword_type:
6501     PyErr_Format(PyExc_TypeError,
6502         "%s() keywords must be strings", function_name);
6503     goto bad;
6504 invalid_keyword:
6505     PyErr_Format(PyExc_TypeError,
6506     #if PY_MAJOR_VERSION < 3
6507         "%s() got an unexpected keyword argument '%s'",
6508         function_name, PyString_AsString(key));
6509     #else
6510         "%s() got an unexpected keyword argument '%U'",
6511         function_name, key);
6512     #endif
6513 bad:
6514     return -1;
6515 }
6516 """,
6517 requires=[raise_double_keywords_utility_code])
6518
6519 #------------------------------------------------------------------------------------
6520
6521 traceback_utility_code = UtilityCode(
6522 proto = """
6523 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6524 """,
6525 impl = """
6526 #include "compile.h"
6527 #include "frameobject.h"
6528 #include "traceback.h"
6529
6530 static void __Pyx_AddTraceback(const char *funcname) {
6531     PyObject *py_srcfile = 0;
6532     PyObject *py_funcname = 0;
6533     PyObject *py_globals = 0;
6534     PyCodeObject *py_code = 0;
6535     PyFrameObject *py_frame = 0;
6536
6537     #if PY_MAJOR_VERSION < 3
6538     py_srcfile = PyString_FromString(%(FILENAME)s);
6539     #else
6540     py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6541     #endif
6542     if (!py_srcfile) goto bad;
6543     if (%(CLINENO)s) {
6544         #if PY_MAJOR_VERSION < 3
6545         py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6546         #else
6547         py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6548         #endif
6549     }
6550     else {
6551         #if PY_MAJOR_VERSION < 3
6552         py_funcname = PyString_FromString(funcname);
6553         #else
6554         py_funcname = PyUnicode_FromString(funcname);
6555         #endif
6556     }
6557     if (!py_funcname) goto bad;
6558     py_globals = PyModule_GetDict(%(GLOBALS)s);
6559     if (!py_globals) goto bad;
6560     py_code = PyCode_New(
6561         0,            /*int argcount,*/
6562         #if PY_MAJOR_VERSION >= 3
6563         0,            /*int kwonlyargcount,*/
6564         #endif
6565         0,            /*int nlocals,*/
6566         0,            /*int stacksize,*/
6567         0,            /*int flags,*/
6568         %(EMPTY_BYTES)s, /*PyObject *code,*/
6569         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6570         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6571         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6572         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6573         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6574         py_srcfile,   /*PyObject *filename,*/
6575         py_funcname,  /*PyObject *name,*/
6576         %(LINENO)s,   /*int firstlineno,*/
6577         %(EMPTY_BYTES)s  /*PyObject *lnotab*/
6578     );
6579     if (!py_code) goto bad;
6580     py_frame = PyFrame_New(
6581         PyThreadState_GET(), /*PyThreadState *tstate,*/
6582         py_code,             /*PyCodeObject *code,*/
6583         py_globals,          /*PyObject *globals,*/
6584         0                    /*PyObject *locals*/
6585     );
6586     if (!py_frame) goto bad;
6587     py_frame->f_lineno = %(LINENO)s;
6588     PyTraceBack_Here(py_frame);
6589 bad:
6590     Py_XDECREF(py_srcfile);
6591     Py_XDECREF(py_funcname);
6592     Py_XDECREF(py_code);
6593     Py_XDECREF(py_frame);
6594 }
6595 """ % {
6596     'FILENAME': Naming.filename_cname,
6597     'LINENO':  Naming.lineno_cname,
6598     'CFILENAME': Naming.cfilenm_cname,
6599     'CLINENO':  Naming.clineno_cname,
6600     'GLOBALS': Naming.module_cname,
6601     'EMPTY_TUPLE' : Naming.empty_tuple,
6602     'EMPTY_BYTES' : Naming.empty_bytes,
6603 })
6604
6605 #------------------------------------------------------------------------------------
6606
6607 unraisable_exception_utility_code = UtilityCode(
6608 proto = """
6609 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6610 """,
6611 impl = """
6612 static void __Pyx_WriteUnraisable(const char *name) {
6613     PyObject *old_exc, *old_val, *old_tb;
6614     PyObject *ctx;
6615     __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6616     #if PY_MAJOR_VERSION < 3
6617     ctx = PyString_FromString(name);
6618     #else
6619     ctx = PyUnicode_FromString(name);
6620     #endif
6621     __Pyx_ErrRestore(old_exc, old_val, old_tb);
6622     if (!ctx) {
6623         PyErr_WriteUnraisable(Py_None);
6624     } else {
6625         PyErr_WriteUnraisable(ctx);
6626         Py_DECREF(ctx);
6627     }
6628 }
6629 """,
6630 requires=[restore_exception_utility_code])
6631
6632 #------------------------------------------------------------------------------------
6633
6634 set_vtable_utility_code = UtilityCode(
6635 proto = """
6636 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6637 """,
6638 impl = """
6639 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6640 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6641     PyObject *ob = PyCapsule_New(vtable, 0, 0);
6642 #else
6643     PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6644 #endif
6645     if (!ob)
6646         goto bad;
6647     if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6648         goto bad;
6649     Py_DECREF(ob);
6650     return 0;
6651 bad:
6652     Py_XDECREF(ob);
6653     return -1;
6654 }
6655 """)
6656
6657 #------------------------------------------------------------------------------------
6658
6659 get_vtable_utility_code = UtilityCode(
6660 proto = """
6661 static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
6662 """,
6663 impl = r"""
6664 static void* __Pyx_GetVtable(PyObject *dict) {
6665     void* ptr;
6666     PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6667     if (!ob)
6668         goto bad;
6669 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6670     ptr = PyCapsule_GetPointer(ob, 0);
6671 #else
6672     ptr = PyCObject_AsVoidPtr(ob);
6673 #endif
6674     if (!ptr && !PyErr_Occurred())
6675         PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
6676     Py_DECREF(ob);
6677     return ptr;
6678 bad:
6679     Py_XDECREF(ob);
6680     return NULL;
6681 }
6682 """)
6683
6684 #------------------------------------------------------------------------------------
6685
6686 init_string_tab_utility_code = UtilityCode(
6687 proto = """
6688 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6689 """,
6690 impl = """
6691 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6692     while (t->p) {
6693         #if PY_MAJOR_VERSION < 3
6694         if (t->is_unicode) {
6695             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6696         } else if (t->intern) {
6697             *t->p = PyString_InternFromString(t->s);
6698         } else {
6699             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6700         }
6701         #else  /* Python 3+ has unicode identifiers */
6702         if (t->is_unicode | t->is_str) {
6703             if (t->intern) {
6704                 *t->p = PyUnicode_InternFromString(t->s);
6705             } else if (t->encoding) {
6706                 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6707             } else {
6708                 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6709             }
6710         } else {
6711             *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6712         }
6713         #endif
6714         if (!*t->p)
6715             return -1;
6716         ++t;
6717     }
6718     return 0;
6719 }
6720 """)
6721
6722 #------------------------------------------------------------------------------------
6723
6724 force_init_threads_utility_code = UtilityCode(
6725 proto="""
6726 #ifndef __PYX_FORCE_INIT_THREADS
6727   #if PY_VERSION_HEX < 0x02040200
6728     #define __PYX_FORCE_INIT_THREADS 1
6729   #else
6730     #define __PYX_FORCE_INIT_THREADS 0
6731   #endif
6732 #endif
6733 """)
6734
6735 #------------------------------------------------------------------------------------
6736
6737 # Note that cPython ignores PyTrace_EXCEPTION,
6738 # but maybe some other profilers don't.
6739
6740 profile_utility_code = UtilityCode(proto="""
6741 #ifndef CYTHON_PROFILE
6742   #define CYTHON_PROFILE 1
6743 #endif
6744
6745 #ifndef CYTHON_PROFILE_REUSE_FRAME
6746   #define CYTHON_PROFILE_REUSE_FRAME 0
6747 #endif
6748
6749 #if CYTHON_PROFILE
6750
6751   #include "compile.h"
6752   #include "frameobject.h"
6753   #include "traceback.h"
6754
6755   #if CYTHON_PROFILE_REUSE_FRAME
6756     #define CYTHON_FRAME_MODIFIER static
6757     #define CYTHON_FRAME_DEL
6758   #else
6759     #define CYTHON_FRAME_MODIFIER
6760     #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6761   #endif
6762
6763   #define __Pyx_TraceDeclarations                                  \\
6764   static PyCodeObject *%(FRAME_CODE)s = NULL;                      \\
6765   CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL;           \\
6766   int __Pyx_use_tracing = 0;
6767
6768   #define __Pyx_TraceCall(funcname, srcfile, firstlineno)                            \\
6769   if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) {      \\
6770       __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno);  \\
6771   }
6772
6773   #define __Pyx_TraceException()                                                           \\
6774   if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6775       PyObject *exc_info = __Pyx_GetExceptionTuple();                                      \\
6776       if (exc_info) {                                                                      \\
6777           PyThreadState_GET()->c_profilefunc(                                              \\
6778               PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info);  \\
6779           Py_DECREF(exc_info);                                                             \\
6780       }                                                                                    \\
6781   }
6782
6783   #define __Pyx_TraceReturn(result)                                                  \\
6784   if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6785       PyThreadState_GET()->c_profilefunc(                                            \\
6786           PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result);     \\
6787       CYTHON_FRAME_DEL;                                                               \\
6788   }
6789
6790   static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6791   static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6792
6793 #else
6794
6795   #define __Pyx_TraceDeclarations
6796   #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6797   #define __Pyx_TraceException()
6798   #define __Pyx_TraceReturn(result)
6799
6800 #endif /* CYTHON_PROFILE */
6801 """
6802 % {
6803     "FRAME": Naming.frame_cname,
6804     "FRAME_CODE": Naming.frame_code_cname,
6805 },
6806 impl = """
6807
6808 #if CYTHON_PROFILE
6809
6810 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6811                                    PyFrameObject** frame,
6812                                    const char *funcname,
6813                                    const char *srcfile,
6814                                    int firstlineno) {
6815     if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6816         if (*code == NULL) {
6817             *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6818             if (*code == NULL) return 0;
6819         }
6820         *frame = PyFrame_New(
6821             PyThreadState_GET(),            /*PyThreadState *tstate*/
6822             *code,                          /*PyCodeObject *code*/
6823             PyModule_GetDict(%(MODULE)s),      /*PyObject *globals*/
6824             0                               /*PyObject *locals*/
6825         );
6826         if (*frame == NULL) return 0;
6827     }
6828     else {
6829         (*frame)->f_tstate = PyThreadState_GET();
6830     }
6831     return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6832 }
6833
6834 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6835     PyObject *py_srcfile = 0;
6836     PyObject *py_funcname = 0;
6837     PyCodeObject *py_code = 0;
6838
6839     #if PY_MAJOR_VERSION < 3
6840     py_funcname = PyString_FromString(funcname);
6841     py_srcfile = PyString_FromString(srcfile);
6842     #else
6843     py_funcname = PyUnicode_FromString(funcname);
6844     py_srcfile = PyUnicode_FromString(srcfile);
6845     #endif
6846     if (!py_funcname | !py_srcfile) goto bad;
6847
6848     py_code = PyCode_New(
6849         0,                /*int argcount,*/
6850         #if PY_MAJOR_VERSION >= 3
6851         0,                /*int kwonlyargcount,*/
6852         #endif
6853         0,                /*int nlocals,*/
6854         0,                /*int stacksize,*/
6855         0,                /*int flags,*/
6856         %(EMPTY_BYTES)s,  /*PyObject *code,*/
6857         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6858         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6859         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6860         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6861         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6862         py_srcfile,       /*PyObject *filename,*/
6863         py_funcname,      /*PyObject *name,*/
6864         firstlineno,      /*int firstlineno,*/
6865         %(EMPTY_BYTES)s   /*PyObject *lnotab*/
6866     );
6867
6868 bad:
6869     Py_XDECREF(py_srcfile);
6870     Py_XDECREF(py_funcname);
6871
6872     return py_code;
6873 }
6874
6875 #endif /* CYTHON_PROFILE */
6876 """ % {
6877     'EMPTY_TUPLE' : Naming.empty_tuple,
6878     'EMPTY_BYTES' : Naming.empty_bytes,
6879     "MODULE": Naming.module_cname,
6880 })