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