3 # Pyrex - Parse tree nodes
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)
15 import sys, os, time, copy
18 from Errors import error, warning, InternalError
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
32 absolute_path_length = 0
34 def relative_position(pos):
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.)
42 a position tuple -- (absolute filename, line number column position)
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])
55 def embed_position(pos, docstring):
56 if not Options.embed_pos_in_docstring:
58 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
61 return EncodedString(pos_line)
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:
68 encoded_bytes = pos_line.encode(encoding)
69 except UnicodeEncodeError:
73 # reuse the string encoding of the original docstring
74 doc = EncodedString(pos_line)
76 doc = EncodedString(pos_line + u'\n' + docstring)
77 doc.encoding = encoding
81 from Code import CCodeWriter
82 from types import FunctionType
84 def write_func_call(func):
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
90 marker = ' /* %s -> %s.%s %s */' % (
91 ' ' * code.call_level,
92 node.__class__.__name__,
95 pristine = code.buffer.stream.tell()
97 start = code.buffer.stream.tell()
99 res = func(*args, **kwds)
101 if start == code.buffer.stream.tell():
102 code.buffer.stream.seek(pristine)
104 marker = marker.replace('->', '<-')
108 return func(*args, **kwds)
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):
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)
123 # pos (string, int, int) Source file position
124 # is_name boolean Is a NameNode
125 # is_literal boolean Is a ConstNode
127 if DebugFlags.debug_trace_code_generation:
128 __metaclass__ = VerboseCodeWriter
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.
139 def __init__(self, pos, **kw):
141 self.__dict__.update(kw)
143 gil_message = "Operation"
147 def gil_error(self, env=None):
148 error(self.pos, "%s not allowed without gil" % self.gil_message)
150 cpp_message = "Operation"
152 def cpp_check(self, env):
157 error(self.pos, "%s only allowed in c++" % self.cpp_message)
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])
174 # There are 4 phases of parse tree processing, applied in order to
175 # all the statements in a given scope-block:
177 # (0) analyse_control_flow
178 # Create the control flow tree into which state can be asserted and
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).
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
195 # Emit C code for all declarations, statements and expressions.
196 # Recursively applies the 3 processing phases to the bodies of
200 def analyse_control_flow(self, env):
203 def analyse_declarations(self, env):
206 def analyse_expressions(self, env):
207 raise InternalError("analyse_expressions not implemented for %s" % \
208 self.__class__.__name__)
210 def generate_code(self, code):
211 raise InternalError("generate_code not implemented for %s" % \
212 self.__class__.__name__)
214 def annotate(self, code):
215 # mro does the wrong thing
216 if isinstance(self, BlockNode):
217 self.body.annotate(code)
222 except AttributeError:
224 if not self.child_attrs:
227 for attr in self.child_attrs:
228 child = getattr(self, attr)
229 # Sometimes lists, sometimes nodes
232 elif isinstance(child, list):
234 pos = max(pos, c.end_pos())
236 pos = max(pos, child.end_pos())
240 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
242 return "<...nesting level cutoff...>"
243 if encountered is None:
245 if id(self) in encountered:
246 return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self))
247 encountered.add(id(self))
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])
258 attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out]
260 return "<%s (0x%x)>" % (self.__class__.__name__, id(self))
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
269 class CompilerDirectivesNode(Node):
271 Sets compiler directives for the children nodes
273 # directives {string:value} A dictionary holding the right value for
274 # *all* possible directives.
276 child_attrs = ["body"]
278 def analyse_control_flow(self, env):
280 env.directives = self.directives
281 self.body.analyse_control_flow(env)
284 def analyse_declarations(self, env):
286 env.directives = self.directives
287 self.body.analyse_declarations(env)
290 def analyse_expressions(self, env):
292 env.directives = self.directives
293 self.body.analyse_expressions(env)
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
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
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
316 class BlockNode(object):
317 # Mixin class for nodes representing a declaration block.
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)
325 def generate_lambda_definitions(self, env, code):
326 for node in env.lambda_defs:
327 node.generate_function_definitions(env, code)
329 class StatListNode(Node):
330 # stats a list of StatNode
332 child_attrs = ["stats"]
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)
339 def analyse_control_flow(self, env):
340 for stat in self.stats:
341 stat.analyse_control_flow(env)
343 def analyse_declarations(self, env):
344 #print "StatListNode.analyse_declarations" ###
345 for stat in self.stats:
346 stat.analyse_declarations(env)
348 def analyse_expressions(self, env):
349 #print "StatListNode.analyse_expressions" ###
350 for stat in self.stats:
351 stat.analyse_expressions(env)
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)
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)
364 def annotate(self, code):
365 for stat in self.stats:
369 class StatNode(Node):
371 # Code generation for statements is split into the following subphases:
373 # (1) generate_function_definitions
374 # Emit C code for the definitions of any structs,
375 # unions, enums and functions defined in the current
378 # (2) generate_execution_code
379 # Emit C code for executable statements.
382 def generate_function_definitions(self, env, code):
385 def generate_execution_code(self, code):
386 raise InternalError("generate_execution_code not implemented for %s" % \
387 self.__class__.__name__)
390 class CDefExternNode(StatNode):
391 # include_file string or None
394 child_attrs = ["body"]
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
401 self.body.analyse_declarations(env)
402 env.in_cinclude = old_cinclude_flag
404 def analyse_expressions(self, env):
407 def generate_execution_code(self, code):
410 def annotate(self, code):
411 self.body.annotate(code)
414 class CDeclaratorNode(Node):
415 # Part of a C declaration.
417 # Processing during analyse_declarations phase:
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.
424 # calling_convention string Calling convention of CFuncDeclaratorNode
425 # for which this is a base
429 calling_convention = ""
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
437 child_attrs = ['default']
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.")
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
454 class CPtrDeclaratorNode(CDeclaratorNode):
455 # base CDeclaratorNode
457 child_attrs = ["base"]
459 def analyse(self, base_type, env, nonempty = 0):
460 if base_type.is_pyobject:
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)
466 class CReferenceDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
469 child_attrs = ["base"]
471 def analyse(self, base_type, env, nonempty = 0):
472 if base_type.is_pyobject:
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)
478 class CArrayDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
482 child_attrs = ["base", "dimension"]
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
490 args = self.dimension,
491 values = [v.analyse_as_type(env) for v in args]
493 ix = values.index(None)
494 error(args[ix].pos, "Template parameter not a type.")
496 base_type = base_type.specialize_here(self.pos, values)
497 return self.base.analyse(base_type, env, nonempty = nonempty)
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()
511 if not base_type.is_complete():
513 "Array element type '%s' is incomplete" % base_type)
514 if base_type.is_pyobject:
516 "Array element cannot be a Python object")
517 if base_type.is_cfunction:
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)
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
533 child_attrs = ["base", "args", "exception_value"]
536 optional_arg_count = 0
538 def analyse(self, return_type, env, nonempty = 0, directive_locals = {}):
542 for i, arg_node in enumerate(self.args):
543 name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
544 is_self_arg = (i == 0 and env.is_c_class_scope))
545 name = name_declarator.name
546 if name in directive_locals:
547 type_node = directive_locals[name]
548 other_type = type_node.analyse_as_type(env)
549 if other_type is None:
550 error(type_node.pos, "Not a type")
551 elif (type is not PyrexTypes.py_object_type
552 and not type.same_as(other_type)):
553 error(self.base.pos, "Signature does not agree with previous declaration")
554 error(type_node.pos, "Previous declaration here")
557 if name_declarator.cname:
559 "Function argument cannot have C name specification")
560 # Turn *[] argument into **
562 type = PyrexTypes.c_ptr_type(type.base_type)
563 # Catch attempted C-style func(void) decl
565 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
566 func_type_args.append(
567 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
569 self.optional_arg_count += 1
570 elif self.optional_arg_count:
571 error(self.pos, "Non-default argument follows default argument")
573 if self.optional_arg_count:
574 scope = StructOrUnionScope()
575 arg_count_member = '%sn' % Naming.pyrex_prefix
576 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
577 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
578 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
579 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
580 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
585 cname = struct_cname)
586 self.op_args_struct.defined_in_pxd = 1
587 self.op_args_struct.used = 1
591 if self.exception_check == '+':
592 env.add_include_file('stdexcept')
593 if return_type.is_pyobject \
594 and (self.exception_value or self.exception_check) \
595 and self.exception_check != '+':
597 "Exception clause not allowed for function returning Python object")
599 if self.exception_value:
600 self.exception_value.analyse_const_expression(env)
601 if self.exception_check == '+':
602 self.exception_value.analyse_types(env)
603 exc_val_type = self.exception_value.type
604 if not exc_val_type.is_error and \
605 not exc_val_type.is_pyobject and \
606 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
607 error(self.exception_value.pos,
608 "Exception value must be a Python exception or cdef function with no arguments.")
609 exc_val = self.exception_value
611 self.exception_value = self.exception_value.coerce_to(return_type, env)
612 if self.exception_value.analyse_const_expression(env):
613 exc_val = self.exception_value.get_constant_c_result_code()
615 raise InternalError("get_constant_c_result_code not implemented for %s" %
616 self.exception_value.__class__.__name__)
617 if not return_type.assignable_from(self.exception_value.type):
618 error(self.exception_value.pos,
619 "Exception value incompatible with function return type")
620 exc_check = self.exception_check
621 if return_type.is_cfunction:
623 "Function cannot return a function")
624 func_type = PyrexTypes.CFuncType(
625 return_type, func_type_args, self.has_varargs,
626 optional_arg_count = self.optional_arg_count,
627 exception_value = exc_val, exception_check = exc_check,
628 calling_convention = self.base.calling_convention,
629 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
630 if self.optional_arg_count:
631 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
632 callspec = env.directives['callspec']
634 current = func_type.calling_convention
635 if current and current != callspec:
636 error(self.pos, "cannot have both '%s' and '%s' "
637 "calling conventions" % (current, callspec))
638 func_type.calling_convention = callspec
639 return self.base.analyse(func_type, env)
642 class CArgDeclNode(Node):
643 # Item in a function declaration argument list.
645 # base_type CBaseTypeNode
646 # declarator CDeclaratorNode
647 # not_none boolean Tagged with 'not None'
648 # or_none boolean Tagged with 'or None'
649 # accept_none boolean Resolved boolean for not_none/or_none
650 # default ExprNode or None
651 # default_value PyObjectConst constant for default value
652 # annotation ExprNode or None Py3 function arg annotation
653 # is_self_arg boolean Is the "self" arg of an extension type method
654 # is_type_arg boolean Is the "class" arg of an extension type classmethod
655 # is_kw_only boolean Is a keyword-only argument
657 child_attrs = ["base_type", "declarator", "default"]
666 name_declarator = None
670 def analyse(self, env, nonempty = 0, is_self_arg = False):
672 self.base_type.is_self_arg = self.is_self_arg = True
673 if self.type is None:
674 # The parser may missinterpret names as types...
676 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
678 self.declarator.name = self.base_type.name
679 self.base_type.name = None
680 self.base_type.is_basic_c_type = False
683 could_be_name = False
684 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
685 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
686 self.declarator.name = self.base_type.arg_name
687 # The parser is unable to resolve the ambiguity of [] as part of the
688 # type (e.g. in buffers) or empty declarator (as with arrays).
689 # This is only arises for empty multi-dimensional arrays.
690 if (base_type.is_array
691 and isinstance(self.base_type, TemplatedTypeNode)
692 and isinstance(self.declarator, CArrayDeclaratorNode)):
693 declarator = self.declarator
694 while isinstance(declarator.base, CArrayDeclaratorNode):
695 declarator = declarator.base
696 declarator.base = self.base_type.array_declarator
697 base_type = base_type.base_type
698 return self.declarator.analyse(base_type, env, nonempty = nonempty)
700 return self.name_declarator, self.type
702 def calculate_default_value_code(self, code):
703 if self.default_value is None:
705 if self.default.is_literal:
706 # will not output any code, just assign the result_code
707 self.default.generate_evaluation_code(code)
708 return self.type.cast_code(self.default.result())
709 self.default_value = code.get_argument_default_const(self.type)
710 return self.default_value
712 def annotate(self, code):
714 self.default.annotate(code)
717 class CBaseTypeNode(Node):
718 # Abstract base class for C base type nodes.
720 # Processing during analyse_declarations phase:
727 def analyse_as_type(self, env):
728 return self.analyse(env)
730 class CAnalysedBaseTypeNode(Node):
735 def analyse(self, env, could_be_name = False):
738 class CSimpleBaseTypeNode(CBaseTypeNode):
740 # module_path [string] Qualifying name components
741 # is_basic_c_type boolean
745 # is_self_arg boolean Is self argument of C method
746 # ##is_type_arg boolean Is type argument of class method
749 arg_name = None # in case the argument name was interpreted as a type
751 is_basic_c_type = False
754 def analyse(self, env, could_be_name = False):
755 # Return type descriptor.
756 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
758 if self.is_basic_c_type:
759 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
761 error(self.pos, "Unrecognised type modifier combination")
762 elif self.name == "object" and not self.module_path:
763 type = py_object_type
764 elif self.name is None:
765 if self.is_self_arg and env.is_c_class_scope:
766 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
767 type = env.parent_type
768 ## elif self.is_type_arg and env.is_c_class_scope:
769 ## type = Builtin.type_type
771 type = py_object_type
774 scope = env.find_imported_module(self.module_path, self.pos)
778 if scope.is_c_class_scope:
779 scope = scope.global_scope()
780 entry = scope.lookup(self.name)
781 if entry and entry.is_type:
784 if self.is_self_arg and env.is_c_class_scope:
785 type = env.parent_type
786 ## elif self.is_type_arg and env.is_c_class_scope:
787 ## type = Builtin.type_type
789 type = py_object_type
790 self.arg_name = self.name
793 if not self.name in self.templates:
794 error(self.pos, "'%s' is not a type identifier" % self.name)
795 type = PyrexTypes.TemplatePlaceholderType(self.name)
797 error(self.pos, "'%s' is not a type identifier" % self.name)
799 if not type.is_numeric or type.is_complex:
800 error(self.pos, "can only complexify c numeric types")
801 type = PyrexTypes.CComplexType(type)
802 type.create_declaration_utility_code(env)
803 elif type is Builtin.complex_type:
804 # Special case: optimise builtin complex type into C's
805 # double complex. The parser cannot do this (as for the
806 # normal scalar types) as the user may have redeclared the
807 # 'complex' type. Testing for the exact type here works.
808 type = PyrexTypes.c_double_complex_type
809 type.create_declaration_utility_code(env)
814 return PyrexTypes.error_type
816 class CNestedBaseTypeNode(CBaseTypeNode):
817 # For C++ classes that live inside other C++ classes.
820 # base_type CBaseTypeNode
822 child_attrs = ['base_type']
824 def analyse(self, env, could_be_name = None):
825 base_type = self.base_type.analyse(env)
826 if base_type is PyrexTypes.error_type:
827 return PyrexTypes.error_type
828 if not base_type.is_cpp_class:
829 error(self.pos, "'%s' is not a valid type scope" % base_type)
830 return PyrexTypes.error_type
831 type_entry = base_type.scope.lookup_here(self.name)
832 if not type_entry or not type_entry.is_type:
833 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
834 return PyrexTypes.error_type
835 return type_entry.type
837 class TemplatedTypeNode(CBaseTypeNode):
839 # positional_args [ExprNode] List of positional arguments
840 # keyword_args DictNode Keyword arguments
841 # base_type_node CBaseTypeNode
844 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
847 child_attrs = ["base_type_node", "positional_args",
848 "keyword_args", "dtype_node"]
854 def analyse(self, env, could_be_name = False, base_type = None):
855 if base_type is None:
856 base_type = self.base_type_node.analyse(env)
857 if base_type.is_error: return base_type
859 if base_type.is_cpp_class:
861 if self.keyword_args and self.keyword_args.key_value_pairs:
862 error(self.pos, "c++ templates cannot take keyword arguments");
863 self.type = PyrexTypes.error_type
866 for template_node in self.positional_args:
867 type = template_node.analyse_as_type(env)
869 error(template_node.pos, "unknown type in template argument")
871 template_types.append(type)
872 self.type = base_type.specialize_here(self.pos, template_types)
874 elif base_type.is_pyobject:
878 options = Buffer.analyse_buffer_options(
881 self.positional_args,
883 base_type.buffer_defaults)
885 if sys.version_info[0] < 3:
886 # Py 2.x enforces byte strings as keyword arguments ...
887 options = dict([ (name.encode('ASCII'), value)
888 for name, value in options.items() ])
890 self.type = PyrexTypes.BufferType(base_type, **options)
894 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
895 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
896 error(self.pos, "invalid array declaration")
897 self.type = PyrexTypes.error_type
899 # It would be nice to merge this class with CArrayDeclaratorNode,
900 # but arrays are part of the declaration, not the type...
901 if not self.positional_args:
904 dimension = self.positional_args[0]
905 self.array_declarator = CArrayDeclaratorNode(self.pos,
906 base = empty_declarator,
907 dimension = dimension)
908 self.type = self.array_declarator.analyse(base_type, env)[1]
912 class CComplexBaseTypeNode(CBaseTypeNode):
913 # base_type CBaseTypeNode
914 # declarator CDeclaratorNode
916 child_attrs = ["base_type", "declarator"]
918 def analyse(self, env, could_be_name = False):
919 base = self.base_type.analyse(env, could_be_name)
920 _, type = self.declarator.analyse(base, env)
924 class CVarDefNode(StatNode):
925 # C variable definition or forward/extern function declaration.
927 # visibility 'private' or 'public' or 'extern'
928 # base_type CBaseTypeNode
929 # declarators [CDeclaratorNode]
933 # decorators [cython.locals(...)] or None
934 # directive_locals { string : NameNode } locals defined by cython.locals(...)
936 child_attrs = ["base_type", "declarators"]
939 directive_locals = None
941 def analyse_declarations(self, env, dest_scope = None):
942 if self.directive_locals is None:
943 self.directive_locals = {}
946 self.dest_scope = dest_scope
947 base_type = self.base_type.analyse(env)
949 # If the field is an external typedef, we cannot be sure about the type,
950 # so do conversion ourself rather than rely on the CPython mechanism (through
951 # a property; made in AnalyseDeclarationsTransform).
952 if (dest_scope.is_c_class_scope
953 and self.visibility in ('public', 'readonly')):
956 need_property = False
957 visibility = self.visibility
959 for declarator in self.declarators:
960 if isinstance(declarator, CFuncDeclaratorNode):
961 name_declarator, type = declarator.analyse(base_type, env, directive_locals=self.directive_locals)
963 name_declarator, type = declarator.analyse(base_type, env)
964 if not type.is_complete():
965 if not (self.visibility == 'extern' and type.is_array):
966 error(declarator.pos,
967 "Variable type '%s' is incomplete" % type)
968 if self.visibility == 'extern' and type.is_pyobject:
969 error(declarator.pos,
970 "Python object cannot be declared extern")
971 name = name_declarator.name
972 cname = name_declarator.cname
974 error(declarator.pos, "Missing name in declaration.")
976 if type.is_cfunction:
977 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
978 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
980 if entry is not None:
981 entry.directive_locals = copy.copy(self.directive_locals)
983 if self.directive_locals:
984 error(self.pos, "Decorators can only be followed by functions")
985 if self.in_pxd and self.visibility != 'extern':
987 "Only 'extern' C variable declaration allowed in .pxd file")
988 entry = dest_scope.declare_var(name, type, declarator.pos,
989 cname=cname, visibility=visibility, api=self.api, is_cdef=1)
990 entry.needs_property = need_property
993 class CStructOrUnionDefNode(StatNode):
995 # cname string or None
996 # kind "struct" or "union"
997 # typedef_flag boolean
998 # visibility "public" or "private"
1001 # attributes [CVarDefNode] or None
1005 child_attrs = ["attributes"]
1007 def analyse_declarations(self, env):
1009 if self.visibility == 'extern' and self.packed:
1010 error(self.pos, "Cannot declare extern struct as 'packed'")
1011 if self.attributes is not None:
1012 scope = StructOrUnionScope(self.name)
1013 self.entry = env.declare_struct_or_union(
1014 self.name, self.kind, scope, self.typedef_flag, self.pos,
1015 self.cname, visibility = self.visibility, api = self.api,
1016 packed = self.packed)
1017 if self.attributes is not None:
1018 if self.in_pxd and not env.in_cinclude:
1019 self.entry.defined_in_pxd = 1
1020 for attr in self.attributes:
1021 attr.analyse_declarations(env, scope)
1022 if self.visibility != 'extern':
1023 need_typedef_indirection = False
1024 for attr in scope.var_entries:
1026 while type.is_array:
1027 type = type.base_type
1028 if type == self.entry.type:
1029 error(attr.pos, "Struct cannot contain itself as a member.")
1030 if self.typedef_flag:
1032 type = type.base_type
1033 if type == self.entry.type:
1034 need_typedef_indirection = True
1035 if need_typedef_indirection:
1036 # C can't handle typedef structs that refer to themselves.
1037 struct_entry = self.entry
1038 self.entry = env.declare_typedef(
1039 self.name, struct_entry.type, self.pos,
1040 cname = self.cname, visibility='ignore')
1041 struct_entry.type.typedef_flag = False
1042 # FIXME: this might be considered a hack ;-)
1043 struct_entry.cname = struct_entry.type.cname = \
1044 '_' + self.entry.type.typedef_cname
1046 def analyse_expressions(self, env):
1049 def generate_execution_code(self, code):
1053 class CppClassNode(CStructOrUnionDefNode):
1056 # cname string or None
1057 # visibility "extern"
1059 # attributes [CVarDefNode] or None
1061 # base_classes [string]
1062 # templates [string] or None
1064 def analyse_declarations(self, env):
1066 if self.attributes is not None:
1067 scope = CppClassScope(self.name, env)
1068 base_class_types = []
1069 for base_class_name in self.base_classes:
1070 base_class_entry = env.lookup(base_class_name)
1071 if base_class_entry is None:
1072 error(self.pos, "'%s' not found" % base_class_name)
1073 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1074 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1076 base_class_types.append(base_class_entry.type)
1077 if self.templates is None:
1078 template_types = None
1080 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1081 self.entry = env.declare_cpp_class(
1082 self.name, scope, self.pos,
1083 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1084 if self.entry is None:
1086 self.entry.is_cpp_class = 1
1087 if self.attributes is not None:
1088 if self.in_pxd and not env.in_cinclude:
1089 self.entry.defined_in_pxd = 1
1090 for attr in self.attributes:
1091 attr.analyse_declarations(scope)
1093 class CEnumDefNode(StatNode):
1094 # name string or None
1095 # cname string or None
1096 # items [CEnumDefItemNode]
1097 # typedef_flag boolean
1098 # visibility "public" or "private"
1103 child_attrs = ["items"]
1105 def analyse_declarations(self, env):
1106 self.entry = env.declare_enum(self.name, self.pos,
1107 cname = self.cname, typedef_flag = self.typedef_flag,
1108 visibility = self.visibility, api = self.api)
1109 if self.items is not None:
1110 if self.in_pxd and not env.in_cinclude:
1111 self.entry.defined_in_pxd = 1
1112 for item in self.items:
1113 item.analyse_declarations(env, self.entry)
1115 def analyse_expressions(self, env):
1118 def generate_execution_code(self, code):
1119 if self.visibility == 'public' or self.api:
1120 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1121 for item in self.entry.enum_values:
1122 code.putln("%s = PyInt_FromLong(%s); %s" % (
1125 code.error_goto_if_null(temp, item.pos)))
1126 code.put_gotref(temp)
1127 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1128 Naming.module_cname,
1131 code.error_goto(item.pos)))
1132 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1133 code.funcstate.release_temp(temp)
1136 class CEnumDefItemNode(StatNode):
1138 # cname string or None
1139 # value ExprNode or None
1141 child_attrs = ["value"]
1143 def analyse_declarations(self, env, enum_entry):
1145 self.value.analyse_const_expression(env)
1146 if not self.value.type.is_int:
1147 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1148 self.value.analyse_const_expression(env)
1149 entry = env.declare_const(self.name, enum_entry.type,
1150 self.value, self.pos, cname = self.cname,
1151 visibility = enum_entry.visibility, api = enum_entry.api)
1152 enum_entry.enum_values.append(entry)
1155 class CTypeDefNode(StatNode):
1156 # base_type CBaseTypeNode
1157 # declarator CDeclaratorNode
1158 # visibility "public" or "private"
1162 child_attrs = ["base_type", "declarator"]
1164 def analyse_declarations(self, env):
1165 base = self.base_type.analyse(env)
1166 name_declarator, type = self.declarator.analyse(base, env)
1167 name = name_declarator.name
1168 cname = name_declarator.cname
1169 entry = env.declare_typedef(name, type, self.pos,
1170 cname = cname, visibility = self.visibility, api = self.api)
1171 if self.in_pxd and not env.in_cinclude:
1172 entry.defined_in_pxd = 1
1174 def analyse_expressions(self, env):
1176 def generate_execution_code(self, code):
1180 class FuncDefNode(StatNode, BlockNode):
1181 # Base class for function definition nodes.
1183 # return_type PyrexType
1184 # #filename string C name of filename string const
1185 # entry Symtab.Entry
1186 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1187 # needs_outer_scope boolean Whether or not this function requires outer scope
1188 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1192 needs_closure = False
1193 needs_outer_scope = False
1194 is_generator = False
1195 is_generator_body = False
1198 def analyse_default_values(self, env):
1199 genv = env.global_scope()
1201 for arg in self.args:
1205 arg.default.analyse_types(env)
1206 arg.default = arg.default.coerce_to(arg.type, genv)
1209 "This argument cannot have a default value")
1214 error(arg.pos, "Non-default argument following default argument")
1216 def align_argument_type(self, env, arg):
1217 directive_locals = self.directive_locals
1219 if arg.name in directive_locals:
1220 type_node = directive_locals[arg.name]
1221 other_type = type_node.analyse_as_type(env)
1222 if other_type is None:
1223 error(type_node.pos, "Not a type")
1224 elif (type is not PyrexTypes.py_object_type
1225 and not type.same_as(other_type)):
1226 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1227 error(type_node.pos, "Previous declaration here")
1229 arg.type = other_type
1232 def need_gil_acquisition(self, lenv):
1235 def create_local_scope(self, env):
1237 while genv.is_py_class_scope or genv.is_c_class_scope:
1238 genv = genv.outer_scope
1239 if self.needs_closure:
1240 lenv = ClosureScope(name=self.entry.name,
1242 scope_name=self.entry.cname)
1244 lenv = LocalScope(name=self.entry.name,
1247 lenv.return_type = self.return_type
1248 type = self.entry.type
1249 if type.is_cfunction:
1250 lenv.nogil = type.nogil and not type.with_gil
1251 self.local_scope = lenv
1252 lenv.directives = env.directives
1255 def generate_function_body(self, env, code):
1256 self.body.generate_execution_code(code)
1258 def generate_function_definitions(self, env, code):
1261 lenv = self.local_scope
1262 if lenv.is_closure_scope and not lenv.is_passthrough:
1263 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1264 Naming.outer_scope_cname)
1266 outer_scope_cname = Naming.outer_scope_cname
1267 lenv.mangle_closure_cnames(outer_scope_cname)
1268 # Generate closure function definitions
1269 self.body.generate_function_definitions(lenv, code)
1270 # generate lambda function definitions
1271 self.generate_lambda_definitions(lenv, code)
1273 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1274 self.entry.scope.is_c_class_scope)
1275 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1276 self.entry.scope.is_c_class_scope)
1277 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1279 if 'cython_unused' not in self.modifiers:
1280 self.modifiers = self.modifiers + ['cython_unused']
1282 preprocessor_guard = None
1283 if self.entry.is_special and not is_buffer_slot:
1284 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1286 preprocessor_guard = slot.preprocessor_guard_code()
1287 if (self.entry.name == '__long__' and
1288 not self.entry.scope.lookup_here('__int__')):
1289 preprocessor_guard = None
1291 profile = code.globalstate.directives['profile']
1292 if profile and lenv.nogil:
1293 warning(self.pos, "Cannot profile nogil function.", 1)
1296 code.globalstate.use_utility_code(profile_utility_code)
1298 # Generate C code for header and body of function
1299 code.enter_cfunc_scope()
1300 code.return_from_error_cleanup_label = code.new_label()
1302 # ----- Top-level constants used by this function
1303 code.mark_pos(self.pos)
1304 self.generate_cached_builtins_decls(lenv, code)
1305 # ----- Function header
1308 if preprocessor_guard:
1309 code.putln(preprocessor_guard)
1311 with_pymethdef = self.needs_assignment_synthesis(env, code)
1313 self.py_func.generate_function_header(code,
1314 with_pymethdef = with_pymethdef,
1316 self.generate_function_header(code,
1317 with_pymethdef = with_pymethdef)
1318 # ----- Local variable declarations
1319 # Find function scope
1321 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1322 cenv = cenv.outer_scope
1323 if self.needs_closure:
1324 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1326 elif self.needs_outer_scope:
1327 if lenv.is_passthrough:
1328 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1330 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1332 self.generate_argument_declarations(lenv, code)
1333 for entry in lenv.var_entries:
1334 if not entry.in_closure:
1335 code.put_var_declaration(entry)
1337 if not self.return_type.is_void:
1338 if self.return_type.is_pyobject:
1342 (self.return_type.declaration_code(Naming.retval_cname),
1344 tempvardecl_code = code.insertion_point()
1346 code.put_declare_refcount_context()
1347 self.generate_keyword_list(code)
1349 code.put_trace_declarations()
1350 # ----- Extern library function declarations
1351 lenv.generate_library_function_declarations(code)
1352 # ----- GIL acquisition
1353 acquire_gil = self.acquire_gil
1355 env.use_utility_code(force_init_threads_utility_code)
1356 code.putln("#ifdef WITH_THREAD")
1357 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1358 code.putln("#endif")
1359 # ----- set up refnanny
1361 code.put_setup_refcount_context(self.entry.name)
1362 # ----- Automatic lead-ins for certain special functions
1363 if is_getbuffer_slot:
1364 self.getbuffer_init(code)
1365 # ----- Create closure scope object
1366 if self.needs_closure:
1367 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1368 Naming.cur_scope_cname,
1369 lenv.scope_class.type.declaration_code(''),
1370 lenv.scope_class.type.typeptr_cname,
1371 lenv.scope_class.type.typeptr_cname,
1372 Naming.empty_tuple))
1373 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1374 if is_getbuffer_slot:
1375 self.getbuffer_error_cleanup(code)
1377 code.put_finish_refcount_context()
1378 # FIXME: what if the error return value is a Python value?
1379 code.putln("return %s;" % self.error_value())
1381 code.put_gotref(Naming.cur_scope_cname)
1382 # Note that it is unsafe to decref the scope at this point.
1383 if self.needs_outer_scope:
1384 code.putln("%s = (%s)%s;" % (
1386 cenv.scope_class.type.declaration_code(''),
1388 if lenv.is_passthrough:
1389 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1390 elif self.needs_closure:
1391 # inner closures own a reference to their outer parent
1392 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1393 code.put_giveref(outer_scope_cname)
1394 # ----- Trace function call
1396 # this looks a bit late, but if we don't get here due to a
1397 # fatal error before hand, it's not really worth tracing
1398 code.put_trace_call(self.entry.name, self.pos)
1399 # ----- Fetch arguments
1400 self.generate_argument_parsing_code(env, code)
1401 # If an argument is assigned to in the body, we must
1402 # incref it to properly keep track of refcounts.
1403 for entry in lenv.arg_entries:
1404 if entry.type.is_pyobject:
1405 if (acquire_gil or entry.assignments) and not entry.in_closure:
1406 code.put_var_incref(entry)
1407 # ----- Initialise local variables
1408 for entry in lenv.var_entries:
1409 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1410 code.put_init_var_to_py_none(entry)
1411 # ----- Initialise local buffer auxiliary variables
1412 for entry in lenv.var_entries + lenv.arg_entries:
1413 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1414 code.putln("%s.buf = NULL;" %
1415 entry.buffer_aux.buffer_info_var.cname)
1416 # ----- Check and convert arguments
1417 self.generate_argument_type_tests(code)
1418 # ----- Acquire buffer arguments
1419 for entry in lenv.arg_entries:
1420 if entry.type.is_buffer:
1421 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1423 # -------------------------
1424 # ----- Function body -----
1425 # -------------------------
1426 self.generate_function_body(env, code)
1428 # ----- Default return value
1430 if self.return_type.is_pyobject:
1431 #if self.return_type.is_extension_type:
1432 # lhs = "(PyObject *)%s" % Naming.retval_cname
1434 lhs = Naming.retval_cname
1435 code.put_init_to_py_none(lhs, self.return_type)
1437 val = self.return_type.default_value
1439 code.putln("%s = %s;" % (Naming.retval_cname, val))
1440 # ----- Error cleanup
1441 if code.error_label in code.labels_used:
1442 code.put_goto(code.return_label)
1443 code.put_label(code.error_label)
1444 for cname, type in code.funcstate.all_managed_temps():
1445 code.put_xdecref(cname, type)
1447 # Clean up buffers -- this calls a Python function
1448 # so need to save and restore error state
1449 buffers_present = len(lenv.buffer_entries) > 0
1451 code.globalstate.use_utility_code(restore_exception_utility_code)
1452 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1453 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1454 for entry in lenv.buffer_entries:
1455 Buffer.put_release_buffer_code(code, entry)
1456 #code.putln("%s = 0;" % entry.cname)
1457 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1459 err_val = self.error_value()
1460 exc_check = self.caller_will_check_exceptions()
1461 if err_val is not None or exc_check:
1462 # TODO: Fix exception tracing (though currently unused by cProfile).
1463 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1464 # code.put_trace_exception()
1465 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1467 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1468 % self.entry.qualified_name, 0)
1470 '__Pyx_WriteUnraisable("%s");' %
1471 self.entry.qualified_name)
1472 env.use_utility_code(unraisable_exception_utility_code)
1473 env.use_utility_code(restore_exception_utility_code)
1474 default_retval = self.return_type.default_value
1475 if err_val is None and default_retval:
1476 err_val = default_retval
1477 if err_val is not None:
1478 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1480 if is_getbuffer_slot:
1481 self.getbuffer_error_cleanup(code)
1483 # If we are using the non-error cleanup section we should
1484 # jump past it if we have an error. The if-test below determine
1485 # whether this section is used.
1486 if buffers_present or is_getbuffer_slot:
1487 code.put_goto(code.return_from_error_cleanup_label)
1490 # ----- Non-error return cleanup
1491 code.put_label(code.return_label)
1492 for entry in lenv.buffer_entries:
1494 Buffer.put_release_buffer_code(code, entry)
1495 if is_getbuffer_slot:
1496 self.getbuffer_normal_cleanup(code)
1497 # ----- Return cleanup for both error and no-error return
1498 code.put_label(code.return_from_error_cleanup_label)
1499 if not Options.init_local_none:
1500 for entry in lenv.var_entries:
1501 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1502 entry.xdecref_cleanup = 1
1504 for entry in lenv.var_entries:
1505 if entry.type.is_pyobject:
1506 if entry.used and not entry.in_closure:
1507 code.put_var_decref(entry)
1508 # Decref any increfed args
1509 for entry in lenv.arg_entries:
1510 if entry.type.is_pyobject:
1511 if (acquire_gil or entry.assignments) and not entry.in_closure:
1512 code.put_var_decref(entry)
1513 if self.needs_closure:
1514 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1517 # This code is duplicated in ModuleNode.generate_module_init_func
1519 default_retval = self.return_type.default_value
1520 err_val = self.error_value()
1521 if err_val is None and default_retval:
1522 err_val = default_retval
1523 if self.return_type.is_pyobject:
1524 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1526 if self.entry.is_special and self.entry.name == "__hash__":
1527 # Returning -1 for __hash__ is supposed to signal an error
1528 # We do as Python instances and coerce -1 into -2.
1529 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1530 Naming.retval_cname, Naming.retval_cname))
1533 if self.return_type.is_pyobject:
1534 code.put_trace_return(Naming.retval_cname)
1536 code.put_trace_return("Py_None")
1538 code.put_finish_refcount_context()
1541 code.putln("#ifdef WITH_THREAD")
1542 code.putln("PyGILState_Release(_save);")
1543 code.putln("#endif")
1545 if not self.return_type.is_void:
1546 code.putln("return %s;" % Naming.retval_cname)
1550 if preprocessor_guard:
1551 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1553 # ----- Go back and insert temp variable declarations
1554 tempvardecl_code.put_temp_declarations(code.funcstate)
1555 # ----- Python version
1556 code.exit_cfunc_scope()
1558 self.py_func.generate_function_definitions(env, code)
1559 self.generate_wrapper_functions(code)
1561 def declare_argument(self, env, arg):
1562 if arg.type.is_void:
1563 error(arg.pos, "Invalid use of 'void'")
1564 elif not arg.type.is_complete() and not arg.type.is_array:
1566 "Argument type '%s' is incomplete" % arg.type)
1567 return env.declare_arg(arg.name, arg.type, arg.pos)
1569 def generate_arg_type_test(self, arg, code):
1570 # Generate type test for one argument.
1571 if arg.type.typeobj_is_available():
1572 code.globalstate.use_utility_code(arg_type_test_utility_code)
1573 typeptr_cname = arg.type.typeptr_cname
1574 arg_code = "((PyObject *)%s)" % arg.entry.cname
1576 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1581 arg.type.is_builtin_type,
1582 code.error_goto(arg.pos)))
1584 error(arg.pos, "Cannot test type of extern C class "
1585 "without type object name specification")
1587 def generate_arg_none_check(self, arg, code):
1588 # Generate None check for one argument.
1589 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1590 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1592 code.error_goto(arg.pos)))
1595 def generate_wrapper_functions(self, code):
1598 def generate_execution_code(self, code):
1599 # Evaluate and store argument default values
1600 for arg in self.args:
1601 default = arg.default
1603 if not default.is_literal:
1604 default.generate_evaluation_code(code)
1605 default.make_owned_reference(code)
1606 result = default.result_as(arg.type)
1609 arg.calculate_default_value_code(code),
1611 if arg.type.is_pyobject:
1612 code.put_giveref(default.result())
1613 default.generate_post_assignment_code(code)
1614 default.free_temps(code)
1615 # For Python class methods, create and store function object
1617 self.assmt.generate_execution_code(code)
1620 # Special code for the __getbuffer__ function
1622 def getbuffer_init(self, code):
1623 info = self.local_scope.arg_entries[1].cname
1624 # Python 3.0 betas have a bug in memoryview which makes it call
1625 # getbuffer with a NULL parameter. For now we work around this;
1626 # the following block should be removed when this bug is fixed.
1627 code.putln("if (%s != NULL) {" % info)
1628 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1629 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1632 def getbuffer_error_cleanup(self, code):
1633 info = self.local_scope.arg_entries[1].cname
1634 code.putln("if (%s != NULL && %s->obj != NULL) {"
1636 code.put_gotref("%s->obj" % info)
1637 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;"
1641 def getbuffer_normal_cleanup(self, code):
1642 info = self.local_scope.arg_entries[1].cname
1643 code.putln("if (%s != NULL && %s->obj == Py_None) {" % (info, info))
1644 code.put_gotref("Py_None")
1645 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1648 class CFuncDefNode(FuncDefNode):
1649 # C function definition.
1651 # modifiers ['inline']
1652 # visibility 'private' or 'public' or 'extern'
1653 # base_type CBaseTypeNode
1654 # declarator CDeclaratorNode
1657 # decorators [DecoratorNode] list of decorators
1659 # with_gil boolean Acquire GIL around body
1661 # py_func wrapper for calling from Python
1662 # overridable whether or not this is a cpdef function
1663 # inline_in_pxd whether this is an inline function in a pxd file
1665 child_attrs = ["base_type", "declarator", "body", "py_func"]
1667 inline_in_pxd = False
1669 directive_locals = None
1671 def unqualified_name(self):
1672 return self.entry.name
1674 def analyse_declarations(self, env):
1675 if self.directive_locals is None:
1676 self.directive_locals = {}
1677 self.directive_locals.update(env.directives['locals'])
1678 base_type = self.base_type.analyse(env)
1679 # The 2 here is because we need both function and argument names.
1680 if isinstance(self.declarator, CFuncDeclaratorNode):
1681 name_declarator, type = self.declarator.analyse(base_type, env,
1682 nonempty = 2 * (self.body is not None),
1683 directive_locals = self.directive_locals)
1685 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1686 if not type.is_cfunction:
1688 "Suite attached to non-function declaration")
1689 # Remember the actual type according to the function header
1690 # written here, because the type in the symbol table entry
1691 # may be different if we're overriding a C method inherited
1692 # from the base type of an extension type.
1694 type.is_overridable = self.overridable
1695 declarator = self.declarator
1696 while not hasattr(declarator, 'args'):
1697 declarator = declarator.base
1698 self.args = declarator.args
1699 for formal_arg, type_arg in zip(self.args, type.args):
1700 self.align_argument_type(env, type_arg)
1701 formal_arg.type = type_arg.type
1702 formal_arg.name = type_arg.name
1703 formal_arg.cname = type_arg.cname
1704 if type_arg.type.is_buffer and 'inline' in self.modifiers:
1705 warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1)
1706 name = name_declarator.name
1707 cname = name_declarator.cname
1708 self.entry = env.declare_cfunction(
1709 name, type, self.pos,
1710 cname = cname, visibility = self.visibility,
1711 defining = self.body is not None,
1712 api = self.api, modifiers = self.modifiers)
1713 self.entry.inline_func_in_pxd = self.inline_in_pxd
1714 self.return_type = type.return_type
1715 if self.return_type.is_array and visibility != 'extern':
1717 "Function cannot return an array")
1719 if self.overridable and not env.is_module_scope:
1720 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1721 # An error will be produced in the cdef function
1722 self.overridable = False
1724 if self.overridable:
1726 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1727 self.py_func = DefNode(pos = self.pos,
1728 name = self.entry.name,
1731 starstar_arg = None,
1733 body = py_func_body,
1735 self.py_func.is_module_scope = env.is_module_scope
1736 self.py_func.analyse_declarations(env)
1737 self.entry.as_variable = self.py_func.entry
1738 # Reset scope entry the above cfunction
1739 env.entries[name] = self.entry
1740 if not env.is_module_scope or Options.lookup_module_cpdef:
1741 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1742 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1743 self.create_local_scope(env)
1745 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1747 args = self.type.args
1748 if omit_optional_args:
1749 args = args[:len(args) - self.type.optional_arg_count]
1750 arg_names = [arg.name for arg in args]
1752 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1754 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1755 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1756 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1757 c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1-is_module_scope:]], wrapper_call=skip_dispatch)
1758 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1760 def declare_arguments(self, env):
1761 for arg in self.type.args:
1763 error(arg.pos, "Missing argument name")
1764 self.declare_argument(env, arg)
1766 def need_gil_acquisition(self, lenv):
1767 return self.type.with_gil
1769 def nogil_check(self, env):
1771 with_gil = type.with_gil
1772 if type.nogil and not with_gil:
1773 if type.return_type.is_pyobject:
1775 "Function with Python return type cannot be declared nogil")
1776 for entry in self.local_scope.var_entries:
1777 if entry.type.is_pyobject:
1778 error(self.pos, "Function declared nogil has Python locals or temporaries")
1780 def analyse_expressions(self, env):
1781 self.local_scope.directives = env.directives
1782 if self.py_func is not None:
1783 # this will also analyse the default values
1784 self.py_func.analyse_expressions(env)
1786 self.analyse_default_values(env)
1787 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1789 def needs_assignment_synthesis(self, env, code=None):
1792 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1795 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1796 arg_decls.append(arg.declaration_code())
1797 if with_dispatch and self.overridable:
1798 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1799 if type.optional_arg_count and with_opt_args:
1800 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1801 if type.has_varargs:
1802 arg_decls.append("...")
1804 arg_decls = ["void"]
1806 cname = self.entry.func_cname
1807 entity = type.function_header_code(cname, ', '.join(arg_decls))
1808 if self.entry.visibility == 'private':
1809 storage_class = "static "
1814 if 'inline' in self.modifiers:
1815 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1817 modifiers = "%s " % ' '.join(self.modifiers).upper()
1819 header = self.return_type.declaration_code(entity, dll_linkage=dll_linkage)
1820 #print (storage_class, modifiers, header)
1821 code.putln("%s%s%s {" % (storage_class, modifiers, header))
1823 def generate_argument_declarations(self, env, code):
1824 for arg in self.args:
1826 result = arg.calculate_default_value_code(code)
1827 code.putln('%s = %s;' % (
1828 arg.type.declaration_code(arg.cname), result))
1830 def generate_keyword_list(self, code):
1833 def generate_argument_parsing_code(self, env, code):
1835 if self.type.optional_arg_count:
1836 code.putln('if (%s) {' % Naming.optional_args_cname)
1837 for arg in self.args:
1839 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1840 declarator = arg.declarator
1841 while not hasattr(declarator, 'name'):
1842 declarator = declarator.base
1843 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1845 for _ in range(self.type.optional_arg_count):
1849 def generate_argument_conversion_code(self, code):
1852 def generate_argument_type_tests(self, code):
1853 # Generate type tests for args whose type in a parent
1854 # class is a supertype of the declared type.
1855 for arg in self.type.args:
1856 if arg.needs_type_test:
1857 self.generate_arg_type_test(arg, code)
1858 elif arg.type.is_pyobject and not arg.accept_none:
1859 self.generate_arg_none_check(arg, code)
1861 def error_value(self):
1862 if self.return_type.is_pyobject:
1866 return self.entry.type.exception_value
1868 def caller_will_check_exceptions(self):
1869 return self.entry.type.exception_check
1871 def generate_wrapper_functions(self, code):
1872 # If the C signature of a function has changed, we need to generate
1873 # wrappers to put in the slots here.
1876 func_type = entry.type
1877 while entry.prev_entry is not None:
1879 entry = entry.prev_entry
1880 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1882 self.generate_function_header(code,
1884 with_dispatch = entry.type.is_overridable,
1885 with_opt_args = entry.type.optional_arg_count,
1886 cname = entry.func_cname)
1887 if not self.return_type.is_void:
1889 args = self.type.args
1890 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1891 if entry.type.is_overridable:
1892 arglist.append(Naming.skip_dispatch_cname)
1893 elif func_type.is_overridable:
1895 if entry.type.optional_arg_count:
1896 arglist.append(Naming.optional_args_cname)
1897 elif func_type.optional_arg_count:
1898 arglist.append('NULL')
1899 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1903 class PyArgDeclNode(Node):
1904 # Argument which must be a Python object (used
1905 # for * and ** arguments).
1908 # entry Symtab.Entry
1909 # annotation ExprNode or None Py3 argument annotation
1912 def generate_function_definitions(self, env, code):
1913 self.entry.generate_function_definitions(env, code)
1915 class DecoratorNode(Node):
1918 # decorator NameNode or CallNode or AttributeNode
1919 child_attrs = ['decorator']
1922 class DefNode(FuncDefNode):
1923 # A Python function definition.
1925 # name string the Python name of the function
1926 # lambda_name string the internal name of a lambda 'function'
1927 # decorators [DecoratorNode] list of decorators
1928 # args [CArgDeclNode] formal arguments
1929 # star_arg PyArgDeclNode or None * argument
1930 # starstar_arg PyArgDeclNode or None ** argument
1931 # doc EncodedString or None
1933 # return_type_annotation
1934 # ExprNode or None the Py3 return type annotation
1936 # The following subnode is constructed internally
1937 # when the def statement is inside a Python class definition.
1939 # assmt AssignmentNode Function construction/assignment
1941 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1946 num_required_kw_args = 0
1947 reqd_kw_flags_cname = "0"
1949 no_assignment_synthesis = 0
1951 return_type_annotation = None
1959 def __init__(self, pos, **kwds):
1960 FuncDefNode.__init__(self, pos, **kwds)
1962 for arg in self.args:
1969 self.num_kwonly_args = k
1970 self.num_required_kw_args = rk
1971 self.num_required_args = r
1973 def as_cfunction(self, cfunc=None, scope=None):
1975 error(self.star_arg.pos, "cdef function cannot have star argument")
1976 if self.starstar_arg:
1977 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1980 for formal_arg in self.args:
1981 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1982 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1984 type = py_object_type,
1985 pos = formal_arg.pos))
1986 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1988 has_varargs = False,
1989 exception_value = None,
1990 exception_check = False,
1993 is_overridable = True)
1994 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1998 cfunc_type = cfunc.type
1999 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
2000 error(self.pos, "wrong number of arguments")
2001 error(cfunc.pos, "previous declaration here")
2002 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
2003 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
2004 is_self_arg = (i == 0 and scope.is_c_class_scope))
2005 if type is None or type is PyrexTypes.py_object_type:
2006 formal_arg.type = type_arg.type
2007 formal_arg.name_declarator = name_declarator
2009 if cfunc_type.exception_value is None:
2010 exception_value = None
2012 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
2013 declarator = CFuncDeclaratorNode(self.pos,
2014 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
2016 has_varargs = False,
2017 exception_check = cfunc_type.exception_check,
2018 exception_value = exception_value,
2019 with_gil = cfunc_type.with_gil,
2020 nogil = cfunc_type.nogil)
2021 return CFuncDefNode(self.pos,
2023 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
2024 declarator = declarator,
2027 overridable = cfunc_type.is_overridable,
2029 with_gil = cfunc_type.with_gil,
2030 nogil = cfunc_type.nogil,
2031 visibility = 'private',
2033 directive_locals = getattr(cfunc, 'directive_locals', {}))
2035 def is_cdef_func_compatible(self):
2036 """Determines if the function's signature is compatible with a
2037 cdef function. This can be used before calling
2038 .as_cfunction() to see if that will be successful.
2040 if self.needs_closure:
2042 if self.star_arg or self.starstar_arg:
2046 def analyse_declarations(self, env):
2047 self.is_classmethod = self.is_staticmethod = False
2049 for decorator in self.decorators:
2050 func = decorator.decorator
2052 self.is_classmethod |= func.name == 'classmethod'
2053 self.is_staticmethod |= func.name == 'staticmethod'
2055 if self.is_classmethod and env.lookup_here('classmethod'):
2056 # classmethod() was overridden - not much we can do here ...
2057 self.is_classmethod = False
2058 if self.is_staticmethod and env.lookup_here('staticmethod'):
2059 # staticmethod() was overridden - not much we can do here ...
2060 self.is_staticmethod = False
2062 if self.name == '__new__' and env.is_py_class_scope:
2063 self.is_staticmethod = 1
2065 self.analyse_argument_types(env)
2066 if self.name == '<lambda>':
2067 self.declare_lambda_function(env)
2069 self.declare_pyfunction(env)
2070 self.analyse_signature(env)
2071 self.return_type = self.entry.signature.return_type()
2072 self.create_local_scope(env)
2074 def analyse_argument_types(self, env):
2075 directive_locals = self.directive_locals = env.directives['locals']
2076 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2077 for arg in self.args:
2078 if hasattr(arg, 'name'):
2079 name_declarator = None
2081 base_type = arg.base_type.analyse(env)
2082 name_declarator, type = \
2083 arg.declarator.analyse(base_type, env)
2084 arg.name = name_declarator.name
2086 self.align_argument_type(env, arg)
2087 if name_declarator and name_declarator.cname:
2089 "Python function argument cannot have C name specification")
2090 arg.type = arg.type.as_argument_type()
2092 arg.needs_conversion = 0
2093 arg.needs_type_test = 0
2095 if arg.type.is_pyobject:
2097 arg.accept_none = True
2099 arg.accept_none = False
2100 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2101 if arg.default and arg.default.constant_result is None:
2102 # special case: def func(MyType obj = None)
2103 arg.accept_none = True
2105 # default depends on compiler directive
2106 arg.accept_none = allow_none_for_extension_args
2108 # probably just a plain 'object'
2109 arg.accept_none = True
2111 arg.accept_none = True # won't be used, but must be there
2113 error(arg.pos, "Only Python type arguments can have 'not None'")
2115 error(arg.pos, "Only Python type arguments can have 'or None'")
2117 def analyse_signature(self, env):
2118 if self.entry.is_special:
2120 error(self.pos, "special functions of cdef classes cannot have decorators")
2121 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2122 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2123 # Use the simpler calling signature for zero- and one-argument functions.
2124 if self.entry.signature is TypeSlots.pyfunction_signature:
2125 if len(self.args) == 0:
2126 self.entry.signature = TypeSlots.pyfunction_noargs
2127 elif len(self.args) == 1:
2128 if self.args[0].default is None and not self.args[0].kw_only:
2129 self.entry.signature = TypeSlots.pyfunction_onearg
2130 elif self.entry.signature is TypeSlots.pymethod_signature:
2131 if len(self.args) == 1:
2132 self.entry.signature = TypeSlots.unaryfunc
2133 elif len(self.args) == 2:
2134 if self.args[1].default is None and not self.args[1].kw_only:
2135 self.entry.signature = TypeSlots.ibinaryfunc
2137 sig = self.entry.signature
2138 nfixed = sig.num_fixed_args()
2139 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2140 and len(self.args) == 0 and self.star_arg:
2141 # this is the only case where a diverging number of
2142 # arguments is not an error - when we have no explicit
2143 # 'self' parameter as in method(*args)
2144 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2145 self.self_in_stararg = 1
2148 for i in range(min(nfixed, len(self.args))):
2151 if sig.is_self_arg(i) and not self.is_staticmethod:
2152 if self.is_classmethod:
2154 arg.hdr_type = arg.type = Builtin.type_type
2157 arg.hdr_type = arg.type = env.parent_type
2158 arg.needs_conversion = 0
2160 arg.hdr_type = sig.fixed_arg_type(i)
2161 if not arg.type.same_as(arg.hdr_type):
2162 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2163 arg.needs_type_test = 1
2165 arg.needs_conversion = 1
2166 if arg.needs_conversion:
2167 arg.hdr_cname = Naming.arg_prefix + arg.name
2169 arg.hdr_cname = Naming.var_prefix + arg.name
2171 if nfixed > len(self.args):
2172 self.bad_signature()
2174 elif nfixed < len(self.args):
2175 if not sig.has_generic_args:
2176 self.bad_signature()
2177 for arg in self.args:
2178 if arg.is_generic and \
2179 (arg.type.is_extension_type or arg.type.is_builtin_type):
2180 arg.needs_type_test = 1
2182 def bad_signature(self):
2183 sig = self.entry.signature
2184 expected_str = "%d" % sig.num_fixed_args()
2185 if sig.has_generic_args:
2186 expected_str = expected_str + " or more"
2188 if name.startswith("__") and name.endswith("__"):
2189 desc = "Special method"
2193 "%s %s has wrong number of arguments "
2194 "(%d declared, %s expected)" % (
2195 desc, self.name, len(self.args), expected_str))
2197 def signature_has_nongeneric_args(self):
2198 argcount = len(self.args)
2199 if argcount == 0 or (
2200 argcount == 1 and (self.args[0].is_self_arg or
2201 self.args[0].is_type_arg)):
2205 def signature_has_generic_args(self):
2206 return self.entry.signature.has_generic_args
2208 def declare_pyfunction(self, env):
2209 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2211 entry = env.lookup_here(name)
2212 if entry and entry.type.is_cfunction and not self.is_wrapper:
2213 warning(self.pos, "Overriding cdef method with def method.", 5)
2214 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2216 prefix = env.next_id(env.scope_prefix)
2218 entry.func_cname = \
2219 Naming.pyfunc_prefix + prefix + name
2220 entry.pymethdef_cname = \
2221 Naming.pymethdef_prefix + prefix + name
2222 if Options.docstrings:
2223 entry.doc = embed_position(self.pos, self.doc)
2225 Naming.funcdoc_prefix + prefix + name
2226 if entry.is_special:
2227 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2228 entry.wrapperbase_cname = None
2230 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2234 def declare_lambda_function(self, env):
2236 prefix = env.scope_prefix
2238 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2239 entry = env.declare_lambda_function(func_cname, self.pos)
2240 entry.pymethdef_cname = \
2241 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2242 entry.qualified_name = env.qualify_name(self.lambda_name)
2246 def declare_arguments(self, env):
2247 for arg in self.args:
2249 error(arg.pos, "Missing argument name")
2251 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2252 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2253 if arg.needs_conversion:
2254 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2255 if arg.type.is_pyobject:
2256 arg.entry.init = "0"
2257 arg.entry.init_to_none = 0
2259 arg.entry = self.declare_argument(env, arg)
2261 arg.entry.is_self_arg = arg.is_self_arg
2263 if arg.is_self_arg or arg.is_type_arg or \
2264 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2265 arg.entry.is_declared_generic = 1
2266 self.declare_python_arg(env, self.star_arg)
2267 self.declare_python_arg(env, self.starstar_arg)
2269 def declare_python_arg(self, env, arg):
2271 if env.directives['infer_types'] != False:
2272 type = PyrexTypes.unspecified_type
2274 type = py_object_type
2275 entry = env.declare_var(arg.name, type, arg.pos)
2278 entry.init_to_none = 0
2279 entry.xdecref_cleanup = 1
2281 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2283 def analyse_expressions(self, env):
2284 self.local_scope.directives = env.directives
2285 self.analyse_default_values(env)
2286 if self.needs_assignment_synthesis(env):
2287 # Shouldn't we be doing this at the module level too?
2288 self.synthesize_assignment_node(env)
2290 def needs_assignment_synthesis(self, env, code=None):
2291 if self.no_assignment_synthesis:
2293 # Should enable for module level as well, that will require more testing...
2294 if self.entry.is_anonymous:
2296 if env.is_module_scope:
2298 return env.directives['binding']
2300 return code.globalstate.directives['binding']
2301 return env.is_py_class_scope or env.is_closure_scope
2303 def synthesize_assignment_node(self, env):
2306 while genv.is_py_class_scope or genv.is_c_class_scope:
2307 genv = genv.outer_scope
2309 if genv.is_closure_scope:
2310 rhs = ExprNodes.InnerFunctionNode(
2311 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2313 rhs = ExprNodes.PyCFunctionNode(
2314 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2316 if env.is_py_class_scope:
2317 if not self.is_staticmethod and not self.is_classmethod:
2320 self.assmt = SingleAssignmentNode(self.pos,
2321 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2323 self.assmt.analyse_declarations(env)
2324 self.assmt.analyse_expressions(env)
2326 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2328 sig = self.entry.signature
2329 if sig.has_dummy_arg or self.self_in_stararg:
2330 arg_code_list.append(
2331 "PyObject *%s" % Naming.self_cname)
2332 for arg in self.args:
2333 if not arg.is_generic:
2334 if arg.is_self_arg or arg.is_type_arg:
2335 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2337 arg_code_list.append(
2338 arg.hdr_type.declaration_code(arg.hdr_cname))
2339 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2340 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2341 if (self.entry.scope.is_c_class_scope and self.entry.name == "__ipow__"):
2342 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2343 if sig.has_generic_args:
2344 arg_code_list.append(
2345 "PyObject *%s, PyObject *%s"
2346 % (Naming.args_cname, Naming.kwds_cname))
2347 arg_code = ", ".join(arg_code_list)
2348 dc = self.return_type.declaration_code(self.entry.func_cname)
2349 mf = " ".join(self.modifiers).upper()
2351 header = "static %s%s(%s)" % (mf, dc, arg_code)
2352 code.putln("%s; /*proto*/" % header)
2355 if (Options.docstrings and self.entry.doc and
2356 not self.entry.scope.is_property_scope and
2357 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2358 docstr = self.entry.doc
2359 if docstr.is_unicode:
2360 docstr = docstr.utf8encode()
2362 'static char %s[] = "%s";' % (
2363 self.entry.doc_cname,
2364 split_string_literal(escape_byte_string(docstr))))
2365 if self.entry.is_special:
2367 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2370 "static PyMethodDef %s = " %
2371 self.entry.pymethdef_cname)
2372 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2373 code.putln("%s {" % header)
2375 def generate_argument_declarations(self, env, code):
2376 for arg in self.args:
2377 if arg.is_generic: # or arg.needs_conversion:
2378 if arg.needs_conversion:
2379 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2380 elif not arg.entry.in_closure:
2381 code.put_var_declaration(arg.entry)
2383 def generate_keyword_list(self, code):
2384 if self.signature_has_generic_args() and \
2385 self.signature_has_nongeneric_args():
2387 "static PyObject **%s[] = {" %
2388 Naming.pykwdlist_cname)
2389 for arg in self.args:
2391 pystring_cname = code.intern_identifier(arg.name)
2392 code.put('&%s,' % pystring_cname)
2395 def generate_argument_parsing_code(self, env, code):
2396 # Generate fast equivalent of PyArg_ParseTuple call for
2397 # generic arguments, if any, including args/kwargs
2398 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2399 # get rid of unused argument warning
2400 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2402 old_error_label = code.new_error_label()
2403 our_error_label = code.error_label
2404 end_label = code.new_label("argument_unpacking_done")
2406 has_kwonly_args = self.num_kwonly_args > 0
2407 has_star_or_kw_args = self.star_arg is not None \
2408 or self.starstar_arg is not None or has_kwonly_args
2410 for arg in self.args:
2411 if not arg.type.is_pyobject:
2412 done = arg.type.create_from_py_utility_code(env)
2413 if not done: pass # will fail later
2415 if not self.signature_has_generic_args():
2416 if has_star_or_kw_args:
2417 error(self.pos, "This method cannot have * or keyword arguments")
2418 self.generate_argument_conversion_code(code)
2420 elif not self.signature_has_nongeneric_args():
2421 # func(*args) or func(**kw) or func(*args, **kw)
2422 self.generate_stararg_copy_code(code)
2425 positional_args = []
2427 for arg in self.args:
2428 arg_entry = arg.entry
2431 if not arg.is_self_arg and not arg.is_type_arg:
2433 kw_only_args.append(arg)
2435 positional_args.append(arg)
2437 kw_only_args.append(arg)
2438 elif not arg.is_self_arg and not arg.is_type_arg:
2439 positional_args.append(arg)
2441 self.generate_tuple_and_keyword_parsing_code(
2442 positional_args, kw_only_args, end_label, code)
2444 code.error_label = old_error_label
2445 if code.label_used(our_error_label):
2446 if not code.label_used(end_label):
2447 code.put_goto(end_label)
2448 code.put_label(our_error_label)
2449 if has_star_or_kw_args:
2450 self.generate_arg_decref(self.star_arg, code)
2451 if self.starstar_arg:
2452 if self.starstar_arg.entry.xdecref_cleanup:
2453 code.put_var_xdecref_clear(self.starstar_arg.entry)
2455 code.put_var_decref_clear(self.starstar_arg.entry)
2456 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2457 # The arguments are put into the closure one after the
2458 # other, so when type errors are found, all references in
2459 # the closure instance must be properly ref-counted to
2460 # facilitate generic closure instance deallocation. In
2461 # the case of an argument type error, it's best to just
2462 # DECREF+clear the already handled references, as this
2463 # frees their references as early as possible.
2464 for arg in self.args:
2465 if arg.type.is_pyobject and arg.entry.in_closure:
2466 code.put_var_xdecref_clear(arg.entry)
2467 if self.needs_closure:
2468 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2469 code.put_finish_refcount_context()
2470 code.putln("return %s;" % self.error_value())
2471 if code.label_used(end_label):
2472 code.put_label(end_label)
2474 # fix refnanny view on closure variables here, instead of
2475 # doing it separately for each arg parsing special case
2476 if self.star_arg and self.star_arg.entry.in_closure:
2477 code.put_var_giveref(self.star_arg.entry)
2478 if self.starstar_arg and self.starstar_arg.entry.in_closure:
2479 code.put_var_giveref(self.starstar_arg.entry)
2480 for arg in self.args:
2481 if arg.type.is_pyobject and arg.entry.in_closure:
2482 code.put_var_giveref(arg.entry)
2484 def generate_arg_assignment(self, arg, item, code):
2485 if arg.type.is_pyobject:
2487 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2489 if entry.in_closure:
2490 code.put_incref(item, PyrexTypes.py_object_type)
2491 code.putln("%s = %s;" % (entry.cname, item))
2493 func = arg.type.from_py_function
2495 code.putln("%s = %s(%s); %s" % (
2499 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2501 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2503 def generate_arg_xdecref(self, arg, code):
2505 code.put_var_xdecref_clear(arg.entry)
2507 def generate_arg_decref(self, arg, code):
2509 code.put_var_decref_clear(arg.entry)
2511 def generate_stararg_copy_code(self, code):
2512 if not self.star_arg:
2513 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2514 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2516 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2517 self.name, Naming.args_cname, self.error_value()))
2520 if self.starstar_arg:
2522 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2524 kwarg_check = "%s" % Naming.kwds_cname
2526 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2527 Naming.kwds_cname, Naming.kwds_cname)
2528 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2530 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2531 kwarg_check, Naming.kwds_cname, self.name,
2532 bool(self.starstar_arg), self.error_value()))
2534 if self.starstar_arg:
2535 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2536 self.starstar_arg.entry.cname,
2539 code.putln("if (unlikely(!%s)) return %s;" % (
2540 self.starstar_arg.entry.cname, self.error_value()))
2541 self.starstar_arg.entry.xdecref_cleanup = 0
2542 code.put_gotref(self.starstar_arg.entry.cname)
2544 if self.self_in_stararg:
2545 # need to create a new tuple with 'self' inserted as first item
2546 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2547 self.star_arg.entry.cname,
2549 self.star_arg.entry.cname))
2550 if self.starstar_arg:
2552 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2553 code.putln("return %s;" % self.error_value())
2556 code.putln("return %s;" % self.error_value())
2557 code.put_gotref(self.star_arg.entry.cname)
2558 code.put_incref(Naming.self_cname, py_object_type)
2559 code.put_giveref(Naming.self_cname)
2560 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2561 self.star_arg.entry.cname, Naming.self_cname))
2562 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2563 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2564 temp, temp, Naming.args_cname, temp))
2565 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2566 Naming.args_cname, temp))
2567 code.put_incref("item", py_object_type)
2568 code.put_giveref("item")
2569 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2570 self.star_arg.entry.cname, temp))
2572 code.funcstate.release_temp(temp)
2573 self.star_arg.entry.xdecref_cleanup = 0
2575 code.put_incref(Naming.args_cname, py_object_type)
2576 code.putln("%s = %s;" % (
2577 self.star_arg.entry.cname,
2579 self.star_arg.entry.xdecref_cleanup = 0
2581 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2582 kw_only_args, success_label, code):
2583 argtuple_error_label = code.new_label("argtuple_error")
2585 min_positional_args = self.num_required_args - self.num_required_kw_args
2586 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2587 min_positional_args -= 1
2588 max_positional_args = len(positional_args)
2589 has_fixed_positional_count = not self.star_arg and \
2590 min_positional_args == max_positional_args
2592 if self.num_required_kw_args:
2593 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2595 if self.starstar_arg or self.star_arg:
2596 self.generate_stararg_init_code(max_positional_args, code)
2598 # --- optimised code when we receive keyword arguments
2599 if self.num_required_kw_args:
2600 likely_hint = "likely"
2602 likely_hint = "unlikely"
2603 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2604 self.generate_keyword_unpacking_code(
2605 min_positional_args, max_positional_args,
2606 has_fixed_positional_count,
2607 positional_args, kw_only_args, argtuple_error_label, code)
2609 # --- optimised code when we do not receive any keyword arguments
2610 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2611 # Python raises arg tuple related errors first, so we must
2612 # check the length here
2613 if min_positional_args == max_positional_args and not self.star_arg:
2617 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2618 Naming.args_cname, compare, min_positional_args))
2619 code.put_goto(argtuple_error_label)
2621 if self.num_required_kw_args:
2622 # pure error case: keywords required but not passed
2623 if max_positional_args > min_positional_args and not self.star_arg:
2624 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2625 Naming.args_cname, max_positional_args))
2626 code.put_goto(argtuple_error_label)
2627 code.putln('} else {')
2628 for i, arg in enumerate(kw_only_args):
2630 pystring_cname = code.intern_identifier(arg.name)
2631 # required keyword-only argument missing
2632 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2635 code.putln(code.error_goto(self.pos))
2638 elif min_positional_args == max_positional_args:
2639 # parse the exact number of positional arguments from the
2641 code.putln('} else {')
2642 for i, arg in enumerate(positional_args):
2643 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2644 self.generate_arg_assignment(arg, item, code)
2645 self.generate_arg_default_assignments(code)
2648 # parse the positional arguments from the variable length
2650 code.putln('} else {')
2651 self.generate_arg_default_assignments(code)
2652 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2654 code.putln('default:')
2655 reversed_args = list(enumerate(positional_args))[::-1]
2656 for i, arg in reversed_args:
2657 if i >= min_positional_args-1:
2658 if min_positional_args > 1:
2659 code.putln('case %2d:' % (i+1)) # pure code beautification
2661 code.put('case %2d: ' % (i+1))
2662 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2663 self.generate_arg_assignment(arg, item, code)
2664 if min_positional_args == 0:
2665 code.put('case 0: ')
2666 code.putln('break;')
2668 if min_positional_args:
2669 for i in range(min_positional_args-1, -1, -1):
2670 code.putln('case %2d:' % i)
2671 code.put_goto(argtuple_error_label)
2673 code.put('default: ')
2674 code.put_goto(argtuple_error_label)
2679 if code.label_used(argtuple_error_label):
2680 code.put_goto(success_label)
2681 code.put_label(argtuple_error_label)
2682 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2683 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2684 self.name, has_fixed_positional_count,
2685 min_positional_args, max_positional_args,
2687 code.putln(code.error_goto(self.pos))
2689 def generate_arg_default_assignments(self, code):
2690 for arg in self.args:
2691 if arg.is_generic and arg.default:
2695 arg.calculate_default_value_code(code)))
2697 def generate_stararg_init_code(self, max_positional_args, code):
2698 if self.starstar_arg:
2699 self.starstar_arg.entry.xdecref_cleanup = 0
2700 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2701 self.starstar_arg.entry.cname,
2702 self.starstar_arg.entry.cname,
2703 self.error_value()))
2704 code.put_gotref(self.starstar_arg.entry.cname)
2706 self.star_arg.entry.xdecref_cleanup = 0
2707 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2709 max_positional_args))
2710 code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % (
2711 self.star_arg.entry.cname, Naming.args_cname,
2712 max_positional_args, Naming.args_cname))
2713 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2714 if self.starstar_arg:
2715 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2716 if self.needs_closure:
2717 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2718 code.put_finish_refcount_context()
2719 code.putln('return %s;' % self.error_value())
2721 code.put_gotref(self.star_arg.entry.cname)
2722 code.putln('} else {')
2723 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2724 code.put_incref(Naming.empty_tuple, py_object_type)
2727 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2728 has_fixed_positional_count, positional_args,
2729 kw_only_args, argtuple_error_label, code):
2730 all_args = tuple(positional_args) + tuple(kw_only_args)
2731 max_args = len(all_args)
2733 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2735 # the 'values' array collects borrowed references to arguments
2736 # before doing any type coercion etc.
2737 code.putln("PyObject* values[%d] = {%s};" % (
2738 max_args, ','.join('0'*max_args)))
2740 # assign borrowed Python default values to the values array,
2741 # so that they can be overwritten by received arguments below
2742 for i, arg in enumerate(all_args):
2743 if arg.default and arg.type.is_pyobject:
2744 default_value = arg.calculate_default_value_code(code)
2745 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2747 # parse the args tuple and check that it's not too long
2748 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2750 code.putln('default:')
2751 for i in range(max_positional_args-1, -1, -1):
2752 code.put('case %2d: ' % (i+1))
2753 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2754 i, Naming.args_cname, i))
2755 code.putln('case 0: break;')
2756 if not self.star_arg:
2757 code.put('default: ') # more arguments than allowed
2758 code.put_goto(argtuple_error_label)
2761 # now fill up the positional/required arguments with values
2763 if self.num_required_args or max_positional_args > 0:
2764 last_required_arg = -1
2765 for i, arg in enumerate(all_args):
2767 last_required_arg = i
2768 if last_required_arg < max_positional_args:
2769 last_required_arg = max_positional_args-1
2770 num_required_args = self.num_required_args
2771 if max_positional_args > 0:
2772 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2773 for i, arg in enumerate(all_args[:last_required_arg+1]):
2774 if max_positional_args > 0 and i <= max_positional_args:
2775 if self.star_arg and i == max_positional_args:
2776 code.putln('default:')
2778 code.putln('case %2d:' % i)
2779 pystring_cname = code.intern_identifier(arg.name)
2782 # handled separately below
2784 code.putln('if (kw_args > 0) {')
2785 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2786 Naming.kwds_cname, pystring_cname))
2787 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2790 num_required_args -= 1
2791 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2792 i, Naming.kwds_cname, pystring_cname))
2793 code.putln('if (likely(values[%d])) kw_args--;' % i);
2794 if i < min_positional_args:
2796 # special case: we know arg 0 is missing
2798 code.put_goto(argtuple_error_label)
2800 # print the correct number of values (args or
2801 # kwargs) that were passed into positional
2802 # arguments up to this point
2803 code.putln('else {')
2804 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2805 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2806 self.name, has_fixed_positional_count,
2807 min_positional_args, max_positional_args, i))
2808 code.putln(code.error_goto(self.pos))
2811 code.putln('else {')
2812 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2813 self.name, pystring_cname))
2814 code.putln(code.error_goto(self.pos))
2816 if max_positional_args > 0:
2819 if kw_only_args and not self.starstar_arg:
2820 # unpack optional keyword-only arguments
2821 # checking for interned strings in a dict is faster than iterating
2822 # but it's too likely that we must iterate if we expect **kwargs
2824 for i, arg in enumerate(all_args[max_positional_args:]):
2825 if not arg.kw_only or not arg.default:
2827 optional_args.append((i+max_positional_args, arg))
2829 # this mimics an unrolled loop so that we can "break" out of it
2830 code.putln('while (kw_args > 0) {')
2831 code.putln('PyObject* value;')
2832 for i, arg in optional_args:
2833 pystring_cname = code.intern_identifier(arg.name)
2835 'value = PyDict_GetItem(%s, %s);' % (
2836 Naming.kwds_cname, pystring_cname))
2838 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2839 code.putln('break;')
2842 code.putln('if (unlikely(kw_args > 0)) {')
2843 # non-positional/-required kw args left in dict: default args,
2844 # kw-only args, **kwargs or error
2846 # This is sort of a catch-all: except for checking required
2847 # arguments, this will always do the right thing for unpacking
2848 # keyword arguments, so that we can concentrate on optimising
2849 # common cases above.
2850 if max_positional_args == 0:
2853 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2854 Naming.args_cname, max_positional_args,
2855 Naming.args_cname, max_positional_args))
2856 pos_arg_count = "used_pos_args"
2858 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2859 code.globalstate.use_utility_code(parse_keywords_utility_code)
2861 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2863 Naming.pykwdlist_cname,
2864 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2867 code.putln(code.error_goto(self.pos))
2870 # convert arg values to their final type and assign them
2871 for i, arg in enumerate(all_args):
2872 if arg.default and not arg.type.is_pyobject:
2873 code.putln("if (values[%d]) {" % i)
2874 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2875 if arg.default and not arg.type.is_pyobject:
2876 code.putln('} else {')
2880 arg.calculate_default_value_code(code)))
2883 def generate_argument_conversion_code(self, code):
2884 # Generate code to convert arguments from signature type to
2885 # declared type, if needed. Also copies signature arguments
2886 # into closure fields.
2887 for arg in self.args:
2888 if arg.needs_conversion:
2889 self.generate_arg_conversion(arg, code)
2890 elif arg.entry.in_closure:
2891 if arg.type.is_pyobject:
2892 code.put_incref(arg.hdr_cname, py_object_type)
2893 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2895 def generate_arg_conversion(self, arg, code):
2896 # Generate conversion code for one argument.
2897 old_type = arg.hdr_type
2899 if old_type.is_pyobject:
2901 code.putln("if (%s) {" % arg.hdr_cname)
2903 code.putln("assert(%s); {" % arg.hdr_cname)
2904 self.generate_arg_conversion_from_pyobject(arg, code)
2906 elif new_type.is_pyobject:
2907 self.generate_arg_conversion_to_pyobject(arg, code)
2909 if new_type.assignable_from(old_type):
2911 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2914 "Cannot convert 1 argument from '%s' to '%s'" %
2915 (old_type, new_type))
2917 def generate_arg_conversion_from_pyobject(self, arg, code):
2919 func = new_type.from_py_function
2920 # copied from CoerceFromPyTypeNode
2922 lhs = arg.entry.cname
2923 rhs = "%s(%s)" % (func, arg.hdr_cname)
2924 if new_type.is_enum:
2925 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2926 code.putln("%s = %s; %s" % (
2929 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2932 "Cannot convert Python object argument to type '%s'"
2935 def generate_arg_conversion_to_pyobject(self, arg, code):
2936 old_type = arg.hdr_type
2937 func = old_type.to_py_function
2939 code.putln("%s = %s(%s); %s" % (
2943 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2944 code.put_var_gotref(arg.entry)
2947 "Cannot convert argument of type '%s' to Python object"
2950 def generate_argument_type_tests(self, code):
2951 # Generate type tests for args whose signature
2952 # type is PyObject * and whose declared type is
2953 # a subtype thereof.
2954 for arg in self.args:
2955 if arg.needs_type_test:
2956 self.generate_arg_type_test(arg, code)
2957 elif not arg.accept_none and arg.type.is_pyobject:
2958 self.generate_arg_none_check(arg, code)
2960 def error_value(self):
2961 return self.entry.signature.error_value
2963 def caller_will_check_exceptions(self):
2967 class GeneratorDefNode(DefNode):
2968 # Generator DefNode.
2970 # gbody GeneratorBodyDefNode
2974 needs_closure = True
2976 child_attrs = DefNode.child_attrs + ["gbody"]
2978 def __init__(self, **kwargs):
2979 # XXX: don't actually needs a body
2980 kwargs['body'] = StatListNode(kwargs['pos'], stats=[])
2981 super(GeneratorDefNode, self).__init__(**kwargs)
2983 def analyse_declarations(self, env):
2984 super(GeneratorDefNode, self).analyse_declarations(env)
2985 self.gbody.local_scope = self.local_scope
2986 self.gbody.analyse_declarations(env)
2988 def generate_function_body(self, env, code):
2989 body_cname = self.gbody.entry.func_cname
2990 generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
2992 code.putln('%s.resume_label = 0;' % generator_cname)
2993 code.putln('%s.body = (__pyx_generator_body_t) %s;' % (generator_cname, body_cname))
2994 code.put_giveref(Naming.cur_scope_cname)
2995 code.put_finish_refcount_context()
2996 code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
2998 def generate_function_definitions(self, env, code):
2999 self.gbody.generate_function_header(code, proto=True)
3000 super(GeneratorDefNode, self).generate_function_definitions(env, code)
3001 self.gbody.generate_function_definitions(env, code)
3004 class GeneratorBodyDefNode(DefNode):
3005 # Generator body DefNode.
3008 is_generator_body = True
3010 def __init__(self, pos=None, name=None, body=None):
3011 super(GeneratorBodyDefNode, self).__init__(pos=pos, body=body, name=name, doc=None,
3013 star_arg=None, starstar_arg=None)
3015 def declare_generator_body(self, env):
3016 prefix = env.next_id(env.scope_prefix)
3017 name = env.next_id('generator')
3018 entry = env.declare_var(prefix + name, py_object_type, self.pos, visibility='private')
3019 entry.func_cname = Naming.genbody_prefix + prefix + name
3020 entry.qualified_name = EncodedString(self.name)
3023 def analyse_declarations(self, env):
3024 self.analyse_argument_types(env)
3025 self.declare_generator_body(env)
3027 def generate_function_header(self, code, proto=False):
3028 header = "static PyObject *%s(%s, PyObject *%s)" % (
3029 self.entry.func_cname,
3030 self.local_scope.scope_class.type.declaration_code(Naming.cur_scope_cname),
3031 Naming.sent_value_cname)
3033 code.putln('%s; /* proto */' % header)
3035 code.putln('%s /* generator body */\n{' % header);
3037 def generate_function_definitions(self, env, code):
3038 lenv = self.local_scope
3040 # Generate closure function definitions
3041 self.body.generate_function_definitions(lenv, code)
3043 # Generate C code for header and body of function
3044 code.enter_cfunc_scope()
3045 code.return_from_error_cleanup_label = code.new_label()
3047 # ----- Top-level constants used by this function
3048 code.mark_pos(self.pos)
3049 self.generate_cached_builtins_decls(lenv, code)
3050 # ----- Function header
3052 self.generate_function_header(code)
3053 # ----- Local variables
3054 code.putln("PyObject *%s = NULL;" % Naming.retval_cname)
3055 tempvardecl_code = code.insertion_point()
3056 code.put_declare_refcount_context()
3057 code.put_setup_refcount_context(self.entry.name)
3059 # ----- Resume switch point.
3060 code.funcstate.init_closure_temps(lenv.scope_class.type.scope)
3061 resume_code = code.insertion_point()
3062 first_run_label = code.new_label('first_run')
3063 code.use_label(first_run_label)
3064 code.put_label(first_run_label)
3066 (code.error_goto_if_null(Naming.sent_value_cname, self.pos)))
3068 # ----- Function body
3069 self.generate_function_body(env, code)
3070 code.putln('PyErr_SetNone(PyExc_StopIteration); %s' % code.error_goto(self.pos))
3071 # ----- Error cleanup
3072 if code.error_label in code.labels_used:
3073 code.put_goto(code.return_label)
3074 code.put_label(code.error_label)
3075 for cname, type in code.funcstate.all_managed_temps():
3076 code.put_xdecref(cname, type)
3077 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
3079 # ----- Non-error return cleanup
3080 code.put_label(code.return_label)
3081 code.put_xdecref(Naming.retval_cname, py_object_type)
3082 code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
3083 code.put_finish_refcount_context()
3084 code.putln('return NULL;');
3087 # ----- Go back and insert temp variable declarations
3088 tempvardecl_code.put_temp_declarations(code.funcstate)
3089 # ----- Generator resume code
3090 resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
3091 resume_code.putln("case 0: goto %s;" % first_run_label)
3093 from ParseTreeTransforms import YieldNodeCollector
3094 collector = YieldNodeCollector()
3095 collector.visitchildren(self)
3096 for yield_expr in collector.yields:
3097 resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
3098 resume_code.putln("default: /* CPython raises the right error here */");
3099 resume_code.put_finish_refcount_context()
3100 resume_code.putln("return NULL;");
3101 resume_code.putln("}");
3103 code.exit_cfunc_scope()
3106 class OverrideCheckNode(StatNode):
3107 # A Node for dispatching to the def method if it
3116 child_attrs = ['body']
3120 def analyse_expressions(self, env):
3121 self.args = env.arg_entries
3122 if self.py_func.is_module_scope:
3127 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
3128 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3129 call_node = ExprNodes.SimpleCallNode(self.pos,
3130 function=self.func_node,
3131 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3132 self.body = ReturnStatNode(self.pos, value=call_node)
3133 self.body.analyse_expressions(env)
3135 def generate_execution_code(self, code):
3136 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
3137 # Check to see if we are an extension type
3138 if self.py_func.is_module_scope:
3139 self_arg = "((PyObject *)%s)" % Naming.module_cname
3141 self_arg = "((PyObject *)%s)" % self.args[0].cname
3142 code.putln("/* Check if called by wrapper */")
3143 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
3144 code.putln("/* Check if overriden in Python */")
3145 if self.py_func.is_module_scope:
3146 code.putln("else {")
3148 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
3149 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3150 self.func_node.set_cname(func_node_temp)
3151 # need to get attribute manually--scope would return cdef method
3152 err = code.error_goto_if_null(func_node_temp, self.pos)
3153 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
3154 func_node_temp, self_arg, interned_attr_cname, err))
3155 code.put_gotref(func_node_temp)
3156 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
3157 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
3158 func_node_temp, self.py_func.entry.func_cname)
3159 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
3160 self.body.generate_execution_code(code)
3162 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
3163 code.funcstate.release_temp(func_node_temp)
3166 class ClassDefNode(StatNode, BlockNode):
3169 class PyClassDefNode(ClassDefNode):
3170 # A Python class definition.
3172 # name EncodedString Name of the class
3173 # doc string or None
3174 # body StatNode Attribute definition code
3175 # entry Symtab.Entry
3176 # scope PyClassScope
3177 # decorators [DecoratorNode] list of decorators or None
3179 # The following subnodes are constructed internally:
3181 # dict DictNode Class dictionary or Py3 namespace
3182 # classobj ClassNode Class object
3183 # target NameNode Variable to assign class object to
3185 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
3187 py3_style_class = False # Python3 style class (bases+kwargs)
3189 def __init__(self, pos, name, bases, doc, body, decorators = None,
3190 keyword_args = None, starstar_arg = None):
3191 StatNode.__init__(self, pos)
3195 self.decorators = decorators
3197 if self.doc and Options.docstrings:
3198 doc = embed_position(self.pos, self.doc)
3199 doc_node = ExprNodes.StringNode(pos, value = doc)
3202 if keyword_args or starstar_arg:
3203 self.py3_style_class = True
3205 self.metaclass = None
3206 if keyword_args and not starstar_arg:
3207 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3208 if item.key.value == 'metaclass':
3209 if self.metaclass is not None:
3210 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3211 # special case: we already know the metaclass,
3212 # so we don't need to do the "build kwargs,
3213 # find metaclass" dance at runtime
3214 self.metaclass = item.value
3215 del keyword_args.key_value_pairs[i]
3216 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3217 self.mkw = ExprNodes.KeywordArgsNode(
3218 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3220 self.mkw = ExprNodes.NullNode(pos)
3221 if self.metaclass is None:
3222 self.metaclass = ExprNodes.PyClassMetaclassNode(
3223 pos, mkw = self.mkw, bases = self.bases)
3224 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3225 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3227 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3228 bases = self.bases, dict = self.dict, doc = doc_node,
3229 metaclass = self.metaclass, mkw = self.mkw)
3231 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3232 self.metaclass = None
3235 self.classobj = ExprNodes.ClassNode(pos, name = name,
3236 bases = bases, dict = self.dict, doc = doc_node)
3237 self.target = ExprNodes.NameNode(pos, name = name)
3239 def as_cclass(self):
3241 Return this node as if it were declared as an extension class
3243 if self.py3_style_class:
3244 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3246 bases = self.classobj.bases.args
3248 base_class_name = None
3249 base_class_module = None
3250 elif len(bases) == 1:
3253 from ExprNodes import AttributeNode, NameNode
3254 while isinstance(base, AttributeNode):
3255 path.insert(0, base.attribute)
3257 if isinstance(base, NameNode):
3258 path.insert(0, base.name)
3259 base_class_name = path[-1]
3261 base_class_module = u'.'.join(path[:-1])
3263 base_class_module = None
3265 error(self.classobj.bases.args.pos, "Invalid base class")
3267 error(self.classobj.bases.args.pos, "C class may only have one base class")
3270 return CClassDefNode(self.pos,
3271 visibility = 'private',
3273 class_name = self.name,
3274 base_class_module = base_class_module,
3275 base_class_name = base_class_name,
3276 decorators = self.decorators,
3281 def create_scope(self, env):
3283 while genv.is_py_class_scope or genv.is_c_class_scope:
3284 genv = genv.outer_scope
3285 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3288 def analyse_declarations(self, env):
3289 self.target.analyse_target_declaration(env)
3290 cenv = self.create_scope(env)
3291 cenv.directives = env.directives
3292 cenv.class_obj_cname = self.target.entry.cname
3293 self.body.analyse_declarations(cenv)
3295 def analyse_expressions(self, env):
3296 if self.py3_style_class:
3297 self.bases.analyse_expressions(env)
3298 self.metaclass.analyse_expressions(env)
3299 self.mkw.analyse_expressions(env)
3300 self.dict.analyse_expressions(env)
3301 self.classobj.analyse_expressions(env)
3302 genv = env.global_scope()
3304 self.body.analyse_expressions(cenv)
3305 self.target.analyse_target_expression(env, self.classobj)
3307 def generate_function_definitions(self, env, code):
3308 self.generate_lambda_definitions(self.scope, code)
3309 self.body.generate_function_definitions(self.scope, code)
3311 def generate_execution_code(self, code):
3312 code.pyclass_stack.append(self)
3314 if self.py3_style_class:
3315 self.bases.generate_evaluation_code(code)
3316 self.mkw.generate_evaluation_code(code)
3317 self.metaclass.generate_evaluation_code(code)
3318 self.dict.generate_evaluation_code(code)
3319 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3320 self.body.generate_execution_code(code)
3321 self.classobj.generate_evaluation_code(code)
3322 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3323 self.target.generate_assignment_code(self.classobj, code)
3324 self.dict.generate_disposal_code(code)
3325 self.dict.free_temps(code)
3326 if self.py3_style_class:
3327 self.mkw.generate_disposal_code(code)
3328 self.mkw.free_temps(code)
3329 self.metaclass.generate_disposal_code(code)
3330 self.metaclass.free_temps(code)
3331 self.bases.generate_disposal_code(code)
3332 self.bases.free_temps(code)
3333 code.pyclass_stack.pop()
3335 class CClassDefNode(ClassDefNode):
3336 # An extension type definition.
3338 # visibility 'private' or 'public' or 'extern'
3339 # typedef_flag boolean
3341 # module_name string or None For import of extern type objects
3342 # class_name string Unqualified name of class
3343 # as_name string or None Name to declare as in this scope
3344 # base_class_module string or None Module containing the base class
3345 # base_class_name string or None Name of the base class
3346 # objstruct_name string or None Specified C name of object struct
3347 # typeobj_name string or None Specified C name of type object
3348 # in_pxd boolean Is in a .pxd file
3349 # decorators [DecoratorNode] list of decorators or None
3350 # doc string or None
3351 # body StatNode or None
3352 # entry Symtab.Entry
3353 # base_type PyExtensionType or None
3354 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3355 # buffer_defaults_pos
3357 child_attrs = ["body"]
3358 buffer_defaults_node = None
3359 buffer_defaults_pos = None
3360 typedef_flag = False
3362 objstruct_name = None
3367 def analyse_declarations(self, env):
3368 #print "CClassDefNode.analyse_declarations:", self.class_name
3369 #print "...visibility =", self.visibility
3370 #print "...module_name =", self.module_name
3373 if self.buffer_defaults_node:
3374 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3375 env, [], self.buffer_defaults_node,
3376 need_complete=False)
3378 buffer_defaults = None
3380 if env.in_cinclude and not self.objstruct_name:
3381 error(self.pos, "Object struct name specification required for "
3382 "C class defined in 'extern from' block")
3383 self.base_type = None
3384 # Now that module imports are cached, we need to
3385 # import the modules for extern classes.
3386 if self.module_name:
3388 for module in env.cimported_modules:
3389 if module.name == self.module_name:
3390 self.module = module
3391 if self.module is None:
3392 self.module = ModuleScope(self.module_name, None, env.context)
3393 self.module.has_extern_class = 1
3394 env.add_imported_module(self.module)
3396 if self.base_class_name:
3397 if self.base_class_module:
3398 base_class_scope = env.find_module(self.base_class_module, self.pos)
3400 base_class_scope = env
3401 if self.base_class_name == 'object':
3402 # extension classes are special and don't need to inherit from object
3403 if base_class_scope is None or base_class_scope.lookup('object') is None:
3404 self.base_class_name = None
3405 self.base_class_module = None
3406 base_class_scope = None
3407 if base_class_scope:
3408 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3409 if base_class_entry:
3410 if not base_class_entry.is_type:
3411 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3412 elif not base_class_entry.type.is_extension_type and \
3413 not (base_class_entry.type.is_builtin_type and \
3414 base_class_entry.type.objstruct_cname):
3415 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3416 elif not base_class_entry.type.is_complete():
3417 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3418 self.base_class_name, self.class_name))
3419 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3420 base_class_entry.type.scope.directives['final']:
3421 error(self.pos, "Base class '%s' of type '%s' is final" % (
3422 self.base_class_name, self.class_name))
3423 elif base_class_entry.type.is_builtin_type and \
3424 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3425 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3426 % base_class_entry.type.name)
3428 self.base_type = base_class_entry.type
3429 has_body = self.body is not None
3430 if self.module_name and self.visibility != 'extern':
3431 module_path = self.module_name.split(".")
3432 home_scope = env.find_imported_module(module_path, self.pos)
3438 if self.visibility == 'extern':
3439 if (self.module_name == '__builtin__' and
3440 self.class_name in Builtin.builtin_types and
3441 env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython
3442 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3444 self.entry = home_scope.declare_c_class(
3445 name = self.class_name,
3447 defining = has_body and self.in_pxd,
3448 implementing = has_body and not self.in_pxd,
3449 module_name = self.module_name,
3450 base_type = self.base_type,
3451 objstruct_cname = self.objstruct_name,
3452 typeobj_cname = self.typeobj_name,
3453 visibility = self.visibility,
3454 typedef_flag = self.typedef_flag,
3456 buffer_defaults = buffer_defaults,
3457 shadow = self.shadow)
3459 home_scope.lookup(self.class_name).as_variable = self.entry
3460 if home_scope is not env and self.visibility == 'extern':
3461 env.add_imported_entry(self.class_name, self.entry, self.pos)
3462 self.scope = scope = self.entry.type.scope
3463 if scope is not None:
3464 scope.directives = env.directives
3466 if self.doc and Options.docstrings:
3467 scope.doc = embed_position(self.pos, self.doc)
3470 self.body.analyse_declarations(scope)
3474 scope.implemented = 1
3475 env.allocate_vtable_names(self.entry)
3477 def analyse_expressions(self, env):
3479 scope = self.entry.type.scope
3480 self.body.analyse_expressions(scope)
3482 def generate_function_definitions(self, env, code):
3484 self.generate_lambda_definitions(self.scope, code)
3485 self.body.generate_function_definitions(self.scope, code)
3487 def generate_execution_code(self, code):
3488 # This is needed to generate evaluation code for
3489 # default values of method arguments.
3491 self.body.generate_execution_code(code)
3493 def annotate(self, code):
3495 self.body.annotate(code)
3498 class PropertyNode(StatNode):
3499 # Definition of a property in an extension type.
3502 # doc EncodedString or None Doc string
3505 child_attrs = ["body"]
3507 def analyse_declarations(self, env):
3508 entry = env.declare_property(self.name, self.doc, self.pos)
3510 entry.scope.directives = env.directives
3511 self.body.analyse_declarations(entry.scope)
3513 def analyse_expressions(self, env):
3514 self.body.analyse_expressions(env)
3516 def generate_function_definitions(self, env, code):
3517 self.body.generate_function_definitions(env, code)
3519 def generate_execution_code(self, code):
3522 def annotate(self, code):
3523 self.body.annotate(code)
3526 class GlobalNode(StatNode):
3527 # Global variable declaration.
3533 def analyse_declarations(self, env):
3534 for name in self.names:
3535 env.declare_global(name, self.pos)
3537 def analyse_expressions(self, env):
3540 def generate_execution_code(self, code):
3544 class NonlocalNode(StatNode):
3545 # Nonlocal variable declaration via the 'nonlocal' keyword.
3551 def analyse_declarations(self, env):
3552 for name in self.names:
3553 env.declare_nonlocal(name, self.pos)
3555 def analyse_expressions(self, env):
3558 def generate_execution_code(self, code):
3562 class ExprStatNode(StatNode):
3563 # Expression used as a statement.
3567 child_attrs = ["expr"]
3569 def analyse_declarations(self, env):
3571 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3572 func = self.expr.function.as_cython_attribute()
3573 if func == u'declare':
3574 args, kwds = self.expr.explicit_args_kwds()
3576 error(self.expr.pos, "Variable names must be specified.")
3577 for var, type_node in kwds.key_value_pairs:
3578 type = type_node.analyse_as_type(env)
3580 error(type_node.pos, "Unknown type")
3582 env.declare_var(var.value, type, var.pos, is_cdef = True)
3583 self.__class__ = PassStatNode
3585 def analyse_expressions(self, env):
3586 self.expr.result_is_used = False # hint that .result() may safely be left empty
3587 self.expr.analyse_expressions(env)
3589 def nogil_check(self, env):
3590 if self.expr.type.is_pyobject and self.expr.is_temp:
3593 gil_message = "Discarding owned Python object"
3595 def generate_execution_code(self, code):
3596 self.expr.generate_evaluation_code(code)
3597 if not self.expr.is_temp and self.expr.result():
3598 code.putln("%s;" % self.expr.result())
3599 self.expr.generate_disposal_code(code)
3600 self.expr.free_temps(code)
3602 def generate_function_definitions(self, env, code):
3603 self.expr.generate_function_definitions(env, code)
3605 def annotate(self, code):
3606 self.expr.annotate(code)
3609 class AssignmentNode(StatNode):
3610 # Abstract base class for assignment nodes.
3612 # The analyse_expressions and generate_execution_code
3613 # phases of assignments are split into two sub-phases
3614 # each, to enable all the right hand sides of a
3615 # parallel assignment to be evaluated before assigning
3616 # to any of the left hand sides.
3618 def analyse_expressions(self, env):
3619 self.analyse_types(env)
3621 # def analyse_expressions(self, env):
3622 # self.analyse_expressions_1(env)
3623 # self.analyse_expressions_2(env)
3625 def generate_execution_code(self, code):
3626 self.generate_rhs_evaluation_code(code)
3627 self.generate_assignment_code(code)
3630 class SingleAssignmentNode(AssignmentNode):
3631 # The simplest case:
3635 # lhs ExprNode Left hand side
3636 # rhs ExprNode Right hand side
3637 # first bool Is this guaranteed the first assignment to lhs?
3639 child_attrs = ["lhs", "rhs"]
3641 declaration_only = False
3643 def analyse_declarations(self, env):
3646 # handle declarations of the form x = cython.foo()
3647 if isinstance(self.rhs, ExprNodes.CallNode):
3648 func_name = self.rhs.function.as_cython_attribute()
3650 args, kwds = self.rhs.explicit_args_kwds()
3652 if func_name in ['declare', 'typedef']:
3653 if len(args) > 2 or kwds is not None:
3654 error(self.rhs.pos, "Can only declare one type at a time.")
3656 type = args[0].analyse_as_type(env)
3658 error(args[0].pos, "Unknown type")
3661 if func_name == 'declare':
3662 if isinstance(lhs, ExprNodes.NameNode):
3663 vars = [(lhs.name, lhs.pos)]
3664 elif isinstance(lhs, ExprNodes.TupleNode):
3665 vars = [(var.name, var.pos) for var in lhs.args]
3667 error(lhs.pos, "Invalid declaration")
3669 for var, pos in vars:
3670 env.declare_var(var, type, pos, is_cdef = True)
3675 self.declaration_only = True
3677 self.declaration_only = True
3678 if not isinstance(lhs, ExprNodes.NameNode):
3679 error(lhs.pos, "Invalid declaration.")
3680 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3682 elif func_name in ['struct', 'union']:
3683 self.declaration_only = True
3684 if len(args) > 0 or kwds is None:
3685 error(self.rhs.pos, "Struct or union members must be given by name.")
3688 for member, type_node in kwds.key_value_pairs:
3689 type = type_node.analyse_as_type(env)
3691 error(type_node.pos, "Unknown type")
3693 members.append((member.value, type, member.pos))
3694 if len(members) < len(kwds.key_value_pairs):
3696 if not isinstance(self.lhs, ExprNodes.NameNode):
3697 error(self.lhs.pos, "Invalid declaration.")
3698 name = self.lhs.name
3699 scope = StructOrUnionScope(name)
3700 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3701 for member, type, pos in members:
3702 scope.declare_var(member, type, pos)
3704 if self.declaration_only:
3707 self.lhs.analyse_target_declaration(env)
3709 def analyse_types(self, env, use_temp = 0):
3710 self.rhs.analyse_types(env)
3711 self.lhs.analyse_target_types(env)
3712 self.lhs.gil_assignment_check(env)
3713 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3715 self.rhs = self.rhs.coerce_to_temp(env)
3717 def generate_rhs_evaluation_code(self, code):
3718 self.rhs.generate_evaluation_code(code)
3720 def generate_assignment_code(self, code):
3721 self.lhs.generate_assignment_code(self.rhs, code)
3723 def generate_function_definitions(self, env, code):
3724 self.rhs.generate_function_definitions(env, code)
3726 def annotate(self, code):
3727 self.lhs.annotate(code)
3728 self.rhs.annotate(code)
3731 class CascadedAssignmentNode(AssignmentNode):
3732 # An assignment with multiple left hand sides:
3736 # lhs_list [ExprNode] Left hand sides
3737 # rhs ExprNode Right hand sides
3741 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3743 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3744 coerced_rhs_list = None
3746 def analyse_declarations(self, env):
3747 for lhs in self.lhs_list:
3748 lhs.analyse_target_declaration(env)
3750 def analyse_types(self, env, use_temp = 0):
3751 self.rhs.analyse_types(env)
3752 if not self.rhs.is_simple():
3754 self.rhs = self.rhs.coerce_to_temp(env)
3756 self.rhs = self.rhs.coerce_to_simple(env)
3757 from ExprNodes import CloneNode
3758 self.coerced_rhs_list = []
3759 for lhs in self.lhs_list:
3760 lhs.analyse_target_types(env)
3761 lhs.gil_assignment_check(env)
3762 rhs = CloneNode(self.rhs)
3763 rhs = rhs.coerce_to(lhs.type, env)
3764 self.coerced_rhs_list.append(rhs)
3766 def generate_rhs_evaluation_code(self, code):
3767 self.rhs.generate_evaluation_code(code)
3769 def generate_assignment_code(self, code):
3770 for i in range(len(self.lhs_list)):
3771 lhs = self.lhs_list[i]
3772 rhs = self.coerced_rhs_list[i]
3773 rhs.generate_evaluation_code(code)
3774 lhs.generate_assignment_code(rhs, code)
3775 # Assignment has disposed of the cloned RHS
3776 self.rhs.generate_disposal_code(code)
3777 self.rhs.free_temps(code)
3779 def generate_function_definitions(self, env, code):
3780 self.rhs.generate_function_definitions(env, code)
3782 def annotate(self, code):
3783 for i in range(len(self.lhs_list)):
3784 lhs = self.lhs_list[i].annotate(code)
3785 rhs = self.coerced_rhs_list[i].annotate(code)
3786 self.rhs.annotate(code)
3789 class ParallelAssignmentNode(AssignmentNode):
3790 # A combined packing/unpacking assignment:
3794 # This has been rearranged by the parser into
3796 # a = d ; b = e ; c = f
3798 # but we must evaluate all the right hand sides
3799 # before assigning to any of the left hand sides.
3801 # stats [AssignmentNode] The constituent assignments
3803 child_attrs = ["stats"]
3805 def analyse_declarations(self, env):
3806 for stat in self.stats:
3807 stat.analyse_declarations(env)
3809 def analyse_expressions(self, env):
3810 for stat in self.stats:
3811 stat.analyse_types(env, use_temp = 1)
3813 # def analyse_expressions(self, env):
3814 # for stat in self.stats:
3815 # stat.analyse_expressions_1(env, use_temp = 1)
3816 # for stat in self.stats:
3817 # stat.analyse_expressions_2(env)
3819 def generate_execution_code(self, code):
3820 for stat in self.stats:
3821 stat.generate_rhs_evaluation_code(code)
3822 for stat in self.stats:
3823 stat.generate_assignment_code(code)
3825 def generate_function_definitions(self, env, code):
3826 for stat in self.stats:
3827 stat.generate_function_definitions(env, code)
3829 def annotate(self, code):
3830 for stat in self.stats:
3834 class InPlaceAssignmentNode(AssignmentNode):
3835 # An in place arithmetic operand:
3841 # lhs ExprNode Left hand side
3842 # rhs ExprNode Right hand side
3843 # op char one of "+-*/%^&|"
3844 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3846 # This code is a bit tricky because in order to obey Python
3847 # semantics the sub-expressions (e.g. indices) of the lhs must
3848 # not be evaluated twice. So we must re-use the values calculated
3849 # in evaluation phase for the assignment phase as well.
3850 # Fortunately, the type of the lhs node is fairly constrained
3851 # (it must be a NameNode, AttributeNode, or IndexNode).
3853 child_attrs = ["lhs", "rhs"]
3855 def analyse_declarations(self, env):
3856 self.lhs.analyse_target_declaration(env)
3858 def analyse_types(self, env):
3859 self.rhs.analyse_types(env)
3860 self.lhs.analyse_target_types(env)
3862 def generate_execution_code(self, code):
3864 self.rhs.generate_evaluation_code(code)
3865 self.lhs.generate_subexpr_evaluation_code(code)
3866 c_op = self.operator
3870 error(self.pos, "No C inplace power operator")
3871 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3872 if self.lhs.type.is_pyobject:
3873 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3874 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3875 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3876 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3879 # TODO: make sure overload is declared
3880 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3881 self.lhs.generate_subexpr_disposal_code(code)
3882 self.lhs.free_subexpr_temps(code)
3883 self.rhs.generate_disposal_code(code)
3884 self.rhs.free_temps(code)
3886 def annotate(self, code):
3887 self.lhs.annotate(code)
3888 self.rhs.annotate(code)
3890 def create_binop_node(self):
3892 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3895 class PrintStatNode(StatNode):
3898 # arg_tuple TupleNode
3899 # stream ExprNode or None (stdout)
3900 # append_newline boolean
3902 child_attrs = ["arg_tuple", "stream"]
3904 def analyse_expressions(self, env):
3906 self.stream.analyse_expressions(env)
3907 self.stream = self.stream.coerce_to_pyobject(env)
3908 self.arg_tuple.analyse_expressions(env)
3909 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3910 env.use_utility_code(printing_utility_code)
3911 if len(self.arg_tuple.args) == 1 and self.append_newline:
3912 env.use_utility_code(printing_one_utility_code)
3914 nogil_check = Node.gil_error
3915 gil_message = "Python print statement"
3917 def generate_execution_code(self, code):
3919 self.stream.generate_evaluation_code(code)
3920 stream_result = self.stream.py_result()
3923 if len(self.arg_tuple.args) == 1 and self.append_newline:
3924 arg = self.arg_tuple.args[0]
3925 arg.generate_evaluation_code(code)
3928 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3931 code.error_goto(self.pos)))
3932 arg.generate_disposal_code(code)
3933 arg.free_temps(code)
3935 self.arg_tuple.generate_evaluation_code(code)
3937 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3939 self.arg_tuple.py_result(),
3940 self.append_newline,
3941 code.error_goto(self.pos)))
3942 self.arg_tuple.generate_disposal_code(code)
3943 self.arg_tuple.free_temps(code)
3946 self.stream.generate_disposal_code(code)
3947 self.stream.free_temps(code)
3949 def generate_function_definitions(self, env, code):
3951 self.stream.generate_function_definitions(env, code)
3952 self.arg_tuple.generate_function_definitions(env, code)
3954 def annotate(self, code):
3956 self.stream.annotate(code)
3957 self.arg_tuple.annotate(code)
3960 class ExecStatNode(StatNode):
3965 child_attrs = ["args"]
3967 def analyse_expressions(self, env):
3968 for i, arg in enumerate(self.args):
3969 arg.analyse_expressions(env)
3970 arg = arg.coerce_to_pyobject(env)
3972 env.use_utility_code(Builtin.pyexec_utility_code)
3974 nogil_check = Node.gil_error
3975 gil_message = "Python exec statement"
3977 def generate_execution_code(self, code):
3979 for arg in self.args:
3980 arg.generate_evaluation_code(code)
3981 args.append( arg.py_result() )
3982 args = tuple(args + ['0', '0'][:3-len(args)])
3983 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3984 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3985 (temp_result,) + args))
3986 for arg in self.args:
3987 arg.generate_disposal_code(code)
3988 arg.free_temps(code)
3990 code.error_goto_if_null(temp_result, self.pos))
3991 code.put_gotref(temp_result)
3992 code.put_decref_clear(temp_result, py_object_type)
3993 code.funcstate.release_temp(temp_result)
3995 def annotate(self, code):
3996 for arg in self.args:
4000 class DelStatNode(StatNode):
4005 child_attrs = ["args"]
4007 def analyse_declarations(self, env):
4008 for arg in self.args:
4009 arg.analyse_target_declaration(env)
4011 def analyse_expressions(self, env):
4012 for arg in self.args:
4013 arg.analyse_target_expression(env, None)
4014 if arg.type.is_pyobject:
4016 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
4018 elif arg.type.is_cpp_class:
4019 error(arg.pos, "Deletion of non-heap C++ object")
4021 error(arg.pos, "Deletion of non-Python, non-C++ object")
4022 #arg.release_target_temp(env)
4024 def nogil_check(self, env):
4025 for arg in self.args:
4026 if arg.type.is_pyobject:
4029 gil_message = "Deleting Python object"
4031 def generate_execution_code(self, code):
4032 for arg in self.args:
4033 if arg.type.is_pyobject:
4034 arg.generate_deletion_code(code)
4035 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
4036 arg.generate_result_code(code)
4037 code.putln("delete %s;" % arg.result())
4038 # else error reported earlier
4040 def annotate(self, code):
4041 for arg in self.args:
4045 class PassStatNode(StatNode):
4050 def analyse_expressions(self, env):
4053 def generate_execution_code(self, code):
4057 class BreakStatNode(StatNode):
4061 def analyse_expressions(self, env):
4064 def generate_execution_code(self, code):
4065 if not code.break_label:
4066 error(self.pos, "break statement not inside loop")
4068 code.put_goto(code.break_label)
4071 class ContinueStatNode(StatNode):
4075 def analyse_expressions(self, env):
4078 def generate_execution_code(self, code):
4079 if code.funcstate.in_try_finally:
4080 error(self.pos, "continue statement inside try of try...finally")
4081 elif not code.continue_label:
4082 error(self.pos, "continue statement not inside loop")
4084 code.put_goto(code.continue_label)
4087 class ReturnStatNode(StatNode):
4090 # value ExprNode or None
4091 # return_type PyrexType
4093 child_attrs = ["value"]
4095 def analyse_expressions(self, env):
4096 return_type = env.return_type
4097 self.return_type = return_type
4099 error(self.pos, "Return not inside a function body")
4102 self.value.analyse_types(env)
4103 if return_type.is_void or return_type.is_returncode:
4104 error(self.value.pos,
4105 "Return with value in void function")
4107 self.value = self.value.coerce_to(env.return_type, env)
4109 if (not return_type.is_void
4110 and not return_type.is_pyobject
4111 and not return_type.is_returncode):
4112 error(self.pos, "Return value required")
4114 def nogil_check(self, env):
4115 if self.return_type.is_pyobject:
4118 gil_message = "Returning Python object"
4120 def generate_execution_code(self, code):
4121 code.mark_pos(self.pos)
4122 if not self.return_type:
4123 # error reported earlier
4125 if self.return_type.is_pyobject:
4126 code.put_xdecref(Naming.retval_cname,
4129 self.value.generate_evaluation_code(code)
4130 self.value.make_owned_reference(code)
4133 Naming.retval_cname,
4134 self.value.result_as(self.return_type)))
4135 self.value.generate_post_assignment_code(code)
4136 self.value.free_temps(code)
4138 if self.return_type.is_pyobject:
4139 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
4140 elif self.return_type.is_returncode:
4143 Naming.retval_cname,
4144 self.return_type.default_value))
4145 for cname, type in code.funcstate.temps_holding_reference():
4146 code.put_decref_clear(cname, type)
4147 code.put_goto(code.return_label)
4149 def generate_function_definitions(self, env, code):
4150 if self.value is not None:
4151 self.value.generate_function_definitions(env, code)
4153 def annotate(self, code):
4155 self.value.annotate(code)
4158 class RaiseStatNode(StatNode):
4161 # exc_type ExprNode or None
4162 # exc_value ExprNode or None
4163 # exc_tb ExprNode or None
4165 child_attrs = ["exc_type", "exc_value", "exc_tb"]
4167 def analyse_expressions(self, env):
4169 self.exc_type.analyse_types(env)
4170 self.exc_type = self.exc_type.coerce_to_pyobject(env)
4172 self.exc_value.analyse_types(env)
4173 self.exc_value = self.exc_value.coerce_to_pyobject(env)
4175 self.exc_tb.analyse_types(env)
4176 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4177 # special cases for builtin exceptions
4178 self.builtin_exc_name = None
4179 if self.exc_type and not self.exc_value and not self.exc_tb:
4182 if (isinstance(exc, ExprNodes.SimpleCallNode) and
4183 not (exc.args or (exc.arg_tuple is not None and
4184 exc.arg_tuple.args))):
4185 exc = exc.function # extract the exception type
4186 if exc.is_name and exc.entry.is_builtin:
4187 self.builtin_exc_name = exc.name
4188 if self.builtin_exc_name == 'MemoryError':
4189 self.exc_type = None # has a separate implementation
4191 nogil_check = Node.gil_error
4192 gil_message = "Raising exception"
4194 def generate_execution_code(self, code):
4195 if self.builtin_exc_name == 'MemoryError':
4196 code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos))
4200 self.exc_type.generate_evaluation_code(code)
4201 type_code = self.exc_type.py_result()
4205 self.exc_value.generate_evaluation_code(code)
4206 value_code = self.exc_value.py_result()
4210 self.exc_tb.generate_evaluation_code(code)
4211 tb_code = self.exc_tb.py_result()
4214 code.globalstate.use_utility_code(raise_utility_code)
4216 "__Pyx_Raise(%s, %s, %s);" % (
4220 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4222 obj.generate_disposal_code(code)
4223 obj.free_temps(code)
4225 code.error_goto(self.pos))
4227 def generate_function_definitions(self, env, code):
4228 if self.exc_type is not None:
4229 self.exc_type.generate_function_definitions(env, code)
4230 if self.exc_value is not None:
4231 self.exc_value.generate_function_definitions(env, code)
4232 if self.exc_tb is not None:
4233 self.exc_tb.generate_function_definitions(env, code)
4235 def annotate(self, code):
4237 self.exc_type.annotate(code)
4239 self.exc_value.annotate(code)
4241 self.exc_tb.annotate(code)
4244 class ReraiseStatNode(StatNode):
4248 def analyse_expressions(self, env):
4249 env.use_utility_code(restore_exception_utility_code)
4251 nogil_check = Node.gil_error
4252 gil_message = "Raising exception"
4254 def generate_execution_code(self, code):
4255 vars = code.funcstate.exc_vars
4257 for varname in vars:
4258 code.put_giveref(varname)
4259 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4260 for varname in vars:
4261 code.put("%s = 0; " % varname)
4263 code.putln(code.error_goto(self.pos))
4265 error(self.pos, "Reraise not inside except clause")
4268 class AssertStatNode(StatNode):
4272 # value ExprNode or None
4274 child_attrs = ["cond", "value"]
4276 def analyse_expressions(self, env):
4277 self.cond = self.cond.analyse_boolean_expression(env)
4279 self.value.analyse_types(env)
4280 self.value = self.value.coerce_to_pyobject(env)
4282 nogil_check = Node.gil_error
4283 gil_message = "Raising exception"
4285 def generate_execution_code(self, code):
4286 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4287 self.cond.generate_evaluation_code(code)
4289 "if (unlikely(!%s)) {" %
4292 self.value.generate_evaluation_code(code)
4294 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4295 self.value.py_result())
4296 self.value.generate_disposal_code(code)
4297 self.value.free_temps(code)
4300 "PyErr_SetNone(PyExc_AssertionError);")
4302 code.error_goto(self.pos))
4305 self.cond.generate_disposal_code(code)
4306 self.cond.free_temps(code)
4307 code.putln("#endif")
4309 def generate_function_definitions(self, env, code):
4310 self.cond.generate_function_definitions(env, code)
4311 if self.value is not None:
4312 self.value.generate_function_definitions(env, code)
4314 def annotate(self, code):
4315 self.cond.annotate(code)
4317 self.value.annotate(code)
4320 class IfStatNode(StatNode):
4323 # if_clauses [IfClauseNode]
4324 # else_clause StatNode or None
4326 child_attrs = ["if_clauses", "else_clause"]
4328 def analyse_control_flow(self, env):
4329 env.start_branching(self.pos)
4330 for if_clause in self.if_clauses:
4331 if_clause.analyse_control_flow(env)
4332 env.next_branch(if_clause.end_pos())
4333 if self.else_clause:
4334 self.else_clause.analyse_control_flow(env)
4335 env.finish_branching(self.end_pos())
4337 def analyse_declarations(self, env):
4338 for if_clause in self.if_clauses:
4339 if_clause.analyse_declarations(env)
4340 if self.else_clause:
4341 self.else_clause.analyse_declarations(env)
4343 def analyse_expressions(self, env):
4344 for if_clause in self.if_clauses:
4345 if_clause.analyse_expressions(env)
4346 if self.else_clause:
4347 self.else_clause.analyse_expressions(env)
4349 def generate_execution_code(self, code):
4350 code.mark_pos(self.pos)
4351 end_label = code.new_label()
4352 for if_clause in self.if_clauses:
4353 if_clause.generate_execution_code(code, end_label)
4354 if self.else_clause:
4355 code.putln("/*else*/ {")
4356 self.else_clause.generate_execution_code(code)
4358 code.put_label(end_label)
4360 def generate_function_definitions(self, env, code):
4361 for clause in self.if_clauses:
4362 clause.generate_function_definitions(env, code)
4363 if self.else_clause is not None:
4364 self.else_clause.generate_function_definitions(env, code)
4366 def annotate(self, code):
4367 for if_clause in self.if_clauses:
4368 if_clause.annotate(code)
4369 if self.else_clause:
4370 self.else_clause.annotate(code)
4373 class IfClauseNode(Node):
4374 # if or elif clause in an if statement
4376 # condition ExprNode
4379 child_attrs = ["condition", "body"]
4381 def analyse_control_flow(self, env):
4382 self.body.analyse_control_flow(env)
4384 def analyse_declarations(self, env):
4385 self.body.analyse_declarations(env)
4387 def analyse_expressions(self, env):
4389 self.condition.analyse_temp_boolean_expression(env)
4390 self.body.analyse_expressions(env)
4392 def get_constant_condition_result(self):
4393 if self.condition.has_constant_result():
4394 return bool(self.condition.constant_result)
4398 def generate_execution_code(self, code, end_label):
4399 self.condition.generate_evaluation_code(code)
4402 self.condition.result())
4403 self.condition.generate_disposal_code(code)
4404 self.condition.free_temps(code)
4405 self.body.generate_execution_code(code)
4406 code.put_goto(end_label)
4409 def generate_function_definitions(self, env, code):
4410 self.condition.generate_function_definitions(env, code)
4411 self.body.generate_function_definitions(env, code)
4413 def annotate(self, code):
4414 self.condition.annotate(code)
4415 self.body.annotate(code)
4418 class SwitchCaseNode(StatNode):
4419 # Generated in the optimization of an if-elif-else node
4421 # conditions [ExprNode]
4424 child_attrs = ['conditions', 'body']
4426 def generate_execution_code(self, code):
4427 for cond in self.conditions:
4428 code.mark_pos(cond.pos)
4429 cond.generate_evaluation_code(code)
4430 code.putln("case %s:" % cond.result())
4431 self.body.generate_execution_code(code)
4432 code.putln("break;")
4434 def generate_function_definitions(self, env, code):
4435 for cond in self.conditions:
4436 cond.generate_function_definitions(env, code)
4437 self.body.generate_function_definitions(env, code)
4439 def annotate(self, code):
4440 for cond in self.conditions:
4442 self.body.annotate(code)
4444 class SwitchStatNode(StatNode):
4445 # Generated in the optimization of an if-elif-else node
4448 # cases [SwitchCaseNode]
4449 # else_clause StatNode or None
4451 child_attrs = ['test', 'cases', 'else_clause']
4453 def generate_execution_code(self, code):
4454 self.test.generate_evaluation_code(code)
4455 code.putln("switch (%s) {" % self.test.result())
4456 for case in self.cases:
4457 case.generate_execution_code(code)
4458 if self.else_clause is not None:
4459 code.putln("default:")
4460 self.else_clause.generate_execution_code(code)
4461 code.putln("break;")
4464 def generate_function_definitions(self, env, code):
4465 self.test.generate_function_definitions(env, code)
4466 for case in self.cases:
4467 case.generate_function_definitions(env, code)
4468 if self.else_clause is not None:
4469 self.else_clause.generate_function_definitions(env, code)
4471 def annotate(self, code):
4472 self.test.annotate(code)
4473 for case in self.cases:
4475 if self.else_clause is not None:
4476 self.else_clause.annotate(code)
4478 class LoopNode(object):
4480 def analyse_control_flow(self, env):
4481 env.start_branching(self.pos)
4482 self.body.analyse_control_flow(env)
4483 env.next_branch(self.body.end_pos())
4484 if self.else_clause:
4485 self.else_clause.analyse_control_flow(env)
4486 env.finish_branching(self.end_pos())
4489 class WhileStatNode(LoopNode, StatNode):
4492 # condition ExprNode
4494 # else_clause StatNode
4496 child_attrs = ["condition", "body", "else_clause"]
4498 def analyse_declarations(self, env):
4499 self.body.analyse_declarations(env)
4500 if self.else_clause:
4501 self.else_clause.analyse_declarations(env)
4503 def analyse_expressions(self, env):
4505 self.condition.analyse_temp_boolean_expression(env)
4506 self.body.analyse_expressions(env)
4507 if self.else_clause:
4508 self.else_clause.analyse_expressions(env)
4510 def generate_execution_code(self, code):
4511 old_loop_labels = code.new_loop_labels()
4514 self.condition.generate_evaluation_code(code)
4515 self.condition.generate_disposal_code(code)
4518 self.condition.result())
4519 self.condition.free_temps(code)
4520 self.body.generate_execution_code(code)
4521 code.put_label(code.continue_label)
4523 break_label = code.break_label
4524 code.set_loop_labels(old_loop_labels)
4525 if self.else_clause:
4526 code.putln("/*else*/ {")
4527 self.else_clause.generate_execution_code(code)
4529 code.put_label(break_label)
4531 def generate_function_definitions(self, env, code):
4532 self.condition.generate_function_definitions(env, code)
4533 self.body.generate_function_definitions(env, code)
4534 if self.else_clause is not None:
4535 self.else_clause.generate_function_definitions(env, code)
4537 def annotate(self, code):
4538 self.condition.annotate(code)
4539 self.body.annotate(code)
4540 if self.else_clause:
4541 self.else_clause.annotate(code)
4544 def ForStatNode(pos, **kw):
4545 if 'iterator' in kw:
4546 return ForInStatNode(pos, **kw)
4548 return ForFromStatNode(pos, **kw)
4550 class ForInStatNode(LoopNode, StatNode):
4554 # iterator IteratorNode
4556 # else_clause StatNode
4557 # item NextNode used internally
4559 child_attrs = ["target", "iterator", "body", "else_clause"]
4562 def analyse_declarations(self, env):
4563 self.target.analyse_target_declaration(env)
4564 self.body.analyse_declarations(env)
4565 if self.else_clause:
4566 self.else_clause.analyse_declarations(env)
4568 def analyse_expressions(self, env):
4570 self.target.analyse_target_types(env)
4571 self.iterator.analyse_expressions(env)
4572 self.item = ExprNodes.NextNode(self.iterator, env)
4573 if (self.iterator.type.is_ptr or self.iterator.type.is_array) and \
4574 self.target.type.assignable_from(self.iterator.type):
4575 # C array slice optimization.
4578 self.item = self.item.coerce_to(self.target.type, env)
4579 self.body.analyse_expressions(env)
4580 if self.else_clause:
4581 self.else_clause.analyse_expressions(env)
4583 def generate_execution_code(self, code):
4584 old_loop_labels = code.new_loop_labels()
4585 self.iterator.allocate_counter_temp(code)
4586 self.iterator.generate_evaluation_code(code)
4589 self.item.generate_evaluation_code(code)
4590 self.target.generate_assignment_code(self.item, code)
4591 self.body.generate_execution_code(code)
4592 code.put_label(code.continue_label)
4595 break_label = code.break_label
4596 code.set_loop_labels(old_loop_labels)
4598 if self.else_clause:
4599 # in nested loops, the 'else' block can contain a
4600 # 'continue' statement for the outer loop, but we may need
4601 # to generate cleanup code before taking that path, so we
4603 orig_continue_label = code.continue_label
4604 code.continue_label = code.new_label('outer_continue')
4606 code.putln("/*else*/ {")
4607 self.else_clause.generate_execution_code(code)
4610 if code.label_used(code.continue_label):
4611 code.put_goto(break_label)
4612 code.put_label(code.continue_label)
4613 self.iterator.generate_disposal_code(code)
4614 code.put_goto(orig_continue_label)
4615 code.set_loop_labels(old_loop_labels)
4617 if code.label_used(break_label):
4618 code.put_label(break_label)
4619 self.iterator.release_counter_temp(code)
4620 self.iterator.generate_disposal_code(code)
4621 self.iterator.free_temps(code)
4623 def generate_function_definitions(self, env, code):
4624 self.target.generate_function_definitions(env, code)
4625 self.iterator.generate_function_definitions(env, code)
4626 self.body.generate_function_definitions(env, code)
4627 if self.else_clause is not None:
4628 self.else_clause.generate_function_definitions(env, code)
4630 def annotate(self, code):
4631 self.target.annotate(code)
4632 self.iterator.annotate(code)
4633 self.body.annotate(code)
4634 if self.else_clause:
4635 self.else_clause.annotate(code)
4636 self.item.annotate(code)
4639 class ForFromStatNode(LoopNode, StatNode):
4640 # for name from expr rel name rel expr
4647 # step ExprNode or None
4649 # else_clause StatNode or None
4655 # loopvar_node ExprNode (usually a NameNode or temp node)
4656 # py_loopvar_node PyTempNode or None
4657 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4659 is_py_target = False
4661 py_loopvar_node = None
4664 gil_message = "For-loop using object bounds or target"
4666 def nogil_check(self, env):
4667 for x in (self.target, self.bound1, self.bound2):
4668 if x.type.is_pyobject:
4671 def analyse_declarations(self, env):
4672 self.target.analyse_target_declaration(env)
4673 self.body.analyse_declarations(env)
4674 if self.else_clause:
4675 self.else_clause.analyse_declarations(env)
4677 def analyse_expressions(self, env):
4679 self.target.analyse_target_types(env)
4680 self.bound1.analyse_types(env)
4681 self.bound2.analyse_types(env)
4682 if self.step is not None:
4683 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4684 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4685 self.step.analyse_types(env)
4687 target_type = self.target.type
4688 if self.target.type.is_numeric:
4689 loop_type = self.target.type
4691 loop_type = PyrexTypes.c_int_type
4692 if not self.bound1.type.is_pyobject:
4693 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4694 if not self.bound2.type.is_pyobject:
4695 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4696 if self.step is not None and not self.step.type.is_pyobject:
4697 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4698 self.bound1 = self.bound1.coerce_to(loop_type, env)
4699 self.bound2 = self.bound2.coerce_to(loop_type, env)
4700 if not self.bound2.is_literal:
4701 self.bound2 = self.bound2.coerce_to_temp(env)
4702 if self.step is not None:
4703 self.step = self.step.coerce_to(loop_type, env)
4704 if not self.step.is_literal:
4705 self.step = self.step.coerce_to_temp(env)
4707 target_type = self.target.type
4708 if not (target_type.is_pyobject or target_type.is_numeric):
4709 error(self.target.pos,
4710 "for-from loop variable must be c numeric type or Python object")
4711 if target_type.is_numeric:
4712 self.is_py_target = False
4713 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4714 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4715 self.loopvar_node = self.target
4716 self.py_loopvar_node = None
4718 self.is_py_target = True
4719 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4720 self.loopvar_node = c_loopvar_node
4721 self.py_loopvar_node = \
4722 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4723 self.body.analyse_expressions(env)
4724 if self.else_clause:
4725 self.else_clause.analyse_expressions(env)
4727 def generate_execution_code(self, code):
4728 old_loop_labels = code.new_loop_labels()
4729 from_range = self.from_range
4730 self.bound1.generate_evaluation_code(code)
4731 self.bound2.generate_evaluation_code(code)
4732 offset, incop = self.relation_table[self.relation1]
4733 if self.step is not None:
4734 self.step.generate_evaluation_code(code)
4735 step = self.step.result()
4736 incop = "%s=%s" % (incop[0], step)
4738 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4739 self.loopvar_node.allocate(code)
4740 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4741 self.py_loopvar_node.allocate(code)
4743 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4745 loopvar_name = self.loopvar_node.result()
4747 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4749 self.bound1.result(), offset,
4750 loopvar_name, self.relation2, self.bound2.result(),
4751 loopvar_name, incop))
4752 if self.py_loopvar_node:
4753 self.py_loopvar_node.generate_evaluation_code(code)
4754 self.target.generate_assignment_code(self.py_loopvar_node, code)
4756 code.putln("%s = %s;" % (
4757 self.target.result(), loopvar_name))
4758 self.body.generate_execution_code(code)
4759 code.put_label(code.continue_label)
4760 if self.py_loopvar_node:
4761 # This mess is to make for..from loops with python targets behave
4762 # exactly like those with C targets with regards to re-assignment
4763 # of the loop variable.
4765 if self.target.entry.is_pyglobal:
4766 # We know target is a NameNode, this is the only ugly case.
4767 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4768 target_node.allocate(code)
4769 interned_cname = code.intern_identifier(self.target.entry.name)
4770 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4771 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4772 target_node.result(),
4773 Naming.module_cname,
4775 code.error_goto_if_null(target_node.result(), self.target.pos)))
4776 code.put_gotref(target_node.result())
4778 target_node = self.target
4779 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4780 from_py_node.temp_code = loopvar_name
4781 from_py_node.generate_result_code(code)
4782 if self.target.entry.is_pyglobal:
4783 code.put_decref(target_node.result(), target_node.type)
4784 target_node.release(code)
4786 if self.py_loopvar_node:
4787 # This is potentially wasteful, but we don't want the semantics to
4788 # depend on whether or not the loop is a python type.
4789 self.py_loopvar_node.generate_evaluation_code(code)
4790 self.target.generate_assignment_code(self.py_loopvar_node, code)
4792 code.funcstate.release_temp(loopvar_name)
4793 break_label = code.break_label
4794 code.set_loop_labels(old_loop_labels)
4795 if self.else_clause:
4796 code.putln("/*else*/ {")
4797 self.else_clause.generate_execution_code(code)
4799 code.put_label(break_label)
4800 self.bound1.generate_disposal_code(code)
4801 self.bound1.free_temps(code)
4802 self.bound2.generate_disposal_code(code)
4803 self.bound2.free_temps(code)
4804 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4805 self.loopvar_node.release(code)
4806 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4807 self.py_loopvar_node.release(code)
4808 if self.step is not None:
4809 self.step.generate_disposal_code(code)
4810 self.step.free_temps(code)
4813 # {relop : (initial offset, increment op)}
4820 def generate_function_definitions(self, env, code):
4821 self.target.generate_function_definitions(env, code)
4822 self.bound1.generate_function_definitions(env, code)
4823 self.bound2.generate_function_definitions(env, code)
4824 if self.step is not None:
4825 self.step.generate_function_definitions(env, code)
4826 self.body.generate_function_definitions(env, code)
4827 if self.else_clause is not None:
4828 self.else_clause.generate_function_definitions(env, code)
4830 def annotate(self, code):
4831 self.target.annotate(code)
4832 self.bound1.annotate(code)
4833 self.bound2.annotate(code)
4835 self.step.annotate(code)
4836 self.body.annotate(code)
4837 if self.else_clause:
4838 self.else_clause.annotate(code)
4841 class WithStatNode(StatNode):
4843 Represents a Python with statement.
4845 This is only used at parse tree level; and is not present in
4846 analysis or generation phases.
4848 # manager The with statement manager object
4849 # target Node (lhs expression)
4851 child_attrs = ["manager", "target", "body"]
4853 class TryExceptStatNode(StatNode):
4854 # try .. except statement
4857 # except_clauses [ExceptClauseNode]
4858 # else_clause StatNode or None
4860 child_attrs = ["body", "except_clauses", "else_clause"]
4862 def analyse_control_flow(self, env):
4863 env.start_branching(self.pos)
4864 self.body.analyse_control_flow(env)
4865 successful_try = env.control_flow # grab this for later
4866 env.next_branch(self.body.end_pos())
4867 env.finish_branching(self.body.end_pos())
4869 env.start_branching(self.except_clauses[0].pos)
4870 for except_clause in self.except_clauses:
4871 except_clause.analyse_control_flow(env)
4872 env.next_branch(except_clause.end_pos())
4874 # the else cause it executed only when the try clause finishes
4875 env.control_flow.incoming = successful_try
4876 if self.else_clause:
4877 self.else_clause.analyse_control_flow(env)
4878 env.finish_branching(self.end_pos())
4880 def analyse_declarations(self, env):
4881 self.body.analyse_declarations(env)
4882 for except_clause in self.except_clauses:
4883 except_clause.analyse_declarations(env)
4884 if self.else_clause:
4885 self.else_clause.analyse_declarations(env)
4886 env.use_utility_code(reset_exception_utility_code)
4888 def analyse_expressions(self, env):
4889 self.body.analyse_expressions(env)
4890 default_clause_seen = 0
4891 for except_clause in self.except_clauses:
4892 except_clause.analyse_expressions(env)
4893 if default_clause_seen:
4894 error(except_clause.pos, "default 'except:' must be last")
4895 if not except_clause.pattern:
4896 default_clause_seen = 1
4897 self.has_default_clause = default_clause_seen
4898 if self.else_clause:
4899 self.else_clause.analyse_expressions(env)
4901 nogil_check = Node.gil_error
4902 gil_message = "Try-except statement"
4904 def generate_execution_code(self, code):
4905 old_return_label = code.return_label
4906 old_break_label = code.break_label
4907 old_continue_label = code.continue_label
4908 old_error_label = code.new_error_label()
4909 our_error_label = code.error_label
4910 except_end_label = code.new_label('exception_handled')
4911 except_error_label = code.new_label('except_error')
4912 except_return_label = code.new_label('except_return')
4913 try_return_label = code.new_label('try_return')
4914 try_break_label = code.new_label('try_break')
4915 try_continue_label = code.new_label('try_continue')
4916 try_end_label = code.new_label('try_end')
4918 exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
4921 code.putln("__Pyx_ExceptionSave(%s);" %
4922 ', '.join(['&%s' % var for var in exc_save_vars]))
4923 for var in exc_save_vars:
4924 code.put_xgotref(var)
4927 code.return_label = try_return_label
4928 code.break_label = try_break_label
4929 code.continue_label = try_continue_label
4930 self.body.generate_execution_code(code)
4933 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4934 code.error_label = except_error_label
4935 code.return_label = except_return_label
4936 if self.else_clause:
4939 self.else_clause.generate_execution_code(code)
4942 for var in exc_save_vars:
4943 code.put_xdecref_clear(var, py_object_type)
4944 code.put_goto(try_end_label)
4945 if code.label_used(try_return_label):
4946 code.put_label(try_return_label)
4947 for var in exc_save_vars:
4948 code.put_xgiveref(var)
4949 code.putln("__Pyx_ExceptionReset(%s);" %
4950 ', '.join(exc_save_vars))
4951 code.put_goto(old_return_label)
4952 code.put_label(our_error_label)
4953 for temp_name, type in temps_to_clean_up:
4954 code.put_xdecref_clear(temp_name, type)
4955 for except_clause in self.except_clauses:
4956 except_clause.generate_handling_code(code, except_end_label)
4958 error_label_used = code.label_used(except_error_label)
4959 if error_label_used or not self.has_default_clause:
4960 if error_label_used:
4961 code.put_label(except_error_label)
4962 for var in exc_save_vars:
4963 code.put_xgiveref(var)
4964 code.putln("__Pyx_ExceptionReset(%s);" %
4965 ', '.join(exc_save_vars))
4966 code.put_goto(old_error_label)
4968 for exit_label, old_label in zip(
4969 [try_break_label, try_continue_label, except_return_label],
4970 [old_break_label, old_continue_label, old_return_label]):
4972 if code.label_used(exit_label):
4973 code.put_label(exit_label)
4974 for var in exc_save_vars:
4975 code.put_xgiveref(var)
4976 code.putln("__Pyx_ExceptionReset(%s);" %
4977 ', '.join(exc_save_vars))
4978 code.put_goto(old_label)
4980 if code.label_used(except_end_label):
4981 code.put_label(except_end_label)
4982 for var in exc_save_vars:
4983 code.put_xgiveref(var)
4984 code.putln("__Pyx_ExceptionReset(%s);" %
4985 ', '.join(exc_save_vars))
4986 code.put_label(try_end_label)
4989 for cname in exc_save_vars:
4990 code.funcstate.release_temp(cname)
4992 code.return_label = old_return_label
4993 code.break_label = old_break_label
4994 code.continue_label = old_continue_label
4995 code.error_label = old_error_label
4997 def generate_function_definitions(self, env, code):
4998 self.body.generate_function_definitions(env, code)
4999 for except_clause in self.except_clauses:
5000 except_clause.generate_function_definitions(env, code)
5001 if self.else_clause is not None:
5002 self.else_clause.generate_function_definitions(env, code)
5004 def annotate(self, code):
5005 self.body.annotate(code)
5006 for except_node in self.except_clauses:
5007 except_node.annotate(code)
5008 if self.else_clause:
5009 self.else_clause.annotate(code)
5012 class ExceptClauseNode(Node):
5013 # Part of try ... except statement.
5015 # pattern [ExprNode]
5016 # target ExprNode or None
5018 # excinfo_target NameNode or None optional target for exception info
5019 # match_flag string result of exception match
5020 # exc_value ExcValueNode used internally
5021 # function_name string qualified name of enclosing function
5022 # exc_vars (string * 3) local exception variables
5024 # excinfo_target is never set by the parser, but can be set by a transform
5025 # in order to extract more extensive information about the exception as a
5026 # sys.exc_info()-style tuple into a target variable
5028 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
5031 excinfo_target = None
5033 def analyse_declarations(self, env):
5035 self.target.analyse_target_declaration(env)
5036 if self.excinfo_target is not None:
5037 self.excinfo_target.analyse_target_declaration(env)
5038 self.body.analyse_declarations(env)
5040 def analyse_expressions(self, env):
5042 genv = env.global_scope()
5043 self.function_name = env.qualified_name
5045 # normalise/unpack self.pattern into a list
5046 for i, pattern in enumerate(self.pattern):
5047 pattern.analyse_expressions(env)
5048 self.pattern[i] = pattern.coerce_to_pyobject(env)
5051 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
5052 self.target.analyse_target_expression(env, self.exc_value)
5053 if self.excinfo_target is not None:
5055 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
5056 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
5057 self.excinfo_tuple.analyse_expressions(env)
5058 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
5060 self.body.analyse_expressions(env)
5062 def generate_handling_code(self, code, end_label):
5063 code.mark_pos(self.pos)
5066 for pattern in self.pattern:
5067 pattern.generate_evaluation_code(code)
5068 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
5070 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
5072 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
5073 for pattern in self.pattern:
5074 pattern.generate_disposal_code(code)
5075 pattern.free_temps(code)
5079 code.funcstate.release_temp(match_flag)
5081 code.putln("/*except:*/ {")
5083 if not getattr(self.body, 'stats', True) and \
5084 self.excinfo_target is None and self.target is None:
5085 # most simple case: no exception variable, empty body (pass)
5086 # => reset the exception state, done
5087 code.putln("PyErr_Restore(0,0,0);")
5088 code.put_goto(end_label)
5092 exc_vars = [code.funcstate.allocate_temp(py_object_type,
5095 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
5096 # We always have to fetch the exception value even if
5097 # there is no target, because this also normalises the
5098 # exception and stores it in the thread state.
5099 code.globalstate.use_utility_code(get_exception_utility_code)
5100 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
5101 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
5102 code.error_goto(self.pos)))
5106 self.exc_value.set_var(exc_vars[1])
5107 self.exc_value.generate_evaluation_code(code)
5108 self.target.generate_assignment_code(self.exc_value, code)
5109 if self.excinfo_target is not None:
5110 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
5111 node.set_var(tempvar)
5112 self.excinfo_tuple.generate_evaluation_code(code)
5113 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
5115 old_break_label, old_continue_label = code.break_label, code.continue_label
5116 code.break_label = code.new_label('except_break')
5117 code.continue_label = code.new_label('except_continue')
5119 old_exc_vars = code.funcstate.exc_vars
5120 code.funcstate.exc_vars = exc_vars
5121 self.body.generate_execution_code(code)
5122 code.funcstate.exc_vars = old_exc_vars
5123 for var in exc_vars:
5124 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
5125 code.put_goto(end_label)
5127 if code.label_used(code.break_label):
5128 code.put_label(code.break_label)
5129 for var in exc_vars:
5130 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
5131 code.put_goto(old_break_label)
5132 code.break_label = old_break_label
5134 if code.label_used(code.continue_label):
5135 code.put_label(code.continue_label)
5136 for var in exc_vars:
5137 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
5138 code.put_goto(old_continue_label)
5139 code.continue_label = old_continue_label
5141 for temp in exc_vars:
5142 code.funcstate.release_temp(temp)
5147 def generate_function_definitions(self, env, code):
5148 if self.target is not None:
5149 self.target.generate_function_definitions(env, code)
5150 self.body.generate_function_definitions(env, code)
5152 def annotate(self, code):
5154 for pattern in self.pattern:
5155 pattern.annotate(code)
5157 self.target.annotate(code)
5158 self.body.annotate(code)
5161 class TryFinallyStatNode(StatNode):
5162 # try ... finally statement
5165 # finally_clause StatNode
5167 # The plan is that we funnel all continue, break
5168 # return and error gotos into the beginning of the
5169 # finally block, setting a variable to remember which
5170 # one we're doing. At the end of the finally block, we
5171 # switch on the variable to figure out where to go.
5172 # In addition, if we're doing an error, we save the
5173 # exception on entry to the finally block and restore
5176 child_attrs = ["body", "finally_clause"]
5178 preserve_exception = 1
5180 disallow_continue_in_try_finally = 0
5181 # There doesn't seem to be any point in disallowing
5182 # continue in the try block, since we have no problem
5185 def create_analysed(pos, env, body, finally_clause):
5186 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5188 create_analysed = staticmethod(create_analysed)
5190 def analyse_control_flow(self, env):
5191 env.start_branching(self.pos)
5192 self.body.analyse_control_flow(env)
5193 env.next_branch(self.body.end_pos())
5194 env.finish_branching(self.body.end_pos())
5195 self.finally_clause.analyse_control_flow(env)
5197 def analyse_declarations(self, env):
5198 self.body.analyse_declarations(env)
5199 self.finally_clause.analyse_declarations(env)
5201 def analyse_expressions(self, env):
5202 self.body.analyse_expressions(env)
5203 self.finally_clause.analyse_expressions(env)
5205 nogil_check = Node.gil_error
5206 gil_message = "Try-finally statement"
5208 def generate_execution_code(self, code):
5209 old_error_label = code.error_label
5210 old_labels = code.all_new_labels()
5211 new_labels = code.get_all_labels()
5212 new_error_label = code.error_label
5213 catch_label = code.new_label()
5216 if self.disallow_continue_in_try_finally:
5217 was_in_try_finally = code.funcstate.in_try_finally
5218 code.funcstate.in_try_finally = 1
5219 self.body.generate_execution_code(code)
5220 if self.disallow_continue_in_try_finally:
5221 code.funcstate.in_try_finally = was_in_try_finally
5224 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5225 code.mark_pos(self.finally_clause.pos)
5229 error_label_used = 0
5230 for i, new_label in enumerate(new_labels):
5231 if new_label in code.labels_used:
5232 cases_used.append(i)
5233 if new_label == new_error_label:
5234 error_label_used = 1
5235 error_label_case = i
5239 if error_label_used and self.preserve_exception:
5241 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5243 "int %s;" % Naming.exc_lineno_name)
5244 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5245 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5246 code.putln(exc_var_init_zero)
5248 exc_var_init_zero = None
5249 code.use_label(catch_label)
5251 "__pyx_why = 0; goto %s;" % catch_label)
5252 for i in cases_used:
5253 new_label = new_labels[i]
5254 #if new_label and new_label != "<try>":
5255 if new_label == new_error_label and self.preserve_exception:
5256 self.put_error_catcher(code,
5257 new_error_label, i+1, catch_label, temps_to_clean_up)
5259 code.put('%s: ' % new_label)
5260 if exc_var_init_zero:
5261 code.putln(exc_var_init_zero)
5262 code.putln("__pyx_why = %s; goto %s;" % (
5265 code.put_label(catch_label)
5266 code.set_all_labels(old_labels)
5267 if error_label_used:
5268 code.new_error_label()
5269 finally_error_label = code.error_label
5270 self.finally_clause.generate_execution_code(code)
5271 if error_label_used:
5272 if finally_error_label in code.labels_used and self.preserve_exception:
5273 over_label = code.new_label()
5274 code.put_goto(over_label);
5275 code.put_label(finally_error_label)
5276 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5277 for var in Naming.exc_vars:
5278 code.putln("Py_XDECREF(%s);" % var)
5280 code.put_goto(old_error_label)
5281 code.put_label(over_label)
5282 code.error_label = old_error_label
5285 "switch (__pyx_why) {")
5286 for i in cases_used:
5287 old_label = old_labels[i]
5288 if old_label == old_error_label and self.preserve_exception:
5289 self.put_error_uncatcher(code, i+1, old_error_label)
5291 code.use_label(old_label)
5293 "case %s: goto %s;" % (
5301 def generate_function_definitions(self, env, code):
5302 self.body.generate_function_definitions(env, code)
5303 self.finally_clause.generate_function_definitions(env, code)
5305 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5306 code.globalstate.use_utility_code(restore_exception_utility_code)
5313 for temp_name, type in temps_to_clean_up:
5314 code.put_xdecref_clear(temp_name, type)
5316 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5320 Naming.exc_lineno_name, Naming.lineno_cname))
5321 code.put_goto(catch_label)
5324 def put_error_uncatcher(self, code, i, error_label):
5325 code.globalstate.use_utility_code(restore_exception_utility_code)
5330 "__Pyx_ErrRestore(%s, %s, %s);" %
5334 Naming.lineno_cname, Naming.exc_lineno_name))
5335 for var in Naming.exc_vars:
5339 code.put_goto(error_label)
5343 def annotate(self, code):
5344 self.body.annotate(code)
5345 self.finally_clause.annotate(code)
5348 class GILStatNode(TryFinallyStatNode):
5349 # 'with gil' or 'with nogil' statement
5351 # state string 'gil' or 'nogil'
5355 preserve_exception = 0
5357 def __init__(self, pos, state, body):
5359 TryFinallyStatNode.__init__(self, pos,
5361 finally_clause = GILExitNode(pos, state = state))
5363 def analyse_expressions(self, env):
5364 env.use_utility_code(force_init_threads_utility_code)
5365 was_nogil = env.nogil
5367 TryFinallyStatNode.analyse_expressions(self, env)
5368 env.nogil = was_nogil
5372 def generate_execution_code(self, code):
5373 code.mark_pos(self.pos)
5375 if self.state == 'gil':
5376 code.putln("#ifdef WITH_THREAD")
5377 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5378 code.putln("#endif")
5380 code.putln("#ifdef WITH_THREAD")
5381 code.putln("PyThreadState *_save = NULL;")
5382 code.putln("#endif")
5383 code.putln("Py_UNBLOCK_THREADS")
5384 TryFinallyStatNode.generate_execution_code(self, code)
5388 class GILExitNode(StatNode):
5389 # Used as the 'finally' block in a GILStatNode
5391 # state string 'gil' or 'nogil'
5395 def analyse_expressions(self, env):
5398 def generate_execution_code(self, code):
5399 if self.state == 'gil':
5400 code.putln("#ifdef WITH_THREAD")
5401 code.putln("PyGILState_Release(_save);")
5402 code.putln("#endif")
5404 code.putln("Py_BLOCK_THREADS")
5407 class CImportStatNode(StatNode):
5410 # module_name string Qualified name of module being imported
5411 # as_name string or None Name specified in "as" clause, if any
5415 def analyse_declarations(self, env):
5416 if not env.is_module_scope:
5417 error(self.pos, "cimport only allowed at module level")
5419 module_scope = env.find_module(self.module_name, self.pos)
5420 if "." in self.module_name:
5421 names = [EncodedString(name) for name in self.module_name.split(".")]
5423 top_module_scope = env.context.find_submodule(top_name)
5424 module_scope = top_module_scope
5425 for name in names[1:]:
5426 submodule_scope = module_scope.find_submodule(name)
5427 module_scope.declare_module(name, submodule_scope, self.pos)
5428 module_scope = submodule_scope
5430 env.declare_module(self.as_name, module_scope, self.pos)
5432 env.declare_module(top_name, top_module_scope, self.pos)
5434 name = self.as_name or self.module_name
5435 env.declare_module(name, module_scope, self.pos)
5437 def analyse_expressions(self, env):
5440 def generate_execution_code(self, code):
5444 class FromCImportStatNode(StatNode):
5445 # from ... cimport statement
5447 # module_name string Qualified name of module
5448 # imported_names [(pos, name, as_name, kind)] Names to be imported
5452 def analyse_declarations(self, env):
5453 if not env.is_module_scope:
5454 error(self.pos, "cimport only allowed at module level")
5456 module_scope = env.find_module(self.module_name, self.pos)
5457 env.add_imported_module(module_scope)
5458 for pos, name, as_name, kind in self.imported_names:
5460 for local_name, entry in module_scope.entries.items():
5461 env.add_imported_entry(local_name, entry, pos)
5463 entry = module_scope.lookup(name)
5465 if kind and not self.declaration_matches(entry, kind):
5466 entry.redeclared(pos)
5468 if kind == 'struct' or kind == 'union':
5469 entry = module_scope.declare_struct_or_union(name,
5470 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5471 elif kind == 'class':
5472 entry = module_scope.declare_c_class(name, pos = pos,
5473 module_name = self.module_name)
5475 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5476 if submodule_scope.parent_module is module_scope:
5477 env.declare_module(as_name or name, submodule_scope, self.pos)
5479 error(pos, "Name '%s' not declared in module '%s'"
5480 % (name, self.module_name))
5483 local_name = as_name or name
5484 env.add_imported_entry(local_name, entry, pos)
5486 def declaration_matches(self, entry, kind):
5487 if not entry.is_type:
5491 if not type.is_extension_type:
5494 if not type.is_struct_or_union:
5496 if kind != type.kind:
5500 def analyse_expressions(self, env):
5503 def generate_execution_code(self, code):
5507 class FromImportStatNode(StatNode):
5508 # from ... import statement
5511 # items [(string, NameNode)]
5512 # interned_items [(string, NameNode, ExprNode)]
5513 # item PyTempNode used internally
5514 # import_star boolean used internally
5516 child_attrs = ["module"]
5519 def analyse_declarations(self, env):
5520 for name, target in self.items:
5522 if not env.is_module_scope:
5523 error(self.pos, "import * only allowed at module level")
5525 env.has_import_star = 1
5526 self.import_star = 1
5528 target.analyse_target_declaration(env)
5530 def analyse_expressions(self, env):
5532 self.module.analyse_expressions(env)
5533 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5534 self.interned_items = []
5535 for name, target in self.items:
5537 for _, entry in env.entries.items():
5538 if not entry.is_type and entry.type.is_extension_type:
5539 env.use_utility_code(ExprNodes.type_test_utility_code)
5542 entry = env.lookup(target.name)
5543 # check whether or not entry is already cimported
5544 if (entry.is_type and entry.type.name == name
5545 and hasattr(entry.type, 'module_name')):
5546 if entry.type.module_name == self.module.module_name.value:
5547 # cimported with absolute name
5550 # cimported with relative name
5551 module = env.find_module(self.module.module_name.value,
5553 if entry.type.module_name == module.qualified_name:
5555 except AttributeError:
5557 target.analyse_target_expression(env, None)
5558 if target.type is py_object_type:
5561 coerced_item = self.item.coerce_to(target.type, env)
5562 self.interned_items.append((name, target, coerced_item))
5564 def generate_execution_code(self, code):
5565 self.module.generate_evaluation_code(code)
5566 if self.import_star:
5568 'if (%s(%s) < 0) %s;' % (
5570 self.module.py_result(),
5571 code.error_goto(self.pos)))
5572 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5573 self.item.set_cname(item_temp)
5574 for name, target, coerced_item in self.interned_items:
5575 cname = code.intern_identifier(name)
5577 '%s = PyObject_GetAttr(%s, %s); %s' % (
5579 self.module.py_result(),
5581 code.error_goto_if_null(item_temp, self.pos)))
5582 code.put_gotref(item_temp)
5583 if coerced_item is None:
5584 target.generate_assignment_code(self.item, code)
5586 coerced_item.allocate_temp_result(code)
5587 coerced_item.generate_result_code(code)
5588 target.generate_assignment_code(coerced_item, code)
5589 code.put_decref_clear(item_temp, py_object_type)
5590 code.funcstate.release_temp(item_temp)
5591 self.module.generate_disposal_code(code)
5592 self.module.free_temps(code)
5596 #------------------------------------------------------------------------------------
5598 # Runtime support code
5600 #------------------------------------------------------------------------------------
5602 utility_function_predeclarations = \
5604 /* inline attribute */
5605 #ifndef CYTHON_INLINE
5606 #if defined(__GNUC__)
5607 #define CYTHON_INLINE __inline__
5608 #elif defined(_MSC_VER)
5609 #define CYTHON_INLINE __inline
5610 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5611 #define CYTHON_INLINE inline
5613 #define CYTHON_INLINE
5617 /* unused attribute */
5618 #ifndef CYTHON_UNUSED
5619 # if defined(__GNUC__)
5620 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5621 # define CYTHON_UNUSED __attribute__ ((__unused__))
5623 # define CYTHON_UNUSED
5625 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5626 # define CYTHON_UNUSED __attribute__ ((__unused__))
5628 # define CYTHON_UNUSED
5632 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*/
5636 if Options.gcc_branch_hints:
5637 branch_prediction_macros = \
5640 /* Test for GCC > 2.95 */
5641 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5642 #define likely(x) __builtin_expect(!!(x), 1)
5643 #define unlikely(x) __builtin_expect(!!(x), 0)
5644 #else /* __GNUC__ > 2 ... */
5645 #define likely(x) (x)
5646 #define unlikely(x) (x)
5647 #endif /* __GNUC__ > 2 ... */
5648 #else /* __GNUC__ */
5649 #define likely(x) (x)
5650 #define unlikely(x) (x)
5651 #endif /* __GNUC__ */
5654 branch_prediction_macros = \
5656 #define likely(x) (x)
5657 #define unlikely(x) (x)
5660 #get_name_predeclaration = \
5661 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5663 #get_name_interned_predeclaration = \
5664 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5666 #------------------------------------------------------------------------------------
5668 printing_utility_code = UtilityCode(
5670 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5671 #if PY_MAJOR_VERSION >= 3
5672 static PyObject* %s = 0;
5673 static PyObject* %s = 0;
5675 """ % (Naming.print_function, Naming.print_function_kwargs),
5677 #if PY_MAJOR_VERSION >= 3
5681 """ % (Naming.print_function, Naming.print_function_kwargs),
5683 #if PY_MAJOR_VERSION < 3
5684 static PyObject *__Pyx_GetStdout(void) {
5685 PyObject *f = PySys_GetObject((char *)"stdout");
5687 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5692 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5697 if (!(f = __Pyx_GetStdout()))
5700 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5701 if (PyFile_SoftSpace(f, 1)) {
5702 if (PyFile_WriteString(" ", f) < 0)
5705 v = PyTuple_GET_ITEM(arg_tuple, i);
5706 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5708 if (PyString_Check(v)) {
5709 char *s = PyString_AsString(v);
5710 Py_ssize_t len = PyString_Size(v);
5712 isspace(Py_CHARMASK(s[len-1])) &&
5714 PyFile_SoftSpace(f, 0);
5718 if (PyFile_WriteString("\n", f) < 0)
5720 PyFile_SoftSpace(f, 0);
5725 #else /* Python 3 has a print function */
5727 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5728 PyObject* kwargs = 0;
5729 PyObject* result = 0;
5730 PyObject* end_string;
5731 if (unlikely(!%(PRINT_FUNCTION)s)) {
5732 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5733 if (!%(PRINT_FUNCTION)s)
5737 kwargs = PyDict_New();
5738 if (unlikely(!kwargs))
5740 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5743 end_string = PyUnicode_FromStringAndSize(" ", 1);
5744 if (unlikely(!end_string))
5746 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5747 Py_DECREF(end_string);
5750 Py_DECREF(end_string);
5752 } else if (!newline) {
5753 if (unlikely(!%(PRINT_KWARGS)s)) {
5754 %(PRINT_KWARGS)s = PyDict_New();
5755 if (unlikely(!%(PRINT_KWARGS)s))
5757 end_string = PyUnicode_FromStringAndSize(" ", 1);
5758 if (unlikely(!end_string))
5760 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5761 Py_DECREF(end_string);
5764 Py_DECREF(end_string);
5766 kwargs = %(PRINT_KWARGS)s;
5768 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5769 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5776 if (kwargs != %(PRINT_KWARGS)s)
5782 """ % {'BUILTINS' : Naming.builtins_cname,
5783 'PRINT_FUNCTION' : Naming.print_function,
5784 'PRINT_KWARGS' : Naming.print_function_kwargs}
5788 printing_one_utility_code = UtilityCode(
5790 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5793 #if PY_MAJOR_VERSION < 3
5795 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5797 if (!(f = __Pyx_GetStdout()))
5800 if (PyFile_SoftSpace(f, 0)) {
5801 if (PyFile_WriteString(" ", f) < 0)
5804 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5806 if (PyFile_WriteString("\n", f) < 0)
5809 /* the line below is just to avoid compiler
5810 * compiler warnings about unused functions */
5811 return __Pyx_Print(f, NULL, 0);
5814 #else /* Python 3 has a print function */
5816 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5818 PyObject* arg_tuple = PyTuple_New(1);
5819 if (unlikely(!arg_tuple))
5822 PyTuple_SET_ITEM(arg_tuple, 0, o);
5823 res = __Pyx_Print(stream, arg_tuple, 1);
5824 Py_DECREF(arg_tuple);
5830 requires=[printing_utility_code])
5834 #------------------------------------------------------------------------------------
5836 # Exception raising code
5838 # Exceptions are raised by __Pyx_Raise() and stored as plain
5839 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5840 # 'except' statement, curexc_* is moved over to exc_* by
5841 # __Pyx_GetException()
5843 restore_exception_utility_code = UtilityCode(
5845 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5846 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5849 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5850 PyObject *tmp_type, *tmp_value, *tmp_tb;
5851 PyThreadState *tstate = PyThreadState_GET();
5853 tmp_type = tstate->curexc_type;
5854 tmp_value = tstate->curexc_value;
5855 tmp_tb = tstate->curexc_traceback;
5856 tstate->curexc_type = type;
5857 tstate->curexc_value = value;
5858 tstate->curexc_traceback = tb;
5859 Py_XDECREF(tmp_type);
5860 Py_XDECREF(tmp_value);
5864 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5865 PyThreadState *tstate = PyThreadState_GET();
5866 *type = tstate->curexc_type;
5867 *value = tstate->curexc_value;
5868 *tb = tstate->curexc_traceback;
5870 tstate->curexc_type = 0;
5871 tstate->curexc_value = 0;
5872 tstate->curexc_traceback = 0;
5877 # The following function is based on do_raise() from ceval.c. There
5878 # are separate versions for Python2 and Python3 as exception handling
5879 # has changed quite a lot between the two versions.
5881 raise_utility_code = UtilityCode(
5883 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5886 #if PY_MAJOR_VERSION < 3
5887 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5891 /* First, check the traceback argument, replacing None with NULL. */
5892 if (tb == Py_None) {
5896 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5897 PyErr_SetString(PyExc_TypeError,
5898 "raise: arg 3 must be a traceback or None");
5901 /* Next, replace a missing value with None */
5902 if (value == NULL) {
5906 #if PY_VERSION_HEX < 0x02050000
5907 if (!PyClass_Check(type))
5909 if (!PyType_Check(type))
5912 /* Raising an instance. The value should be a dummy. */
5913 if (value != Py_None) {
5914 PyErr_SetString(PyExc_TypeError,
5915 "instance exception may not have a separate value");
5918 /* Normalize to raise <class>, <instance> */
5921 #if PY_VERSION_HEX < 0x02050000
5922 if (PyInstance_Check(type)) {
5923 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5928 PyErr_SetString(PyExc_TypeError,
5929 "raise: exception must be an old-style class or instance");
5933 type = (PyObject*) Py_TYPE(type);
5935 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5936 PyErr_SetString(PyExc_TypeError,
5937 "raise: exception class must be a subclass of BaseException");
5943 __Pyx_ErrRestore(type, value, tb);
5952 #else /* Python 3+ */
5954 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5955 if (tb == Py_None) {
5957 } else if (tb && !PyTraceBack_Check(tb)) {
5958 PyErr_SetString(PyExc_TypeError,
5959 "raise: arg 3 must be a traceback or None");
5962 if (value == Py_None)
5965 if (PyExceptionInstance_Check(type)) {
5967 PyErr_SetString(PyExc_TypeError,
5968 "instance exception may not have a separate value");
5972 type = (PyObject*) Py_TYPE(value);
5973 } else if (!PyExceptionClass_Check(type)) {
5974 PyErr_SetString(PyExc_TypeError,
5975 "raise: exception class must be a subclass of BaseException");
5979 PyErr_SetObject(type, value);
5982 PyThreadState *tstate = PyThreadState_GET();
5983 PyObject* tmp_tb = tstate->curexc_traceback;
5986 tstate->curexc_traceback = tb;
5996 requires=[restore_exception_utility_code])
5998 #------------------------------------------------------------------------------------
6000 get_exception_utility_code = UtilityCode(
6002 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6005 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
6006 PyObject *local_type, *local_value, *local_tb;
6007 PyObject *tmp_type, *tmp_value, *tmp_tb;
6008 PyThreadState *tstate = PyThreadState_GET();
6009 local_type = tstate->curexc_type;
6010 local_value = tstate->curexc_value;
6011 local_tb = tstate->curexc_traceback;
6012 tstate->curexc_type = 0;
6013 tstate->curexc_value = 0;
6014 tstate->curexc_traceback = 0;
6015 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
6016 if (unlikely(tstate->curexc_type))
6018 #if PY_MAJOR_VERSION >= 3
6019 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
6023 *value = local_value;
6025 Py_INCREF(local_type);
6026 Py_INCREF(local_value);
6027 Py_INCREF(local_tb);
6028 tmp_type = tstate->exc_type;
6029 tmp_value = tstate->exc_value;
6030 tmp_tb = tstate->exc_traceback;
6031 tstate->exc_type = local_type;
6032 tstate->exc_value = local_value;
6033 tstate->exc_traceback = local_tb;
6034 /* Make sure tstate is in a consistent state when we XDECREF
6035 these objects (XDECREF may run arbitrary code). */
6036 Py_XDECREF(tmp_type);
6037 Py_XDECREF(tmp_value);
6044 Py_XDECREF(local_type);
6045 Py_XDECREF(local_value);
6046 Py_XDECREF(local_tb);
6052 #------------------------------------------------------------------------------------
6054 get_exception_tuple_utility_code = UtilityCode(proto="""
6055 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
6057 # I doubt that calling __Pyx_GetException() here is correct as it moves
6058 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
6059 # exception handlers later on from receiving it.
6061 static PyObject *__Pyx_GetExceptionTuple(void) {
6062 PyObject *type = NULL, *value = NULL, *tb = NULL;
6063 if (__Pyx_GetException(&type, &value, &tb) == 0) {
6064 PyObject* exc_info = PyTuple_New(3);
6069 PyTuple_SET_ITEM(exc_info, 0, type);
6070 PyTuple_SET_ITEM(exc_info, 1, value);
6071 PyTuple_SET_ITEM(exc_info, 2, tb);
6078 requires=[get_exception_utility_code])
6080 #------------------------------------------------------------------------------------
6082 reset_exception_utility_code = UtilityCode(
6084 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6085 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
6088 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
6089 PyThreadState *tstate = PyThreadState_GET();
6090 *type = tstate->exc_type;
6091 *value = tstate->exc_value;
6092 *tb = tstate->exc_traceback;
6098 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
6099 PyObject *tmp_type, *tmp_value, *tmp_tb;
6100 PyThreadState *tstate = PyThreadState_GET();
6101 tmp_type = tstate->exc_type;
6102 tmp_value = tstate->exc_value;
6103 tmp_tb = tstate->exc_traceback;
6104 tstate->exc_type = type;
6105 tstate->exc_value = value;
6106 tstate->exc_traceback = tb;
6107 Py_XDECREF(tmp_type);
6108 Py_XDECREF(tmp_value);
6113 #------------------------------------------------------------------------------------
6115 swap_exception_utility_code = UtilityCode(
6117 static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6120 static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
6121 PyObject *tmp_type, *tmp_value, *tmp_tb;
6122 PyThreadState *tstate = PyThreadState_GET();
6124 tmp_type = tstate->exc_type;
6125 tmp_value = tstate->exc_value;
6126 tmp_tb = tstate->exc_traceback;
6128 tstate->exc_type = *type;
6129 tstate->exc_value = *value;
6130 tstate->exc_traceback = *tb;
6138 #------------------------------------------------------------------------------------
6140 arg_type_test_utility_code = UtilityCode(
6142 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6143 const char *name, int exact); /*proto*/
6146 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6147 const char *name, int exact)
6150 PyErr_Format(PyExc_SystemError, "Missing type object");
6153 if (none_allowed && obj == Py_None) return 1;
6155 if (Py_TYPE(obj) == type) return 1;
6158 if (PyObject_TypeCheck(obj, type)) return 1;
6160 PyErr_Format(PyExc_TypeError,
6161 "Argument '%s' has incorrect type (expected %s, got %s)",
6162 name, type->tp_name, Py_TYPE(obj)->tp_name);
6167 #------------------------------------------------------------------------------------
6169 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
6170 # many or too few positional arguments were found. This handles
6171 # Py_ssize_t formatting correctly.
6173 raise_argtuple_invalid_utility_code = UtilityCode(
6175 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
6176 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
6179 static void __Pyx_RaiseArgtupleInvalid(
6180 const char* func_name,
6184 Py_ssize_t num_found)
6186 Py_ssize_t num_expected;
6187 const char *number, *more_or_less;
6189 if (num_found < num_min) {
6190 num_expected = num_min;
6191 more_or_less = "at least";
6193 num_expected = num_max;
6194 more_or_less = "at most";
6197 more_or_less = "exactly";
6199 number = (num_expected == 1) ? "" : "s";
6200 PyErr_Format(PyExc_TypeError,
6201 #if PY_VERSION_HEX < 0x02050000
6202 "%s() takes %s %d positional argument%s (%d given)",
6204 "%s() takes %s %zd positional argument%s (%zd given)",
6206 func_name, more_or_less, num_expected, number, num_found);
6210 raise_keyword_required_utility_code = UtilityCode(
6212 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6215 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6216 const char* func_name,
6219 PyErr_Format(PyExc_TypeError,
6220 #if PY_MAJOR_VERSION >= 3
6221 "%s() needs keyword-only argument %U", func_name, kw_name);
6223 "%s() needs keyword-only argument %s", func_name,
6224 PyString_AS_STRING(kw_name));
6229 raise_double_keywords_utility_code = UtilityCode(
6231 static void __Pyx_RaiseDoubleKeywordsError(
6232 const char* func_name, PyObject* kw_name); /*proto*/
6235 static void __Pyx_RaiseDoubleKeywordsError(
6236 const char* func_name,
6239 PyErr_Format(PyExc_TypeError,
6240 #if PY_MAJOR_VERSION >= 3
6241 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6243 "%s() got multiple values for keyword argument '%s'", func_name,
6244 PyString_AS_STRING(kw_name));
6249 #------------------------------------------------------------------------------------
6251 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
6252 # were passed to a function, or if any keywords were passed to a
6253 # function that does not accept them.
6255 keyword_string_check_utility_code = UtilityCode(
6257 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6258 const char* function_name, int kw_allowed); /*proto*/
6261 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6263 const char* function_name,
6268 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6269 #if PY_MAJOR_VERSION < 3
6270 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6272 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6274 goto invalid_keyword_type;
6276 if ((!kw_allowed) && unlikely(key))
6277 goto invalid_keyword;
6279 invalid_keyword_type:
6280 PyErr_Format(PyExc_TypeError,
6281 "%s() keywords must be strings", function_name);
6284 PyErr_Format(PyExc_TypeError,
6285 #if PY_MAJOR_VERSION < 3
6286 "%s() got an unexpected keyword argument '%s'",
6287 function_name, PyString_AsString(key));
6289 "%s() got an unexpected keyword argument '%U'",
6290 function_name, key);
6296 #------------------------------------------------------------------------------------
6298 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6299 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6300 # keywords will raise an invalid keyword error.
6302 # Three kinds of errors are checked: 1) non-string keywords, 2)
6303 # unexpected keywords and 3) overlap with positional arguments.
6305 # If num_posargs is greater 0, it denotes the number of positional
6306 # arguments that were passed and that must therefore not appear
6307 # amongst the keywords as well.
6309 # This method does not check for required keyword arguments.
6312 parse_keywords_utility_code = UtilityCode(
6314 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6315 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6316 const char* function_name); /*proto*/
6319 static int __Pyx_ParseOptionalKeywords(
6321 PyObject **argnames[],
6324 Py_ssize_t num_pos_args,
6325 const char* function_name)
6327 PyObject *key = 0, *value = 0;
6330 PyObject*** first_kw_arg = argnames + num_pos_args;
6332 while (PyDict_Next(kwds, &pos, &key, &value)) {
6333 name = first_kw_arg;
6334 while (*name && (**name != key)) name++;
6336 values[name-argnames] = value;
6338 #if PY_MAJOR_VERSION < 3
6339 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6341 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6343 goto invalid_keyword_type;
6345 for (name = first_kw_arg; *name; name++) {
6346 #if PY_MAJOR_VERSION >= 3
6347 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6348 PyUnicode_Compare(**name, key) == 0) break;
6350 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6351 _PyString_Eq(**name, key)) break;
6355 values[name-argnames] = value;
6357 /* unexpected keyword found */
6358 for (name=argnames; name != first_kw_arg; name++) {
6359 if (**name == key) goto arg_passed_twice;
6360 #if PY_MAJOR_VERSION >= 3
6361 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6362 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6364 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6365 _PyString_Eq(**name, key)) goto arg_passed_twice;
6369 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6371 goto invalid_keyword;
6379 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6381 invalid_keyword_type:
6382 PyErr_Format(PyExc_TypeError,
6383 "%s() keywords must be strings", function_name);
6386 PyErr_Format(PyExc_TypeError,
6387 #if PY_MAJOR_VERSION < 3
6388 "%s() got an unexpected keyword argument '%s'",
6389 function_name, PyString_AsString(key));
6391 "%s() got an unexpected keyword argument '%U'",
6392 function_name, key);
6398 requires=[raise_double_keywords_utility_code])
6400 #------------------------------------------------------------------------------------
6402 traceback_utility_code = UtilityCode(
6404 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6407 #include "compile.h"
6408 #include "frameobject.h"
6409 #include "traceback.h"
6411 static void __Pyx_AddTraceback(const char *funcname) {
6412 PyObject *py_srcfile = 0;
6413 PyObject *py_funcname = 0;
6414 PyObject *py_globals = 0;
6415 PyCodeObject *py_code = 0;
6416 PyFrameObject *py_frame = 0;
6418 #if PY_MAJOR_VERSION < 3
6419 py_srcfile = PyString_FromString(%(FILENAME)s);
6421 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6423 if (!py_srcfile) goto bad;
6425 #if PY_MAJOR_VERSION < 3
6426 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6428 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6432 #if PY_MAJOR_VERSION < 3
6433 py_funcname = PyString_FromString(funcname);
6435 py_funcname = PyUnicode_FromString(funcname);
6438 if (!py_funcname) goto bad;
6439 py_globals = PyModule_GetDict(%(GLOBALS)s);
6440 if (!py_globals) goto bad;
6441 py_code = PyCode_New(
6442 0, /*int argcount,*/
6443 #if PY_MAJOR_VERSION >= 3
6444 0, /*int kwonlyargcount,*/
6447 0, /*int stacksize,*/
6449 %(EMPTY_BYTES)s, /*PyObject *code,*/
6450 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6451 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6452 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6453 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6454 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6455 py_srcfile, /*PyObject *filename,*/
6456 py_funcname, /*PyObject *name,*/
6457 %(LINENO)s, /*int firstlineno,*/
6458 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6460 if (!py_code) goto bad;
6461 py_frame = PyFrame_New(
6462 PyThreadState_GET(), /*PyThreadState *tstate,*/
6463 py_code, /*PyCodeObject *code,*/
6464 py_globals, /*PyObject *globals,*/
6465 0 /*PyObject *locals*/
6467 if (!py_frame) goto bad;
6468 py_frame->f_lineno = %(LINENO)s;
6469 PyTraceBack_Here(py_frame);
6471 Py_XDECREF(py_srcfile);
6472 Py_XDECREF(py_funcname);
6473 Py_XDECREF(py_code);
6474 Py_XDECREF(py_frame);
6477 'FILENAME': Naming.filename_cname,
6478 'LINENO': Naming.lineno_cname,
6479 'CFILENAME': Naming.cfilenm_cname,
6480 'CLINENO': Naming.clineno_cname,
6481 'GLOBALS': Naming.module_cname,
6482 'EMPTY_TUPLE' : Naming.empty_tuple,
6483 'EMPTY_BYTES' : Naming.empty_bytes,
6486 #------------------------------------------------------------------------------------
6488 unraisable_exception_utility_code = UtilityCode(
6490 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6493 static void __Pyx_WriteUnraisable(const char *name) {
6494 PyObject *old_exc, *old_val, *old_tb;
6496 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6497 #if PY_MAJOR_VERSION < 3
6498 ctx = PyString_FromString(name);
6500 ctx = PyUnicode_FromString(name);
6502 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6504 PyErr_WriteUnraisable(Py_None);
6506 PyErr_WriteUnraisable(ctx);
6511 requires=[restore_exception_utility_code])
6513 #------------------------------------------------------------------------------------
6515 set_vtable_utility_code = UtilityCode(
6517 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6520 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6521 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6522 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6524 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6528 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6538 #------------------------------------------------------------------------------------
6540 get_vtable_utility_code = UtilityCode(
6542 static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
6545 static void* __Pyx_GetVtable(PyObject *dict) {
6547 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6550 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6551 ptr = PyCapsule_GetPointer(ob, 0);
6553 ptr = PyCObject_AsVoidPtr(ob);
6555 if (!ptr && !PyErr_Occurred())
6556 PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
6565 #------------------------------------------------------------------------------------
6567 init_string_tab_utility_code = UtilityCode(
6569 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6572 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6574 #if PY_MAJOR_VERSION < 3
6575 if (t->is_unicode) {
6576 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6577 } else if (t->intern) {
6578 *t->p = PyString_InternFromString(t->s);
6580 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6582 #else /* Python 3+ has unicode identifiers */
6583 if (t->is_unicode | t->is_str) {
6585 *t->p = PyUnicode_InternFromString(t->s);
6586 } else if (t->encoding) {
6587 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6589 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6592 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6603 #------------------------------------------------------------------------------------
6605 force_init_threads_utility_code = UtilityCode(
6607 #ifndef __PYX_FORCE_INIT_THREADS
6608 #if PY_VERSION_HEX < 0x02040200
6609 #define __PYX_FORCE_INIT_THREADS 1
6611 #define __PYX_FORCE_INIT_THREADS 0
6616 #------------------------------------------------------------------------------------
6618 # Note that cPython ignores PyTrace_EXCEPTION,
6619 # but maybe some other profilers don't.
6621 profile_utility_code = UtilityCode(proto="""
6622 #ifndef CYTHON_PROFILE
6623 #define CYTHON_PROFILE 1
6626 #ifndef CYTHON_PROFILE_REUSE_FRAME
6627 #define CYTHON_PROFILE_REUSE_FRAME 0
6632 #include "compile.h"
6633 #include "frameobject.h"
6634 #include "traceback.h"
6636 #if CYTHON_PROFILE_REUSE_FRAME
6637 #define CYTHON_FRAME_MODIFIER static
6638 #define CYTHON_FRAME_DEL
6640 #define CYTHON_FRAME_MODIFIER
6641 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6644 #define __Pyx_TraceDeclarations \\
6645 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6646 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6647 int __Pyx_use_tracing = 0;
6649 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6650 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6651 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6654 #define __Pyx_TraceException() \\
6655 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6656 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6658 PyThreadState_GET()->c_profilefunc( \\
6659 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6660 Py_DECREF(exc_info); \\
6664 #define __Pyx_TraceReturn(result) \\
6665 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6666 PyThreadState_GET()->c_profilefunc( \\
6667 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6668 CYTHON_FRAME_DEL; \\
6671 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6672 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6676 #define __Pyx_TraceDeclarations
6677 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6678 #define __Pyx_TraceException()
6679 #define __Pyx_TraceReturn(result)
6681 #endif /* CYTHON_PROFILE */
6684 "FRAME": Naming.frame_cname,
6685 "FRAME_CODE": Naming.frame_code_cname,
6691 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6692 PyFrameObject** frame,
6693 const char *funcname,
6694 const char *srcfile,
6696 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6697 if (*code == NULL) {
6698 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6699 if (*code == NULL) return 0;
6701 *frame = PyFrame_New(
6702 PyThreadState_GET(), /*PyThreadState *tstate*/
6703 *code, /*PyCodeObject *code*/
6704 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6705 0 /*PyObject *locals*/
6707 if (*frame == NULL) return 0;
6710 (*frame)->f_tstate = PyThreadState_GET();
6712 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6715 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6716 PyObject *py_srcfile = 0;
6717 PyObject *py_funcname = 0;
6718 PyCodeObject *py_code = 0;
6720 #if PY_MAJOR_VERSION < 3
6721 py_funcname = PyString_FromString(funcname);
6722 py_srcfile = PyString_FromString(srcfile);
6724 py_funcname = PyUnicode_FromString(funcname);
6725 py_srcfile = PyUnicode_FromString(srcfile);
6727 if (!py_funcname | !py_srcfile) goto bad;
6729 py_code = PyCode_New(
6730 0, /*int argcount,*/
6731 #if PY_MAJOR_VERSION >= 3
6732 0, /*int kwonlyargcount,*/
6735 0, /*int stacksize,*/
6737 %(EMPTY_BYTES)s, /*PyObject *code,*/
6738 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6739 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6740 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6741 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6742 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6743 py_srcfile, /*PyObject *filename,*/
6744 py_funcname, /*PyObject *name,*/
6745 firstlineno, /*int firstlineno,*/
6746 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6750 Py_XDECREF(py_srcfile);
6751 Py_XDECREF(py_funcname);
6756 #endif /* CYTHON_PROFILE */
6758 'EMPTY_TUPLE' : Naming.empty_tuple,
6759 'EMPTY_BYTES' : Naming.empty_bytes,
6760 "MODULE": Naming.module_cname,