2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
17 from StringEncoding import EncodedString, escape_byte_string, split_docstring
22 absolute_path_length = 0
24 def relative_position(pos):
26 We embed the relative filename in the generated C file, since we
27 don't want to have to regnerate and compile all the source code
28 whenever the Python install directory moves (which could happen,
29 e.g,. when distributing binaries.)
32 a position tuple -- (absolute filename, line number column position)
40 global absolute_path_length
41 if absolute_path_length==0:
42 absolute_path_length = len(os.path.abspath(os.getcwd()))
43 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
45 def embed_position(pos, docstring):
46 if not Options.embed_pos_in_docstring:
48 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
51 return EncodedString(pos_line)
53 # make sure we can encode the filename in the docstring encoding
54 # otherwise make the docstring a unicode string
55 encoding = docstring.encoding
56 if encoding is not None:
58 encoded_bytes = pos_line.encode(encoding)
59 except UnicodeEncodeError:
63 # reuse the string encoding of the original docstring
64 doc = EncodedString(pos_line)
66 doc = EncodedString(pos_line + u'\n' + docstring)
67 doc.encoding = encoding
71 from Code import CCodeWriter
72 from types import FunctionType
74 def write_func_call(func):
76 if len(args) > 1 and isinstance(args[1], CCodeWriter):
77 # here we annotate the code with this function call
78 # but only if new code is generated
80 marker = ' /* %s -> %s.%s %s */' % (
81 ' ' * code.call_level,
82 node.__class__.__name__,
85 pristine = code.buffer.stream.tell()
87 start = code.buffer.stream.tell()
89 res = func(*args, **kwds)
91 if start == code.buffer.stream.tell():
92 code.buffer.stream.seek(pristine)
94 marker = marker.replace('->', '<-')
98 return func(*args, **kwds)
101 class VerboseCodeWriter(type):
102 # Set this as a metaclass to trace function calls in code.
103 # This slows down code generation and makes much larger files.
104 def __new__(cls, name, bases, attrs):
106 for mname, m in attrs.items():
107 if isinstance(m, FunctionType):
108 attrs[mname] = write_func_call(m)
109 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
113 # pos (string, int, int) Source file position
114 # is_name boolean Is a NameNode
115 # is_literal boolean Is a ConstNode
117 if DebugFlags.debug_trace_code_generation:
118 __metaclass__ = VerboseCodeWriter
124 # All descandants should set child_attrs to a list of the attributes
125 # containing nodes considered "children" in the tree. Each such attribute
126 # can either contain a single node or a list of nodes. See Visitor.py.
129 def __init__(self, pos, **kw):
131 self.__dict__.update(kw)
133 gil_message = "Operation"
135 def gil_check(self, env):
140 error(self.pos, "%s not allowed without gil" % self.gil_message)
142 def clone_node(self):
143 """Clone the node. This is defined as a shallow copy, except for member lists
144 amongst the child attributes (from get_child_accessors) which are also
145 copied. Lists containing child nodes are thus seen as a way for the node
146 to hold multiple children directly; the list is not treated as a seperate
147 level in the tree."""
148 result = copy.copy(self)
149 for attrname in result.child_attrs:
150 value = getattr(result, attrname)
151 if isinstance(value, list):
152 setattr(result, attrname, [x for x in value])
157 # There are 4 phases of parse tree processing, applied in order to
158 # all the statements in a given scope-block:
160 # (0) analyse_control_flow
161 # Create the control flow tree into which state can be asserted and
164 # (1) analyse_declarations
165 # Make symbol table entries for all declarations at the current
166 # level, both explicit (def, cdef, etc.) and implicit (assignment
167 # to an otherwise undeclared name).
169 # (2) analyse_expressions
170 # Determine the result types of expressions and fill in the
171 # 'type' attribute of each ExprNode. Insert coercion nodes into the
172 # tree where needed to convert to and from Python objects.
173 # Allocate temporary locals for intermediate results. Fill
174 # in the 'result_code' attribute of each ExprNode with a C code
178 # Emit C code for all declarations, statements and expressions.
179 # Recursively applies the 3 processing phases to the bodies of
183 def analyse_control_flow(self, env):
186 def analyse_declarations(self, env):
189 def analyse_expressions(self, env):
190 raise InternalError("analyse_expressions not implemented for %s" % \
191 self.__class__.__name__)
193 def generate_code(self, code):
194 raise InternalError("generate_code not implemented for %s" % \
195 self.__class__.__name__)
197 def annotate(self, code):
198 # mro does the wrong thing
199 if isinstance(self, BlockNode):
200 self.body.annotate(code)
205 except AttributeError:
207 if not self.child_attrs:
210 for attr in self.child_attrs:
211 child = getattr(self, attr)
212 # Sometimes lists, sometimes nodes
215 elif isinstance(child, list):
217 pos = max(pos, c.end_pos())
219 pos = max(pos, child.end_pos())
223 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
225 return "<...nesting level cutoff...>"
226 if encountered is None:
228 if id(self) in encountered:
229 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
230 encountered.add(id(self))
232 def dump_child(x, level):
233 if isinstance(x, Node):
234 return x.dump(level, filter_out, cutoff-1, encountered)
235 elif isinstance(x, list):
236 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
241 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
243 return "<%s (%d)>" % (self.__class__.__name__, id(self))
246 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
247 for key, value in attrs:
248 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
249 res += "%s>" % indent
252 class CompilerDirectivesNode(Node):
254 Sets compiler directives for the children nodes
256 # directives {string:value} A dictionary holding the right value for
257 # *all* possible directives.
259 child_attrs = ["body"]
261 def analyse_control_flow(self, env):
263 env.directives = self.directives
264 self.body.analyse_control_flow(env)
267 def analyse_declarations(self, env):
269 env.directives = self.directives
270 self.body.analyse_declarations(env)
273 def analyse_expressions(self, env):
275 env.directives = self.directives
276 self.body.analyse_expressions(env)
279 def generate_function_definitions(self, env, code):
280 env_old = env.directives
281 code_old = code.globalstate.directives
282 code.globalstate.directives = self.directives
283 self.body.generate_function_definitions(env, code)
284 env.directives = env_old
285 code.globalstate.directives = code_old
287 def generate_execution_code(self, code):
288 old = code.globalstate.directives
289 code.globalstate.directives = self.directives
290 self.body.generate_execution_code(code)
291 code.globalstate.directives = old
293 def annotate(self, code):
294 old = code.globalstate.directives
295 code.globalstate.directives = self.directives
296 self.body.annotate(code)
297 code.globalstate.directives = old
299 class BlockNode(object):
300 # Mixin class for nodes representing a declaration block.
302 def generate_const_definitions(self, env, code):
303 if env.const_entries:
304 for entry in env.const_entries:
305 if not entry.is_interned:
306 code.globalstate.add_const_definition(entry)
308 def generate_interned_string_decls(self, env, code):
309 entries = env.global_scope().new_interned_string_entries
311 for entry in entries:
312 code.globalstate.add_interned_string_decl(entry)
315 def generate_py_string_decls(self, env, code):
317 return # earlier error
318 entries = env.pystring_entries
320 for entry in entries:
321 if not entry.is_interned:
322 code.globalstate.add_py_string_decl(entry)
324 def generate_interned_num_decls(self, env, code):
325 # Flush accumulated interned nums from the global scope
326 # and generate declarations for them.
327 genv = env.global_scope()
328 entries = genv.interned_nums
330 for entry in entries:
331 code.globalstate.add_interned_num_decl(entry)
334 def generate_cached_builtins_decls(self, env, code):
335 entries = env.global_scope().undeclared_cached_builtins
336 for entry in entries:
337 code.globalstate.add_cached_builtin_decl(entry)
341 class StatListNode(Node):
342 # stats a list of StatNode
344 child_attrs = ["stats"]
346 def create_analysed(pos, env, *args, **kw):
347 node = StatListNode(pos, *args, **kw)
348 return node # No node-specific analysis necesarry
349 create_analysed = staticmethod(create_analysed)
351 def analyse_control_flow(self, env):
352 for stat in self.stats:
353 stat.analyse_control_flow(env)
355 def analyse_declarations(self, env):
356 #print "StatListNode.analyse_declarations" ###
357 for stat in self.stats:
358 stat.analyse_declarations(env)
360 def analyse_expressions(self, env):
361 #print "StatListNode.analyse_expressions" ###
362 for stat in self.stats:
363 stat.analyse_expressions(env)
365 def generate_function_definitions(self, env, code):
366 #print "StatListNode.generate_function_definitions" ###
367 for stat in self.stats:
368 stat.generate_function_definitions(env, code)
370 def generate_execution_code(self, code):
371 #print "StatListNode.generate_execution_code" ###
372 for stat in self.stats:
373 code.mark_pos(stat.pos)
374 stat.generate_execution_code(code)
376 def annotate(self, code):
377 for stat in self.stats:
381 class StatNode(Node):
383 # Code generation for statements is split into the following subphases:
385 # (1) generate_function_definitions
386 # Emit C code for the definitions of any structs,
387 # unions, enums and functions defined in the current
390 # (2) generate_execution_code
391 # Emit C code for executable statements.
394 def generate_function_definitions(self, env, code):
397 def generate_execution_code(self, code):
398 raise InternalError("generate_execution_code not implemented for %s" % \
399 self.__class__.__name__)
402 class CDefExternNode(StatNode):
403 # include_file string or None
406 child_attrs = ["body"]
408 def analyse_declarations(self, env):
409 if self.include_file:
410 env.add_include_file(self.include_file)
411 old_cinclude_flag = env.in_cinclude
413 self.body.analyse_declarations(env)
414 env.in_cinclude = old_cinclude_flag
416 def analyse_expressions(self, env):
419 def generate_execution_code(self, code):
422 def annotate(self, code):
423 self.body.annotate(code)
426 class CDeclaratorNode(Node):
427 # Part of a C declaration.
429 # Processing during analyse_declarations phase:
432 # Returns (name, type) pair where name is the
433 # CNameDeclaratorNode of the name being declared
434 # and type is the type it is being declared as.
436 # calling_convention string Calling convention of CFuncDeclaratorNode
437 # for which this is a base
441 calling_convention = ""
444 class CNameDeclaratorNode(CDeclaratorNode):
445 # name string The Pyrex name being declared
446 # cname string or None C name, if specified
447 # default ExprNode or None the value assigned on declaration
449 child_attrs = ['default']
453 def analyse(self, base_type, env, nonempty = 0):
454 if nonempty and self.name == '':
455 # May have mistaken the name for the type.
456 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
457 error(self.pos, "Missing argument name")
458 elif base_type.is_void:
459 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
461 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
462 base_type = py_object_type
463 self.type = base_type
464 return self, base_type
466 class CPtrDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
469 child_attrs = ["base"]
471 def analyse(self, base_type, env, nonempty = 0):
472 if base_type.is_pyobject:
474 "Pointer base type cannot be a Python object")
475 ptr_type = PyrexTypes.c_ptr_type(base_type)
476 return self.base.analyse(ptr_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):
486 self.dimension.analyse_const_expression(env)
487 if not self.dimension.type.is_int:
488 error(self.dimension.pos, "Array dimension not integer")
489 size = self.dimension.result()
497 if not base_type.is_complete():
499 "Array element type '%s' is incomplete" % base_type)
500 if base_type.is_pyobject:
502 "Array element cannot be a Python object")
503 if base_type.is_cfunction:
505 "Array element cannot be a function")
506 array_type = PyrexTypes.c_array_type(base_type, size)
507 return self.base.analyse(array_type, env, nonempty = nonempty)
510 class CFuncDeclaratorNode(CDeclaratorNode):
511 # base CDeclaratorNode
512 # args [CArgDeclNode]
513 # has_varargs boolean
514 # exception_value ConstNode
515 # exception_check boolean True if PyErr_Occurred check needed
516 # nogil boolean Can be called without gil
517 # with_gil boolean Acquire gil around function body
519 child_attrs = ["base", "args", "exception_value"]
522 optional_arg_count = 0
524 def analyse(self, return_type, env, nonempty = 0):
528 for arg_node in self.args:
529 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
530 name = name_declarator.name
531 if name_declarator.cname:
533 "Function argument cannot have C name specification")
534 # Turn *[] argument into **
536 type = PyrexTypes.c_ptr_type(type.base_type)
537 # Catch attempted C-style func(void) decl
539 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
540 # if type.is_pyobject and self.nogil:
542 # "Function with Python argument cannot be declared nogil")
543 func_type_args.append(
544 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
546 self.optional_arg_count += 1
547 elif self.optional_arg_count:
548 error(self.pos, "Non-default argument follows default argument")
550 if self.optional_arg_count:
551 scope = StructOrUnionScope()
552 arg_count_member = '%sn' % Naming.pyrex_prefix
553 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
554 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
555 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
556 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
557 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
562 cname = struct_cname)
563 self.op_args_struct.defined_in_pxd = 1
564 self.op_args_struct.used = 1
568 if self.exception_check == '+':
569 env.add_include_file('stdexcept')
570 if return_type.is_pyobject \
571 and (self.exception_value or self.exception_check) \
572 and self.exception_check != '+':
574 "Exception clause not allowed for function returning Python object")
576 if self.exception_value:
577 self.exception_value.analyse_const_expression(env)
578 if self.exception_check == '+':
579 exc_val_type = self.exception_value.type
580 if not exc_val_type.is_error and \
581 not exc_val_type.is_pyobject and \
582 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
583 error(self.exception_value.pos,
584 "Exception value must be a Python exception or cdef function with no arguments.")
585 exc_val = self.exception_value
587 exc_val = self.exception_value.result()
588 if not return_type.assignable_from(self.exception_value.type):
589 error(self.exception_value.pos,
590 "Exception value incompatible with function return type")
591 exc_check = self.exception_check
592 if return_type.is_array:
594 "Function cannot return an array")
595 if return_type.is_cfunction:
597 "Function cannot return a function")
598 func_type = PyrexTypes.CFuncType(
599 return_type, func_type_args, self.has_varargs,
600 optional_arg_count = self.optional_arg_count,
601 exception_value = exc_val, exception_check = exc_check,
602 calling_convention = self.base.calling_convention,
603 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
604 if self.optional_arg_count:
605 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
606 callspec = env.directives['callspec']
608 current = func_type.calling_convention
609 if current and current != callspec:
610 error(self.pos, "cannot have both '%s' and '%s' "
611 "calling conventions" % (current, callspec))
612 func_type.calling_convention = callspec
613 return self.base.analyse(func_type, env)
616 class CArgDeclNode(Node):
617 # Item in a function declaration argument list.
619 # base_type CBaseTypeNode
620 # declarator CDeclaratorNode
621 # not_none boolean Tagged with 'not None'
622 # default ExprNode or None
623 # default_entry Symtab.Entry Entry for the variable holding the default value
624 # default_result_code string cname or code fragment for default value
625 # is_self_arg boolean Is the "self" arg of an extension type method
626 # is_kw_only boolean Is a keyword-only argument
628 child_attrs = ["base_type", "declarator", "default"]
633 name_declarator = None
635 def analyse(self, env, nonempty = 0):
636 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
637 if self.type is None:
638 # The parser may missinterpret names as types...
640 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
642 self.declarator.name = self.base_type.name
643 self.base_type.name = None
644 self.base_type.is_basic_c_type = False
647 could_be_name = False
648 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
649 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
650 self.declarator.name = self.base_type.arg_name
651 return self.declarator.analyse(base_type, env, nonempty = nonempty)
653 return self.name_declarator, self.type
655 def annotate(self, code):
657 self.default.annotate(code)
660 class CBaseTypeNode(Node):
661 # Abstract base class for C base type nodes.
663 # Processing during analyse_declarations phase:
670 class CAnalysedBaseTypeNode(Node):
675 def analyse(self, env, could_be_name = False):
678 class CSimpleBaseTypeNode(CBaseTypeNode):
680 # module_path [string] Qualifying name components
681 # is_basic_c_type boolean
685 # is_self_arg boolean Is self argument of C method
688 arg_name = None # in case the argument name was interpreted as a type
690 def analyse(self, env, could_be_name = False):
691 # Return type descriptor.
692 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
694 if self.is_basic_c_type:
695 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
697 error(self.pos, "Unrecognised type modifier combination")
698 elif self.name == "object" and not self.module_path:
699 type = py_object_type
700 elif self.name is None:
701 if self.is_self_arg and env.is_c_class_scope:
702 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
703 type = env.parent_type
705 type = py_object_type
708 scope = env.find_imported_module(self.module_path, self.pos)
712 if scope.is_c_class_scope:
713 scope = scope.global_scope()
714 entry = scope.lookup(self.name)
715 if entry and entry.is_type:
718 if self.is_self_arg and env.is_c_class_scope:
719 type = env.parent_type
721 type = py_object_type
722 self.arg_name = self.name
724 error(self.pos, "'%s' is not a type identifier" % self.name)
726 if not type.is_numeric or type.is_complex:
727 error(self.pos, "can only complexify c numeric types")
728 type = PyrexTypes.CComplexType(type)
729 type.create_declaration_utility_code(env)
733 return PyrexTypes.error_type
735 class CBufferAccessTypeNode(CBaseTypeNode):
737 # positional_args [ExprNode] List of positional arguments
738 # keyword_args DictNode Keyword arguments
739 # base_type_node CBaseTypeNode
742 # type PyrexType.BufferType ...containing the right options
745 child_attrs = ["base_type_node", "positional_args",
746 "keyword_args", "dtype_node"]
752 def analyse(self, env, could_be_name = False):
753 base_type = self.base_type_node.analyse(env)
754 if base_type.is_error: return base_type
757 options = Buffer.analyse_buffer_options(
760 self.positional_args,
762 base_type.buffer_defaults)
764 self.type = PyrexTypes.BufferType(base_type, **options)
767 class CComplexBaseTypeNode(CBaseTypeNode):
768 # base_type CBaseTypeNode
769 # declarator CDeclaratorNode
771 child_attrs = ["base_type", "declarator"]
773 def analyse(self, env, could_be_name = False):
774 base = self.base_type.analyse(env, could_be_name)
775 _, type = self.declarator.analyse(base, env)
779 class CVarDefNode(StatNode):
780 # C variable definition or forward/extern function declaration.
782 # visibility 'private' or 'public' or 'extern'
783 # base_type CBaseTypeNode
784 # declarators [CDeclaratorNode]
787 # need_properties [entry]
789 # decorators [cython.locals(...)] or None
790 # directive_locals { string : NameNode } locals defined by cython.locals(...)
792 child_attrs = ["base_type", "declarators"]
796 directive_locals = {}
798 def analyse_declarations(self, env, dest_scope = None):
801 self.dest_scope = dest_scope
802 base_type = self.base_type.analyse(env)
804 # If the field is an external typedef, we cannot be sure about the type,
805 # so do conversion ourself rather than rely on the CPython mechanism (through
806 # a property; made in AnalyseDeclarationsTransform).
807 if (dest_scope.is_c_class_scope
808 and self.visibility == 'public'
809 and base_type.is_pyobject
810 and (base_type.is_builtin_type or base_type.is_extension_type)):
811 self.need_properties = []
813 visibility = 'private'
815 need_property = False
816 visibility = self.visibility
818 for declarator in self.declarators:
819 name_declarator, type = declarator.analyse(base_type, env)
820 if not type.is_complete():
821 if not (self.visibility == 'extern' and type.is_array):
822 error(declarator.pos,
823 "Variable type '%s' is incomplete" % type)
824 if self.visibility == 'extern' and type.is_pyobject:
825 error(declarator.pos,
826 "Python object cannot be declared extern")
827 name = name_declarator.name
828 cname = name_declarator.cname
830 error(declarator.pos, "Missing name in declaration.")
832 if type.is_cfunction:
833 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
834 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
836 if entry is not None:
837 entry.directive_locals = self.directive_locals
839 if self.directive_locals:
840 s.error("Decorators can only be followed by functions")
841 if self.in_pxd and self.visibility != 'extern':
843 "Only 'extern' C variable declaration allowed in .pxd file")
844 entry = dest_scope.declare_var(name, type, declarator.pos,
845 cname = cname, visibility = visibility, is_cdef = 1)
847 self.need_properties.append(entry)
848 entry.needs_property = 1
851 class CStructOrUnionDefNode(StatNode):
853 # cname string or None
854 # kind "struct" or "union"
855 # typedef_flag boolean
856 # visibility "public" or "private"
858 # attributes [CVarDefNode] or None
862 child_attrs = ["attributes"]
864 def analyse_declarations(self, env):
866 if self.visibility == 'extern' and self.packed:
867 error(self.pos, "Cannot declare extern struct as 'packed'")
868 if self.attributes is not None:
869 scope = StructOrUnionScope(self.name)
870 self.entry = env.declare_struct_or_union(
871 self.name, self.kind, scope, self.typedef_flag, self.pos,
872 self.cname, visibility = self.visibility, packed = self.packed)
873 if self.attributes is not None:
874 if self.in_pxd and not env.in_cinclude:
875 self.entry.defined_in_pxd = 1
876 for attr in self.attributes:
877 attr.analyse_declarations(env, scope)
878 if self.visibility != 'extern':
879 need_typedef_indirection = False
880 for attr in scope.var_entries:
883 type = type.base_type
884 if type == self.entry.type:
885 error(attr.pos, "Struct cannot contain itself as a member.")
886 if self.typedef_flag:
888 type = type.base_type
889 if type == self.entry.type:
890 need_typedef_indirection = True
891 if need_typedef_indirection:
892 # C can't handle typedef structs that refer to themselves.
893 struct_entry = self.entry
894 cname = env.new_const_cname()
895 self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore')
896 struct_entry.type.typedef_flag = False
897 struct_entry.cname = struct_entry.type.cname = env.new_const_cname()
899 def analyse_expressions(self, env):
902 def generate_execution_code(self, code):
906 class CEnumDefNode(StatNode):
907 # name string or None
908 # cname string or None
909 # items [CEnumDefItemNode]
910 # typedef_flag boolean
911 # visibility "public" or "private"
915 child_attrs = ["items"]
917 def analyse_declarations(self, env):
918 self.entry = env.declare_enum(self.name, self.pos,
919 cname = self.cname, typedef_flag = self.typedef_flag,
920 visibility = self.visibility)
921 if self.items is not None:
922 if self.in_pxd and not env.in_cinclude:
923 self.entry.defined_in_pxd = 1
924 for item in self.items:
925 item.analyse_declarations(env, self.entry)
927 def analyse_expressions(self, env):
928 if self.visibility == 'public':
929 self.temp = env.allocate_temp_pyobject()
930 env.release_temp(self.temp)
932 def generate_execution_code(self, code):
933 if self.visibility == 'public':
934 for item in self.entry.enum_values:
935 code.putln("%s = PyInt_FromLong(%s); %s" % (
938 code.error_goto_if_null(self.temp, item.pos)))
939 code.put_gotref(self.temp)
940 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
944 code.error_goto(item.pos)))
945 code.put_decref_clear(self.temp, PyrexTypes.py_object_type)
948 class CEnumDefItemNode(StatNode):
950 # cname string or None
951 # value ExprNode or None
953 child_attrs = ["value"]
955 def analyse_declarations(self, env, enum_entry):
957 self.value.analyse_const_expression(env)
958 if not self.value.type.is_int:
959 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
960 self.value.analyse_const_expression(env)
961 value = self.value.result()
964 entry = env.declare_const(self.name, enum_entry.type,
965 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
966 enum_entry.enum_values.append(entry)
969 class CTypeDefNode(StatNode):
970 # base_type CBaseTypeNode
971 # declarator CDeclaratorNode
972 # visibility "public" or "private"
975 child_attrs = ["base_type", "declarator"]
977 def analyse_declarations(self, env):
978 base = self.base_type.analyse(env)
979 name_declarator, type = self.declarator.analyse(base, env)
980 name = name_declarator.name
981 cname = name_declarator.cname
982 entry = env.declare_typedef(name, type, self.pos,
983 cname = cname, visibility = self.visibility)
984 if self.in_pxd and not env.in_cinclude:
985 entry.defined_in_pxd = 1
987 def analyse_expressions(self, env):
989 def generate_execution_code(self, code):
993 class FuncDefNode(StatNode, BlockNode):
994 # Base class for function definition nodes.
996 # return_type PyrexType
997 # #filename string C name of filename string const
999 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1000 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1004 needs_closure = False
1006 def analyse_default_values(self, env):
1007 genv = env.global_scope()
1008 for arg in self.args:
1011 if not hasattr(arg, 'default_entry'):
1012 arg.default.analyse_types(env)
1013 arg.default = arg.default.coerce_to(arg.type, genv)
1014 if arg.default.is_literal:
1015 arg.default_entry = arg.default
1016 arg.default_result_code = arg.default.calculate_result_code()
1017 if arg.default.type != arg.type and not arg.type.is_int:
1018 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
1020 arg.default.allocate_temps(genv)
1021 arg.default_entry = genv.add_default_value(arg.type)
1022 if arg.type.is_pyobject:
1023 arg.default_entry.init = 0
1024 arg.default_entry.used = 1
1025 arg.default_result_code = arg.default_entry.cname
1028 "This argument cannot have a default value")
1031 def need_gil_acquisition(self, lenv):
1034 def create_local_scope(self, env):
1036 while env.is_py_class_scope or env.is_c_class_scope:
1037 env = env.outer_scope
1038 if self.needs_closure:
1039 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1041 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1042 lenv.return_type = self.return_type
1043 type = self.entry.type
1044 if type.is_cfunction:
1045 lenv.nogil = type.nogil and not type.with_gil
1046 self.local_scope = lenv
1047 lenv.directives = env.directives
1050 def generate_function_definitions(self, env, code):
1053 lenv = self.local_scope
1055 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1056 self.entry.scope.is_c_class_scope)
1058 # Generate C code for header and body of function
1059 code.enter_cfunc_scope()
1060 code.return_from_error_cleanup_label = code.new_label()
1062 # ----- Top-level constants used by this function
1063 code.mark_pos(self.pos)
1064 self.generate_interned_num_decls(lenv, code)
1065 self.generate_interned_string_decls(lenv, code)
1066 self.generate_py_string_decls(lenv, code)
1067 self.generate_cached_builtins_decls(lenv, code)
1069 #code.put_var_declarations(lenv.const_entries, static = 1)
1070 self.generate_const_definitions(lenv, code)
1071 # ----- Function header
1074 self.py_func.generate_function_header(code,
1075 with_pymethdef = env.is_py_class_scope,
1077 self.generate_function_header(code,
1078 with_pymethdef = env.is_py_class_scope)
1079 # ----- Local variable declarations
1080 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1081 self.generate_argument_declarations(lenv, code)
1082 if self.needs_closure:
1083 code.putln("/* TODO: declare and create scope object */")
1084 code.put_var_declarations(lenv.var_entries)
1086 if not self.return_type.is_void:
1087 if self.return_type.is_pyobject:
1091 (self.return_type.declaration_code(
1092 Naming.retval_cname),
1094 tempvardecl_code = code.insertion_point()
1095 self.generate_keyword_list(code)
1096 # ----- Extern library function declarations
1097 lenv.generate_library_function_declarations(code)
1098 # ----- GIL acquisition
1099 acquire_gil = self.need_gil_acquisition(lenv)
1101 env.use_utility_code(force_init_threads_utility_code)
1102 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1103 # ----- Automatic lead-ins for certain special functions
1105 code.put_setup_refcount_context(self.entry.name)
1106 if is_getbuffer_slot:
1107 self.getbuffer_init(code)
1108 # ----- Fetch arguments
1109 self.generate_argument_parsing_code(env, code)
1110 # If an argument is assigned to in the body, we must
1111 # incref it to properly keep track of refcounts.
1112 for entry in lenv.arg_entries:
1113 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1114 code.put_var_incref(entry)
1115 # ----- Initialise local variables
1116 for entry in lenv.var_entries:
1117 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1118 code.put_init_var_to_py_none(entry)
1119 # ----- Initialise local buffer auxiliary variables
1120 for entry in lenv.var_entries + lenv.arg_entries:
1121 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1122 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1123 # ----- Check and convert arguments
1124 self.generate_argument_type_tests(code)
1125 # ----- Acquire buffer arguments
1126 for entry in lenv.arg_entries:
1127 if entry.type.is_buffer:
1128 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1129 # ----- Function body
1130 self.body.generate_execution_code(code)
1131 # ----- Default return value
1133 if self.return_type.is_pyobject:
1134 #if self.return_type.is_extension_type:
1135 # lhs = "(PyObject *)%s" % Naming.retval_cname
1137 lhs = Naming.retval_cname
1138 code.put_init_to_py_none(lhs, self.return_type)
1140 val = self.return_type.default_value
1142 code.putln("%s = %s;" % (Naming.retval_cname, val))
1143 # ----- Error cleanup
1144 if code.error_label in code.labels_used:
1145 code.put_goto(code.return_label)
1146 code.put_label(code.error_label)
1147 # cleanup temps the old way
1148 code.put_var_xdecrefs(lenv.temp_entries)
1149 # cleanup temps the new way
1150 for cname, type in code.funcstate.all_managed_temps():
1151 code.put_xdecref(cname, type)
1153 # Clean up buffers -- this calls a Python function
1154 # so need to save and restore error state
1155 buffers_present = len(lenv.buffer_entries) > 0
1157 code.globalstate.use_utility_code(restore_exception_utility_code)
1158 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1159 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1160 for entry in lenv.buffer_entries:
1161 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1162 #code.putln("%s = 0;" % entry.cname)
1163 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1165 err_val = self.error_value()
1166 exc_check = self.caller_will_check_exceptions()
1167 if err_val is not None or exc_check:
1168 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1170 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1171 % self.entry.qualified_name, 0)
1173 '__Pyx_WriteUnraisable("%s");' %
1174 self.entry.qualified_name)
1175 env.use_utility_code(unraisable_exception_utility_code)
1176 env.use_utility_code(restore_exception_utility_code)
1177 default_retval = self.return_type.default_value
1178 if err_val is None and default_retval:
1179 err_val = default_retval
1180 if err_val is not None:
1183 Naming.retval_cname,
1186 if is_getbuffer_slot:
1187 self.getbuffer_error_cleanup(code)
1189 # If we are using the non-error cleanup section we should
1190 # jump past it if we have an error. The if-test below determine
1191 # whether this section is used.
1192 if buffers_present or is_getbuffer_slot:
1193 code.put_goto(code.return_from_error_cleanup_label)
1196 # ----- Non-error return cleanup
1197 # If you add anything here, remember to add a condition to the
1198 # if-test above in the error block (so that it can jump past this
1200 code.put_label(code.return_label)
1201 for entry in lenv.buffer_entries:
1203 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1204 if is_getbuffer_slot:
1205 self.getbuffer_normal_cleanup(code)
1206 # ----- Return cleanup for both error and no-error return
1207 code.put_label(code.return_from_error_cleanup_label)
1208 if not Options.init_local_none:
1209 for entry in lenv.var_entries:
1210 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1211 entry.xdecref_cleanup = 1
1212 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1213 # Decref any increfed args
1214 for entry in lenv.arg_entries:
1215 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1216 code.put_var_decref(entry)
1218 # code.putln("/* TODO: decref scope object */")
1220 # This code is duplicated in ModuleNode.generate_module_init_func
1222 default_retval = self.return_type.default_value
1223 err_val = self.error_value()
1224 if err_val is None and default_retval:
1225 err_val = default_retval
1226 if self.return_type.is_pyobject:
1227 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1229 code.put_finish_refcount_context()
1231 if self.entry.is_special and self.entry.name == "__hash__":
1232 # Returning -1 for __hash__ is supposed to signal an error
1233 # We do as Python instances and coerce -1 into -2.
1234 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
1237 code.putln("PyGILState_Release(_save);")
1239 if not self.return_type.is_void:
1240 code.putln("return %s;" % Naming.retval_cname)
1243 # ----- Go back and insert temp variable declarations
1244 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1245 tempvardecl_code.put_temp_declarations(code.funcstate)
1246 # ----- Python version
1247 code.exit_cfunc_scope()
1249 self.py_func.generate_function_definitions(env, code)
1250 self.generate_wrapper_functions(code)
1252 def declare_argument(self, env, arg):
1253 if arg.type.is_void:
1254 error(arg.pos, "Invalid use of 'void'")
1255 elif not arg.type.is_complete() and not arg.type.is_array:
1257 "Argument type '%s' is incomplete" % arg.type)
1258 return env.declare_arg(arg.name, arg.type, arg.pos)
1260 def generate_wrapper_functions(self, code):
1263 def generate_execution_code(self, code):
1264 # Evaluate and store argument default values
1265 for arg in self.args:
1266 default = arg.default
1268 if not default.is_literal:
1269 default.generate_evaluation_code(code)
1270 default.make_owned_reference(code)
1273 arg.default_entry.cname,
1274 default.result_as(arg.default_entry.type)))
1275 if default.is_temp and default.type.is_pyobject:
1276 code.putln("%s = 0;" % default.result())
1277 default.free_temps(code)
1278 code.put_var_giveref(arg.default_entry)
1279 # For Python class methods, create and store function object
1281 self.assmt.generate_execution_code(code)
1284 # Special code for the __getbuffer__ function
1286 def getbuffer_init(self, code):
1287 info = self.local_scope.arg_entries[1].cname
1288 # Python 3.0 betas have a bug in memoryview which makes it call
1289 # getbuffer with a NULL parameter. For now we work around this;
1290 # the following line should be removed when this bug is fixed.
1291 code.putln("if (%s == NULL) return 0;" % info)
1292 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1293 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1295 def getbuffer_error_cleanup(self, code):
1296 info = self.local_scope.arg_entries[1].cname
1297 code.put_gotref("%s->obj" % info)
1298 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1301 def getbuffer_normal_cleanup(self, code):
1302 info = self.local_scope.arg_entries[1].cname
1303 code.putln("if (%s->obj == Py_None) {" % info)
1304 code.put_gotref("Py_None")
1305 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1308 class CFuncDefNode(FuncDefNode):
1309 # C function definition.
1311 # modifiers ['inline']
1312 # visibility 'private' or 'public' or 'extern'
1313 # base_type CBaseTypeNode
1314 # declarator CDeclaratorNode
1317 # decorators [DecoratorNode] list of decorators
1319 # with_gil boolean Acquire GIL around body
1321 # py_func wrapper for calling from Python
1322 # overridable whether or not this is a cpdef function
1323 # inline_in_pxd whether this is an inline function in a pxd file
1325 child_attrs = ["base_type", "declarator", "body", "py_func"]
1327 inline_in_pxd = False
1329 directive_locals = {}
1331 def unqualified_name(self):
1332 return self.entry.name
1334 def analyse_declarations(self, env):
1335 self.directive_locals.update(env.directives['locals'])
1336 base_type = self.base_type.analyse(env)
1337 # The 2 here is because we need both function and argument names.
1338 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1339 if not type.is_cfunction:
1341 "Suite attached to non-function declaration")
1342 # Remember the actual type according to the function header
1343 # written here, because the type in the symbol table entry
1344 # may be different if we're overriding a C method inherited
1345 # from the base type of an extension type.
1347 type.is_overridable = self.overridable
1348 declarator = self.declarator
1349 while not hasattr(declarator, 'args'):
1350 declarator = declarator.base
1351 self.args = declarator.args
1352 for formal_arg, type_arg in zip(self.args, type.args):
1353 formal_arg.type = type_arg.type
1354 formal_arg.name = type_arg.name
1355 formal_arg.cname = type_arg.cname
1356 name = name_declarator.name
1357 cname = name_declarator.cname
1358 self.entry = env.declare_cfunction(
1359 name, type, self.pos,
1360 cname = cname, visibility = self.visibility,
1361 defining = self.body is not None,
1362 api = self.api, modifiers = self.modifiers)
1363 self.entry.inline_func_in_pxd = self.inline_in_pxd
1364 self.return_type = type.return_type
1366 if self.overridable and not env.is_module_scope:
1367 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1368 # An error will be produced in the cdef function
1369 self.overridable = False
1371 if self.overridable:
1373 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1374 self.py_func = DefNode(pos = self.pos,
1375 name = self.entry.name,
1378 starstar_arg = None,
1380 body = py_func_body,
1382 self.py_func.is_module_scope = env.is_module_scope
1383 self.py_func.analyse_declarations(env)
1384 self.entry.as_variable = self.py_func.entry
1385 # Reset scope entry the above cfunction
1386 env.entries[name] = self.entry
1387 self.py_func.interned_attr_cname = env.intern_identifier(
1388 self.py_func.entry.name)
1389 if not env.is_module_scope or Options.lookup_module_cpdef:
1390 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1391 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1393 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1395 args = self.type.args
1396 if omit_optional_args:
1397 args = args[:len(args) - self.type.optional_arg_count]
1398 arg_names = [arg.name for arg in args]
1400 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1402 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1403 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1404 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1405 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)
1406 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1408 def declare_arguments(self, env):
1409 for arg in self.type.args:
1411 error(arg.pos, "Missing argument name")
1412 self.declare_argument(env, arg)
1414 def need_gil_acquisition(self, lenv):
1416 with_gil = self.type.with_gil
1417 if type.nogil and not with_gil:
1418 if type.return_type.is_pyobject:
1420 "Function with Python return type cannot be declared nogil")
1421 for entry in lenv.var_entries + lenv.temp_entries:
1422 if entry.type.is_pyobject:
1423 error(self.pos, "Function declared nogil has Python locals or temporaries")
1426 def analyse_expressions(self, env):
1427 self.local_scope.directives = env.directives
1428 self.analyse_default_values(env)
1429 if self.py_func is not None:
1430 self.py_func.analyse_expressions(env)
1432 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1435 visibility = self.entry.visibility
1436 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1437 arg_decls.append(arg.declaration_code())
1438 if with_dispatch and self.overridable:
1439 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1440 if type.optional_arg_count and with_opt_args:
1441 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1442 if type.has_varargs:
1443 arg_decls.append("...")
1445 arg_decls = ["void"]
1447 cname = self.entry.func_cname
1448 entity = type.function_header_code(cname, ', '.join(arg_decls))
1449 if visibility == 'public':
1450 dll_linkage = "DL_EXPORT"
1453 header = self.return_type.declaration_code(entity,
1454 dll_linkage = dll_linkage)
1455 if visibility == 'extern':
1456 storage_class = "%s " % Naming.extern_c_macro
1457 elif visibility == 'public':
1460 storage_class = "static "
1461 code.putln("%s%s %s {" % (
1463 ' '.join(self.modifiers).upper(), # macro forms
1466 def generate_argument_declarations(self, env, code):
1467 for arg in self.args:
1469 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1471 def generate_keyword_list(self, code):
1474 def generate_argument_parsing_code(self, env, code):
1476 if self.type.optional_arg_count:
1477 code.putln('if (%s) {' % Naming.optional_args_cname)
1478 for arg in self.args:
1480 # FIXME: simple name prefixing doesn't work when
1481 # argument name mangling is in place
1482 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1483 declarator = arg.declarator
1484 while not hasattr(declarator, 'name'):
1485 declarator = declarator.base
1486 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1488 for _ in range(self.type.optional_arg_count):
1492 def generate_argument_conversion_code(self, code):
1495 def generate_argument_type_tests(self, code):
1496 # Generate type tests for args whose type in a parent
1497 # class is a supertype of the declared type.
1498 for arg in self.type.args:
1499 if arg.needs_type_test:
1500 self.generate_arg_type_test(arg, code)
1502 def generate_arg_type_test(self, arg, code):
1503 # Generate type test for one argument.
1504 if arg.type.typeobj_is_available():
1505 typeptr_cname = arg.type.typeptr_cname
1506 arg_code = "((PyObject *)%s)" % arg.cname
1508 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1513 type.is_builtin_type,
1514 code.error_goto(arg.pos)))
1516 error(arg.pos, "Cannot test type of extern C class "
1517 "without type object name specification")
1519 def error_value(self):
1520 if self.return_type.is_pyobject:
1524 return self.entry.type.exception_value
1526 def caller_will_check_exceptions(self):
1527 return self.entry.type.exception_check
1529 def generate_wrapper_functions(self, code):
1530 # If the C signature of a function has changed, we need to generate
1531 # wrappers to put in the slots here.
1534 func_type = entry.type
1535 while entry.prev_entry is not None:
1537 entry = entry.prev_entry
1538 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1540 self.generate_function_header(code,
1542 with_dispatch = entry.type.is_overridable,
1543 with_opt_args = entry.type.optional_arg_count,
1544 cname = entry.func_cname)
1545 if not self.return_type.is_void:
1547 args = self.type.args
1548 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1549 if entry.type.is_overridable:
1550 arglist.append(Naming.skip_dispatch_cname)
1551 elif func_type.is_overridable:
1553 if entry.type.optional_arg_count:
1554 arglist.append(Naming.optional_args_cname)
1555 elif func_type.optional_arg_count:
1556 arglist.append('NULL')
1557 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1561 class PyArgDeclNode(Node):
1562 # Argument which must be a Python object (used
1563 # for * and ** arguments).
1566 # entry Symtab.Entry
1570 class DecoratorNode(Node):
1573 # decorator NameNode or CallNode
1574 child_attrs = ['decorator']
1577 class DefNode(FuncDefNode):
1578 # A Python function definition.
1580 # name string the Python name of the function
1581 # decorators [DecoratorNode] list of decorators
1582 # args [CArgDeclNode] formal arguments
1583 # star_arg PyArgDeclNode or None * argument
1584 # starstar_arg PyArgDeclNode or None ** argument
1585 # doc EncodedString or None
1588 # The following subnode is constructed internally
1589 # when the def statement is inside a Python class definition.
1591 # assmt AssignmentNode Function construction/assignment
1593 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1597 num_required_kw_args = 0
1598 reqd_kw_flags_cname = "0"
1604 def __init__(self, pos, **kwds):
1605 FuncDefNode.__init__(self, pos, **kwds)
1607 for arg in self.args:
1614 self.num_kwonly_args = k
1615 self.num_required_kw_args = rk
1616 self.num_required_args = r
1618 def as_cfunction(self, cfunc=None, scope=None):
1620 error(self.star_arg.pos, "cdef function cannot have star argument")
1621 if self.starstar_arg:
1622 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1625 for formal_arg in self.args:
1626 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1627 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1629 type = py_object_type,
1630 pos = formal_arg.pos))
1631 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1633 has_varargs = False,
1634 exception_value = None,
1635 exception_check = False,
1638 is_overridable = True)
1639 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1641 cfunc_type = cfunc.type
1642 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1643 error(self.pos, "wrong number of arguments")
1644 error(declarator.pos, "previous declaration here")
1645 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1646 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1647 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1648 formal_arg.type = type_arg.type
1649 formal_arg.name_declarator = name_declarator
1651 if cfunc_type.exception_value is None:
1652 exception_value = None
1654 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1655 declarator = CFuncDeclaratorNode(self.pos,
1656 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1658 has_varargs = False,
1659 exception_check = cfunc_type.exception_check,
1660 exception_value = exception_value,
1661 with_gil = cfunc_type.with_gil,
1662 nogil = cfunc_type.nogil)
1663 return CFuncDefNode(self.pos,
1665 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1666 declarator = declarator,
1669 overridable = cfunc_type.is_overridable,
1671 with_gil = cfunc_type.with_gil,
1672 nogil = cfunc_type.nogil,
1673 visibility = 'private',
1675 directive_locals = getattr(cfunc, 'directive_locals', {}))
1677 def analyse_declarations(self, env):
1678 directive_locals = self.directive_locals = env.directives['locals']
1679 for arg in self.args:
1680 if hasattr(arg, 'name'):
1682 name_declarator = None
1684 base_type = arg.base_type.analyse(env)
1685 name_declarator, type = \
1686 arg.declarator.analyse(base_type, env)
1687 arg.name = name_declarator.name
1688 if arg.name in directive_locals:
1689 type_node = directive_locals[arg.name]
1690 other_type = type_node.analyse_as_type(env)
1691 if other_type is None:
1692 error(type_node.pos, "Not a type")
1693 elif (type is not PyrexTypes.py_object_type
1694 and not type.same_as(other_type)):
1695 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1696 error(type_node.pos, "Previous declaration here")
1699 if name_declarator and name_declarator.cname:
1701 "Python function argument cannot have C name specification")
1702 arg.type = type.as_argument_type()
1704 arg.needs_conversion = 0
1705 arg.needs_type_test = 0
1707 if arg.not_none and not arg.type.is_extension_type:
1709 "Only extension type arguments can have 'not None'")
1710 self.declare_pyfunction(env)
1711 self.analyse_signature(env)
1712 self.return_type = self.entry.signature.return_type()
1714 def analyse_signature(self, env):
1715 any_type_tests_needed = 0
1716 if self.entry.is_special:
1717 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1718 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1719 # Use the simpler calling signature for zero- and one-argument functions.
1720 if self.entry.signature is TypeSlots.pyfunction_signature:
1721 if len(self.args) == 0:
1722 self.entry.signature = TypeSlots.pyfunction_noargs
1723 elif len(self.args) == 1:
1724 if self.args[0].default is None and not self.args[0].kw_only:
1725 self.entry.signature = TypeSlots.pyfunction_onearg
1726 elif self.entry.signature is TypeSlots.pymethod_signature:
1727 if len(self.args) == 1:
1728 self.entry.signature = TypeSlots.unaryfunc
1729 elif len(self.args) == 2:
1730 if self.args[1].default is None and not self.args[1].kw_only:
1731 self.entry.signature = TypeSlots.ibinaryfunc
1732 sig = self.entry.signature
1733 nfixed = sig.num_fixed_args()
1734 for i in range(nfixed):
1735 if i < len(self.args):
1738 if sig.is_self_arg(i):
1740 arg.hdr_type = arg.type = env.parent_type
1741 arg.needs_conversion = 0
1743 arg.hdr_type = sig.fixed_arg_type(i)
1744 if not arg.type.same_as(arg.hdr_type):
1745 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1746 arg.needs_type_test = 1
1747 any_type_tests_needed = 1
1749 arg.needs_conversion = 1
1750 if arg.needs_conversion:
1751 arg.hdr_cname = Naming.arg_prefix + arg.name
1753 arg.hdr_cname = Naming.var_prefix + arg.name
1755 self.bad_signature()
1757 if nfixed < len(self.args):
1758 if not sig.has_generic_args:
1759 self.bad_signature()
1760 for arg in self.args:
1761 if arg.is_generic and \
1762 (arg.type.is_extension_type or arg.type.is_builtin_type):
1763 arg.needs_type_test = 1
1764 any_type_tests_needed = 1
1765 if any_type_tests_needed:
1766 env.use_utility_code(arg_type_test_utility_code)
1768 def bad_signature(self):
1769 sig = self.entry.signature
1770 expected_str = "%d" % sig.num_fixed_args()
1771 if sig.has_generic_args:
1772 expected_str = expected_str + " or more"
1774 if name.startswith("__") and name.endswith("__"):
1775 desc = "Special method"
1779 "%s %s has wrong number of arguments "
1780 "(%d declared, %s expected)" % (
1781 desc, self.name, len(self.args), expected_str))
1783 def signature_has_nongeneric_args(self):
1784 argcount = len(self.args)
1785 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1789 def signature_has_generic_args(self):
1790 return self.entry.signature.has_generic_args
1792 def declare_pyfunction(self, env):
1793 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1795 entry = env.lookup_here(self.name)
1796 if entry and entry.type.is_cfunction and not self.is_wrapper:
1797 warning(self.pos, "Overriding cdef method with def method.", 5)
1798 entry = env.declare_pyfunction(self.name, self.pos)
1800 prefix = env.scope_prefix
1801 entry.func_cname = \
1802 Naming.pyfunc_prefix + prefix + name
1803 entry.pymethdef_cname = \
1804 Naming.pymethdef_prefix + prefix + name
1805 if Options.docstrings:
1806 entry.doc = embed_position(self.pos, self.doc)
1808 Naming.funcdoc_prefix + prefix + name
1812 def declare_arguments(self, env):
1813 for arg in self.args:
1815 error(arg.pos, "Missing argument name")
1816 if arg.needs_conversion:
1817 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1818 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1819 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1820 if arg.type.is_pyobject:
1821 arg.entry.init = "0"
1822 arg.entry.init_to_none = 0
1824 arg.entry = self.declare_argument(env, arg)
1826 arg.entry.is_self_arg = arg.is_self_arg
1827 if not arg.is_self_arg:
1828 arg.name_entry = env.get_string_const(
1829 arg.name, identifier = True)
1830 env.add_py_string(arg.name_entry, identifier = True)
1832 if arg.is_self_arg or \
1833 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1834 arg.entry.is_declared_generic = 1
1835 self.declare_python_arg(env, self.star_arg)
1836 self.declare_python_arg(env, self.starstar_arg)
1838 def declare_python_arg(self, env, arg):
1840 entry = env.declare_var(arg.name,
1841 PyrexTypes.py_object_type, arg.pos)
1844 entry.init_to_none = 0
1845 entry.xdecref_cleanup = 1
1847 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1849 def analyse_expressions(self, env):
1850 self.local_scope.directives = env.directives
1851 self.analyse_default_values(env)
1852 if env.is_py_class_scope:
1853 self.synthesize_assignment_node(env)
1855 def synthesize_assignment_node(self, env):
1857 self.assmt = SingleAssignmentNode(self.pos,
1858 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1859 rhs = ExprNodes.UnboundMethodNode(self.pos,
1860 class_cname = env.class_obj_cname,
1861 function = ExprNodes.PyCFunctionNode(self.pos,
1862 pymethdef_cname = self.entry.pymethdef_cname)))
1863 self.assmt.analyse_declarations(env)
1864 self.assmt.analyse_expressions(env)
1866 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1868 sig = self.entry.signature
1869 if sig.has_dummy_arg:
1870 arg_code_list.append(
1871 "PyObject *%s" % Naming.self_cname)
1872 for arg in self.args:
1873 if not arg.is_generic:
1875 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1877 arg_code_list.append(
1878 arg.hdr_type.declaration_code(arg.hdr_cname))
1879 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1880 arg_code_list.append("PyObject *unused")
1881 if sig.has_generic_args:
1882 arg_code_list.append(
1883 "PyObject *%s, PyObject *%s"
1884 % (Naming.args_cname, Naming.kwds_cname))
1885 arg_code = ", ".join(arg_code_list)
1886 dc = self.return_type.declaration_code(self.entry.func_cname)
1887 header = "static %s(%s)" % (dc, arg_code)
1888 code.putln("%s; /*proto*/" % header)
1891 if self.entry.doc and Options.docstrings:
1892 docstr = self.entry.doc
1893 if not isinstance(docstr, str):
1894 docstr = docstr.utf8encode()
1896 'static char %s[] = "%s";' % (
1897 self.entry.doc_cname,
1898 split_docstring(escape_byte_string(docstr))))
1901 "static PyMethodDef %s = " %
1902 self.entry.pymethdef_cname)
1903 code.put_pymethoddef(self.entry, ";")
1904 code.putln("%s {" % header)
1906 def generate_argument_declarations(self, env, code):
1907 for arg in self.args:
1908 if arg.is_generic: # or arg.needs_conversion:
1909 if arg.needs_conversion:
1910 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1912 code.put_var_declaration(arg.entry)
1914 def generate_keyword_list(self, code):
1915 if self.signature_has_generic_args() and \
1916 self.signature_has_nongeneric_args():
1918 "static PyObject **%s[] = {" %
1919 Naming.pykwdlist_cname)
1920 for arg in self.args:
1922 code.put('&%s,' % arg.name_entry.pystring_cname)
1925 def generate_argument_parsing_code(self, env, code):
1926 # Generate PyArg_ParseTuple call for generic
1927 # arguments, if any.
1928 if self.entry.signature.has_dummy_arg:
1929 # get rid of unused argument warning
1930 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1932 old_error_label = code.new_error_label()
1933 our_error_label = code.error_label
1934 end_label = code.new_label("argument_unpacking_done")
1936 has_kwonly_args = self.num_kwonly_args > 0
1937 has_star_or_kw_args = self.star_arg is not None \
1938 or self.starstar_arg is not None or has_kwonly_args
1940 for arg in self.args:
1941 if not arg.type.is_pyobject and arg.type.from_py_function is None:
1942 arg.type.create_from_py_utility_code(env)
1944 if not self.signature_has_generic_args():
1945 if has_star_or_kw_args:
1946 error(self.pos, "This method cannot have * or keyword arguments")
1947 self.generate_argument_conversion_code(code)
1949 elif not self.signature_has_nongeneric_args():
1950 # func(*args) or func(**kw) or func(*args, **kw)
1951 self.generate_stararg_copy_code(code)
1954 positional_args = []
1957 for arg in self.args:
1958 arg_entry = arg.entry
1962 if not arg.is_self_arg:
1964 kw_only_args.append(arg)
1966 positional_args.append(arg)
1968 kw_only_args.append(arg)
1971 error(arg.pos, "Non-default argument following default argument")
1972 elif not arg.is_self_arg:
1973 positional_args.append(arg)
1975 self.generate_tuple_and_keyword_parsing_code(
1976 positional_args, kw_only_args, end_label, code)
1978 code.error_label = old_error_label
1979 if code.label_used(our_error_label):
1980 if not code.label_used(end_label):
1981 code.put_goto(end_label)
1982 code.put_label(our_error_label)
1983 if has_star_or_kw_args:
1984 self.generate_arg_decref(self.star_arg, code)
1985 if self.starstar_arg:
1986 if self.starstar_arg.entry.xdecref_cleanup:
1987 code.put_var_xdecref(self.starstar_arg.entry)
1989 code.put_var_decref(self.starstar_arg.entry)
1990 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1991 code.putln("return %s;" % self.error_value())
1992 if code.label_used(end_label):
1993 code.put_label(end_label)
1995 def generate_arg_assignment(self, arg, item, code):
1996 if arg.type.is_pyobject:
1998 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1999 code.putln("%s = %s;" % (arg.entry.cname, item))
2001 func = arg.type.from_py_function
2003 code.putln("%s = %s(%s); %s" % (
2007 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2009 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2011 def generate_arg_xdecref(self, arg, code):
2013 code.put_var_xdecref(arg.entry)
2015 def generate_arg_decref(self, arg, code):
2017 code.put_var_decref(arg.entry)
2019 def generate_stararg_copy_code(self, code):
2020 if not self.star_arg:
2021 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2022 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2024 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2025 self.name.utf8encode(), Naming.args_cname, self.error_value()))
2028 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2030 if self.starstar_arg:
2032 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2034 kwarg_check = "%s" % Naming.kwds_cname
2036 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2037 Naming.kwds_cname, Naming.kwds_cname)
2039 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2040 kwarg_check, Naming.kwds_cname, self.name,
2041 bool(self.starstar_arg), self.error_value()))
2043 if self.starstar_arg:
2044 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2045 self.starstar_arg.entry.cname,
2048 code.putln("if (unlikely(!%s)) return %s;" % (
2049 self.starstar_arg.entry.cname, self.error_value()))
2050 self.starstar_arg.entry.xdecref_cleanup = 0
2051 code.put_gotref(self.starstar_arg.entry.cname)
2055 code.put_incref(Naming.args_cname, py_object_type)
2056 code.putln("%s = %s;" % (
2057 self.star_arg.entry.cname,
2059 self.star_arg.entry.xdecref_cleanup = 0
2061 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2062 kw_only_args, success_label, code):
2063 argtuple_error_label = code.new_label("argtuple_error")
2065 min_positional_args = self.num_required_args - self.num_required_kw_args
2066 if len(self.args) > 0 and self.args[0].is_self_arg:
2067 min_positional_args -= 1
2068 max_positional_args = len(positional_args)
2069 has_fixed_positional_count = not self.star_arg and \
2070 min_positional_args == max_positional_args
2072 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2073 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2074 if self.num_required_kw_args:
2075 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2077 if self.starstar_arg or self.star_arg:
2078 self.generate_stararg_init_code(max_positional_args, code)
2080 # --- optimised code when we receive keyword arguments
2081 if self.num_required_kw_args:
2082 likely_hint = "likely"
2084 likely_hint = "unlikely"
2085 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2086 self.generate_keyword_unpacking_code(
2087 min_positional_args, max_positional_args,
2088 has_fixed_positional_count,
2089 positional_args, kw_only_args, argtuple_error_label, code)
2091 # --- optimised code when we do not receive any keyword arguments
2092 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2093 # Python raises arg tuple related errors first, so we must
2094 # check the length here
2095 if min_positional_args == max_positional_args and not self.star_arg:
2099 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2100 Naming.args_cname, compare, min_positional_args))
2101 code.put_goto(argtuple_error_label)
2103 if self.num_required_kw_args:
2104 # pure error case: keywords required but not passed
2105 if max_positional_args > min_positional_args and not self.star_arg:
2106 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2107 Naming.args_cname, max_positional_args))
2108 code.put_goto(argtuple_error_label)
2109 code.putln('} else {')
2110 for i, arg in enumerate(kw_only_args):
2112 # required keyword-only argument missing
2113 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2114 self.name.utf8encode(),
2115 arg.name_entry.pystring_cname))
2116 code.putln(code.error_goto(self.pos))
2119 elif min_positional_args == max_positional_args:
2120 # parse the exact number of positional arguments from the
2122 code.putln('} else {')
2123 for i, arg in enumerate(positional_args):
2124 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2125 self.generate_arg_assignment(arg, item, code)
2126 self.generate_arg_default_assignments(code)
2129 # parse the positional arguments from the variable length
2131 code.putln('} else {')
2132 self.generate_arg_default_assignments(code)
2133 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2135 code.putln('default:')
2136 reversed_args = list(enumerate(positional_args))[::-1]
2137 for i, arg in reversed_args:
2138 if i >= min_positional_args-1:
2139 if min_positional_args > 1:
2140 code.putln('case %2d:' % (i+1)) # pure code beautification
2142 code.put('case %2d: ' % (i+1))
2143 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2144 self.generate_arg_assignment(arg, item, code)
2145 if min_positional_args == 0:
2146 code.put('case 0: ')
2147 code.putln('break;')
2149 if min_positional_args:
2150 for i in range(min_positional_args-1, -1, -1):
2151 code.putln('case %2d:' % i)
2152 code.put_goto(argtuple_error_label)
2154 code.put('default: ')
2155 code.put_goto(argtuple_error_label)
2160 if code.label_used(argtuple_error_label):
2161 code.put_goto(success_label)
2162 code.put_label(argtuple_error_label)
2163 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2164 self.name.utf8encode(), has_fixed_positional_count,
2165 min_positional_args, max_positional_args,
2167 code.putln(code.error_goto(self.pos))
2169 def generate_arg_default_assignments(self, code):
2170 for arg in self.args:
2171 if arg.is_generic and arg.default:
2175 arg.default_result_code))
2177 def generate_stararg_init_code(self, max_positional_args, code):
2178 if self.starstar_arg:
2179 self.starstar_arg.entry.xdecref_cleanup = 0
2180 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2181 self.starstar_arg.entry.cname,
2182 self.starstar_arg.entry.cname,
2183 self.error_value()))
2184 code.put_gotref(self.starstar_arg.entry.cname)
2186 self.star_arg.entry.xdecref_cleanup = 0
2187 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2189 max_positional_args))
2190 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2191 self.star_arg.entry.cname, Naming.args_cname,
2192 max_positional_args, Naming.args_cname))
2193 code.put_gotref(self.star_arg.entry.cname)
2194 if self.starstar_arg:
2196 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2197 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2198 code.putln('return %s;' % self.error_value())
2201 code.putln("if (unlikely(!%s)) return %s;" % (
2202 self.star_arg.entry.cname, self.error_value()))
2203 code.putln('} else {')
2204 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2205 code.put_incref(Naming.empty_tuple, py_object_type)
2208 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2209 has_fixed_positional_count, positional_args,
2210 kw_only_args, argtuple_error_label, code):
2211 all_args = tuple(positional_args) + tuple(kw_only_args)
2212 max_args = len(all_args)
2215 for i, arg in enumerate(all_args):
2216 if arg.default and arg.type.is_pyobject:
2217 default_value = arg.default_result_code
2218 if arg.type is not PyrexTypes.py_object_type:
2219 default_value = "(PyObject*)"+default_value
2220 default_args.append((i, default_value))
2222 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2224 # it looks funny to separate the init-to-0 from setting the
2225 # default value, but C89 needs this
2226 code.putln("PyObject* values[%d] = {%s};" % (
2227 max_args, ','.join(['0']*max_args)))
2228 for i, default_value in default_args:
2229 code.putln('values[%d] = %s;' % (i, default_value))
2231 # parse the tuple and check that it's not too long
2232 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2234 code.putln('default:')
2235 for i in range(max_positional_args-1, -1, -1):
2236 code.put('case %2d: ' % (i+1))
2237 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2238 i, Naming.args_cname, i))
2239 code.putln('case 0: break;')
2240 if not self.star_arg:
2241 code.put('default: ') # more arguments than allowed
2242 code.put_goto(argtuple_error_label)
2245 # now fill up the positional/required arguments with values
2247 if self.num_required_args or max_positional_args > 0:
2248 last_required_arg = -1
2249 for i, arg in enumerate(all_args):
2251 last_required_arg = i
2252 if last_required_arg < max_positional_args:
2253 last_required_arg = max_positional_args-1
2254 num_required_args = self.num_required_args
2255 if max_positional_args > 0:
2256 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2257 for i, arg in enumerate(all_args[:last_required_arg+1]):
2258 if max_positional_args > 0 and i <= max_positional_args:
2259 if self.star_arg and i == max_positional_args:
2260 code.putln('default:')
2262 code.putln('case %2d:' % i)
2265 # handled separately below
2267 code.putln('if (kw_args > %d) {' % num_required_args)
2268 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2269 Naming.kwds_cname, arg.name_entry.pystring_cname))
2270 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2273 num_required_args -= 1
2274 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2275 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2276 code.putln('if (likely(values[%d])) kw_args--;' % i);
2277 if i < min_positional_args:
2279 # special case: we know arg 0 is missing
2281 code.put_goto(argtuple_error_label)
2283 # print the correct number of values (args or
2284 # kwargs) that were passed into positional
2285 # arguments up to this point
2286 code.putln('else {')
2287 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2288 self.name.utf8encode(), has_fixed_positional_count,
2289 min_positional_args, max_positional_args, i))
2290 code.putln(code.error_goto(self.pos))
2293 code.putln('else {')
2294 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2295 self.name.utf8encode(), arg.name_entry.pystring_cname))
2296 code.putln(code.error_goto(self.pos))
2298 if max_positional_args > 0:
2301 if kw_only_args and not self.starstar_arg:
2302 # unpack optional keyword-only arguments
2303 # checking for interned strings in a dict is faster than iterating
2304 # but it's too likely that we must iterate if we expect **kwargs
2306 for i, arg in enumerate(all_args[max_positional_args:]):
2307 if not arg.kw_only or not arg.default:
2309 optional_args.append((i+max_positional_args, arg))
2311 # this mimics an unrolled loop so that we can "break" out of it
2312 code.putln('while (kw_args > 0) {')
2313 code.putln('PyObject* value;')
2314 for i, arg in optional_args:
2316 'value = PyDict_GetItem(%s, %s);' % (
2317 Naming.kwds_cname, arg.name_entry.pystring_cname))
2319 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2320 code.putln('break;')
2323 code.putln('if (unlikely(kw_args > 0)) {')
2324 # non-positional/-required kw args left in dict: default args,
2325 # kw-only args, **kwargs or error
2327 # This is sort of a catch-all: except for checking required
2328 # arguments, this will always do the right thing for unpacking
2329 # keyword arguments, so that we can concentrate on optimising
2330 # common cases above.
2331 if max_positional_args == 0:
2334 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2335 Naming.args_cname, max_positional_args,
2336 Naming.args_cname, max_positional_args))
2337 pos_arg_count = "used_pos_args"
2339 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2340 code.globalstate.use_utility_code(parse_keywords_utility_code)
2342 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2344 Naming.pykwdlist_cname,
2345 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2347 self.name.utf8encode()))
2348 code.putln(code.error_goto(self.pos))
2351 # convert arg values to their final type and assign them
2352 for i, arg in enumerate(all_args):
2353 if arg.default and not arg.type.is_pyobject:
2354 code.putln("if (values[%d]) {" % i)
2355 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2356 if arg.default and not arg.type.is_pyobject:
2357 code.putln('} else {')
2361 arg.default_result_code))
2364 def generate_argument_conversion_code(self, code):
2365 # Generate code to convert arguments from
2366 # signature type to declared type, if needed.
2367 for arg in self.args:
2368 if arg.needs_conversion:
2369 self.generate_arg_conversion(arg, code)
2371 def generate_arg_conversion(self, arg, code):
2372 # Generate conversion code for one argument.
2373 old_type = arg.hdr_type
2375 if old_type.is_pyobject:
2377 code.putln("if (%s) {" % arg.hdr_cname)
2379 code.putln("assert(%s); {" % arg.hdr_cname)
2380 self.generate_arg_conversion_from_pyobject(arg, code)
2382 elif new_type.is_pyobject:
2383 self.generate_arg_conversion_to_pyobject(arg, code)
2385 if new_type.assignable_from(old_type):
2387 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2390 "Cannot convert 1 argument from '%s' to '%s'" %
2391 (old_type, new_type))
2393 def generate_arg_conversion_from_pyobject(self, arg, code):
2395 func = new_type.from_py_function
2396 # copied from CoerceFromPyTypeNode
2398 code.putln("%s = %s(%s); %s" % (
2402 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2405 "Cannot convert Python object argument to type '%s'"
2408 def generate_arg_conversion_to_pyobject(self, arg, code):
2409 old_type = arg.hdr_type
2410 func = old_type.to_py_function
2412 code.putln("%s = %s(%s); %s" % (
2416 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2417 code.put_var_gotref(arg.entry)
2420 "Cannot convert argument of type '%s' to Python object"
2423 def generate_argument_type_tests(self, code):
2424 # Generate type tests for args whose signature
2425 # type is PyObject * and whose declared type is
2426 # a subtype thereof.
2427 for arg in self.args:
2428 if arg.needs_type_test:
2429 self.generate_arg_type_test(arg, code)
2431 def generate_arg_type_test(self, arg, code):
2432 # Generate type test for one argument.
2433 if arg.type.typeobj_is_available():
2434 typeptr_cname = arg.type.typeptr_cname
2435 arg_code = "((PyObject *)%s)" % arg.entry.cname
2437 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2442 arg.type.is_builtin_type,
2443 code.error_goto(arg.pos)))
2445 error(arg.pos, "Cannot test type of extern C class "
2446 "without type object name specification")
2448 def error_value(self):
2449 return self.entry.signature.error_value
2451 def caller_will_check_exceptions(self):
2454 class OverrideCheckNode(StatNode):
2455 # A Node for dispatching to the def method if it
2464 child_attrs = ['body']
2468 def analyse_expressions(self, env):
2469 self.args = env.arg_entries
2470 if self.py_func.is_module_scope:
2475 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2476 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2477 call_node = ExprNodes.SimpleCallNode(self.pos,
2478 function=self.func_node,
2479 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2480 self.body = ReturnStatNode(self.pos, value=call_node)
2481 self.body.analyse_expressions(env)
2483 def generate_execution_code(self, code):
2484 # Check to see if we are an extension type
2485 if self.py_func.is_module_scope:
2486 self_arg = "((PyObject *)%s)" % Naming.module_cname
2488 self_arg = "((PyObject *)%s)" % self.args[0].cname
2489 code.putln("/* Check if called by wrapper */")
2490 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2491 code.putln("/* Check if overriden in Python */")
2492 if self.py_func.is_module_scope:
2493 code.putln("else {")
2495 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2496 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2497 # need to get attribute manually--scope would return cdef method
2498 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2499 code.put_gotref(self.func_node.py_result())
2500 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2501 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2502 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2503 self.body.generate_execution_code(code)
2505 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2508 class ClassDefNode(StatNode, BlockNode):
2511 class PyClassDefNode(ClassDefNode):
2512 # A Python class definition.
2514 # name EncodedString Name of the class
2515 # doc string or None
2516 # body StatNode Attribute definition code
2517 # entry Symtab.Entry
2518 # scope PyClassScope
2520 # The following subnodes are constructed internally:
2522 # dict DictNode Class dictionary
2523 # classobj ClassNode Class object
2524 # target NameNode Variable to assign class object to
2526 child_attrs = ["body", "dict", "classobj", "target"]
2528 def __init__(self, pos, name, bases, doc, body):
2529 StatNode.__init__(self, pos)
2534 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2535 if self.doc and Options.docstrings:
2536 doc = embed_position(self.pos, self.doc)
2537 doc_node = ExprNodes.StringNode(pos, value = doc)
2540 self.classobj = ExprNodes.ClassNode(pos, name = name,
2541 bases = bases, dict = self.dict, doc = doc_node)
2542 self.target = ExprNodes.NameNode(pos, name = name)
2544 def as_cclass(self):
2546 Return this node as if it were declared as an extension class
2548 bases = self.classobj.bases.args
2550 base_class_name = None
2551 base_class_module = None
2552 elif len(bases) == 1:
2555 from ExprNodes import AttributeNode, NameNode
2556 while isinstance(base, AttributeNode):
2557 path.insert(0, base.attribute)
2559 if isinstance(base, NameNode):
2560 path.insert(0, base.name)
2561 base_class_name = path[-1]
2563 base_class_module = u'.'.join(path[:-1])
2565 base_class_module = None
2567 error(self.classobj.bases.args.pos, "Invalid base class")
2569 error(self.classobj.bases.args.pos, "C class may only have one base class")
2572 return CClassDefNode(self.pos,
2573 visibility = 'private',
2575 class_name = self.name,
2576 base_class_module = base_class_module,
2577 base_class_name = base_class_name,
2582 def create_scope(self, env):
2584 while env.is_py_class_scope or env.is_c_class_scope:
2585 env = env.outer_scope
2586 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2589 def analyse_declarations(self, env):
2590 self.target.analyse_target_declaration(env)
2591 cenv = self.create_scope(env)
2592 cenv.directives = env.directives
2593 cenv.class_obj_cname = self.target.entry.cname
2594 self.body.analyse_declarations(cenv)
2596 def analyse_expressions(self, env):
2597 self.dict.analyse_expressions(env)
2598 self.classobj.analyse_expressions(env)
2599 genv = env.global_scope()
2601 cenv.class_dict_cname = self.dict.result()
2602 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2603 self.body.analyse_expressions(cenv)
2604 self.target.analyse_target_expression(env, self.classobj)
2605 self.dict.release_temp(env)
2606 #self.classobj.release_temp(env)
2607 #self.target.release_target_temp(env)
2609 def generate_function_definitions(self, env, code):
2610 self.generate_py_string_decls(self.scope, code)
2611 self.body.generate_function_definitions(self.scope, code)
2613 def generate_execution_code(self, code):
2614 self.dict.generate_evaluation_code(code)
2615 self.classobj.generate_evaluation_code(code)
2616 self.body.generate_execution_code(code)
2617 self.target.generate_assignment_code(self.classobj, code)
2618 self.dict.generate_disposal_code(code)
2619 self.dict.free_temps(code)
2622 class CClassDefNode(ClassDefNode):
2623 # An extension type definition.
2625 # visibility 'private' or 'public' or 'extern'
2626 # typedef_flag boolean
2628 # module_name string or None For import of extern type objects
2629 # class_name string Unqualified name of class
2630 # as_name string or None Name to declare as in this scope
2631 # base_class_module string or None Module containing the base class
2632 # base_class_name string or None Name of the base class
2633 # objstruct_name string or None Specified C name of object struct
2634 # typeobj_name string or None Specified C name of type object
2635 # in_pxd boolean Is in a .pxd file
2636 # doc string or None
2637 # body StatNode or None
2638 # entry Symtab.Entry
2639 # base_type PyExtensionType or None
2640 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2641 # buffer_defaults_pos
2643 child_attrs = ["body"]
2644 buffer_defaults_node = None
2645 buffer_defaults_pos = None
2646 typedef_flag = False
2648 objstruct_name = None
2651 def analyse_declarations(self, env):
2652 #print "CClassDefNode.analyse_declarations:", self.class_name
2653 #print "...visibility =", self.visibility
2654 #print "...module_name =", self.module_name
2657 if self.buffer_defaults_node:
2658 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2659 env, [], self.buffer_defaults_node,
2660 need_complete=False)
2662 buffer_defaults = None
2664 if env.in_cinclude and not self.objstruct_name:
2665 error(self.pos, "Object struct name specification required for "
2666 "C class defined in 'extern from' block")
2667 self.base_type = None
2668 # Now that module imports are cached, we need to
2669 # import the modules for extern classes.
2670 if self.module_name:
2672 for module in env.cimported_modules:
2673 if module.name == self.module_name:
2674 self.module = module
2675 if self.module is None:
2676 self.module = ModuleScope(self.module_name, None, env.context)
2677 self.module.has_extern_class = 1
2678 env.add_imported_module(self.module)
2680 if self.base_class_name:
2681 if self.base_class_module:
2682 base_class_scope = env.find_module(self.base_class_module, self.pos)
2684 base_class_scope = env
2685 if self.base_class_name == 'object':
2686 # extension classes are special and don't need to inherit from object
2687 if base_class_scope is None or base_class_scope.lookup('object') is None:
2688 self.base_class_name = None
2689 self.base_class_module = None
2690 base_class_scope = None
2691 if base_class_scope:
2692 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2693 if base_class_entry:
2694 if not base_class_entry.is_type:
2695 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2696 elif not base_class_entry.type.is_extension_type:
2697 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2698 elif not base_class_entry.type.is_complete():
2699 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2701 self.base_type = base_class_entry.type
2702 has_body = self.body is not None
2703 if self.module_name and self.visibility != 'extern':
2704 module_path = self.module_name.split(".")
2705 home_scope = env.find_imported_module(module_path, self.pos)
2711 if self.visibility == 'extern':
2712 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2713 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2715 self.entry = home_scope.declare_c_class(
2716 name = self.class_name,
2718 defining = has_body and self.in_pxd,
2719 implementing = has_body and not self.in_pxd,
2720 module_name = self.module_name,
2721 base_type = self.base_type,
2722 objstruct_cname = self.objstruct_name,
2723 typeobj_cname = self.typeobj_name,
2724 visibility = self.visibility,
2725 typedef_flag = self.typedef_flag,
2727 buffer_defaults = buffer_defaults)
2728 if home_scope is not env and self.visibility == 'extern':
2729 env.add_imported_entry(self.class_name, self.entry, pos)
2730 scope = self.entry.type.scope
2731 if scope is not None:
2732 scope.directives = env.directives
2734 if self.doc and Options.docstrings:
2735 scope.doc = embed_position(self.pos, self.doc)
2738 self.body.analyse_declarations(scope)
2742 scope.implemented = 1
2743 env.allocate_vtable_names(self.entry)
2745 def analyse_expressions(self, env):
2747 scope = self.entry.type.scope
2748 self.body.analyse_expressions(scope)
2750 def generate_function_definitions(self, env, code):
2751 self.generate_py_string_decls(self.entry.type.scope, code)
2753 self.body.generate_function_definitions(
2754 self.entry.type.scope, code)
2756 def generate_execution_code(self, code):
2757 # This is needed to generate evaluation code for
2758 # default values of method arguments.
2760 self.body.generate_execution_code(code)
2762 def annotate(self, code):
2764 self.body.annotate(code)
2767 class PropertyNode(StatNode):
2768 # Definition of a property in an extension type.
2771 # doc EncodedString or None Doc string
2774 child_attrs = ["body"]
2776 def analyse_declarations(self, env):
2777 entry = env.declare_property(self.name, self.doc, self.pos)
2779 if self.doc and Options.docstrings:
2780 doc_entry = env.get_string_const(
2781 self.doc, identifier = False)
2782 entry.doc_cname = doc_entry.cname
2783 entry.scope.directives = env.directives
2784 self.body.analyse_declarations(entry.scope)
2786 def analyse_expressions(self, env):
2787 self.body.analyse_expressions(env)
2789 def generate_function_definitions(self, env, code):
2790 self.body.generate_function_definitions(env, code)
2792 def generate_execution_code(self, code):
2795 def annotate(self, code):
2796 self.body.annotate(code)
2799 class GlobalNode(StatNode):
2800 # Global variable declaration.
2806 def analyse_declarations(self, env):
2807 for name in self.names:
2808 env.declare_global(name, self.pos)
2810 def analyse_expressions(self, env):
2813 def generate_execution_code(self, code):
2817 class ExprStatNode(StatNode):
2818 # Expression used as a statement.
2822 child_attrs = ["expr"]
2824 def analyse_declarations(self, env):
2826 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2827 func = self.expr.function.as_cython_attribute()
2828 if func == u'declare':
2829 args, kwds = self.expr.explicit_args_kwds()
2831 error(self.expr.pos, "Variable names must be specified.")
2832 for var, type_node in kwds.key_value_pairs:
2833 type = type_node.analyse_as_type(env)
2835 error(type_node.pos, "Unknown type")
2837 env.declare_var(var.value, type, var.pos, is_cdef = True)
2838 self.__class__ = PassStatNode
2840 def analyse_expressions(self, env):
2841 self.expr.analyse_expressions(env)
2842 self.expr.release_temp(env)
2844 def generate_execution_code(self, code):
2845 self.expr.generate_evaluation_code(code)
2846 if not self.expr.is_temp and self.expr.result():
2847 code.putln("%s;" % self.expr.result())
2848 self.expr.generate_disposal_code(code)
2849 self.expr.free_temps(code)
2851 def annotate(self, code):
2852 self.expr.annotate(code)
2855 class AssignmentNode(StatNode):
2856 # Abstract base class for assignment nodes.
2858 # The analyse_expressions and generate_execution_code
2859 # phases of assignments are split into two sub-phases
2860 # each, to enable all the right hand sides of a
2861 # parallel assignment to be evaluated before assigning
2862 # to any of the left hand sides.
2864 def analyse_expressions(self, env):
2865 self.analyse_types(env)
2866 self.allocate_rhs_temps(env)
2867 self.allocate_lhs_temps(env)
2869 # def analyse_expressions(self, env):
2870 # self.analyse_expressions_1(env)
2871 # self.analyse_expressions_2(env)
2873 def generate_execution_code(self, code):
2874 self.generate_rhs_evaluation_code(code)
2875 self.generate_assignment_code(code)
2878 class SingleAssignmentNode(AssignmentNode):
2879 # The simplest case:
2883 # lhs ExprNode Left hand side
2884 # rhs ExprNode Right hand side
2885 # first bool Is this guaranteed the first assignment to lhs?
2887 child_attrs = ["lhs", "rhs"]
2889 declaration_only = False
2891 def analyse_declarations(self, env):
2894 # handle declarations of the form x = cython.foo()
2895 if isinstance(self.rhs, ExprNodes.CallNode):
2896 func_name = self.rhs.function.as_cython_attribute()
2898 args, kwds = self.rhs.explicit_args_kwds()
2900 if func_name in ['declare', 'typedef']:
2901 if len(args) > 2 or kwds is not None:
2902 error(rhs.pos, "Can only declare one type at a time.")
2904 type = args[0].analyse_as_type(env)
2906 error(args[0].pos, "Unknown type")
2909 if func_name == 'declare':
2910 if isinstance(lhs, ExprNodes.NameNode):
2911 vars = [(lhs.name, lhs.pos)]
2912 elif isinstance(lhs, ExprNodes.TupleNode):
2913 vars = [(var.name, var.pos) for var in lhs.args]
2915 error(lhs.pos, "Invalid declaration")
2917 for var, pos in vars:
2918 env.declare_var(var, type, pos, is_cdef = True)
2923 self.declaration_only = True
2925 self.declaration_only = True
2926 if not isinstance(lhs, ExprNodes.NameNode):
2927 error(lhs.pos, "Invalid declaration.")
2928 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2930 elif func_name in ['struct', 'union']:
2931 self.declaration_only = True
2932 if len(args) > 0 or kwds is None:
2933 error(rhs.pos, "Struct or union members must be given by name.")
2936 for member, type_node in kwds.key_value_pairs:
2937 type = type_node.analyse_as_type(env)
2939 error(type_node.pos, "Unknown type")
2941 members.append((member.value, type, member.pos))
2942 if len(members) < len(kwds.key_value_pairs):
2944 if not isinstance(self.lhs, ExprNodes.NameNode):
2945 error(self.lhs.pos, "Invalid declaration.")
2946 name = self.lhs.name
2947 scope = StructOrUnionScope(name)
2948 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2949 for member, type, pos in members:
2950 scope.declare_var(member, type, pos)
2952 if self.declaration_only:
2955 self.lhs.analyse_target_declaration(env)
2957 def analyse_types(self, env, use_temp = 0):
2958 self.rhs.analyse_types(env)
2959 self.lhs.analyse_target_types(env)
2960 self.lhs.gil_assignment_check(env)
2961 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2963 self.rhs = self.rhs.coerce_to_temp(env)
2965 def allocate_rhs_temps(self, env):
2966 self.rhs.allocate_temps(env)
2968 def allocate_lhs_temps(self, env):
2969 self.lhs.allocate_target_temps(env, self.rhs)
2970 #self.lhs.release_target_temp(env)
2971 #self.rhs.release_temp(env)
2973 def generate_rhs_evaluation_code(self, code):
2974 self.rhs.generate_evaluation_code(code)
2976 def generate_assignment_code(self, code):
2977 self.lhs.generate_assignment_code(self.rhs, code)
2979 def annotate(self, code):
2980 self.lhs.annotate(code)
2981 self.rhs.annotate(code)
2984 class CascadedAssignmentNode(AssignmentNode):
2985 # An assignment with multiple left hand sides:
2989 # lhs_list [ExprNode] Left hand sides
2990 # rhs ExprNode Right hand sides
2994 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2996 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2997 coerced_rhs_list = None
2999 def analyse_declarations(self, env):
3000 for lhs in self.lhs_list:
3001 lhs.analyse_target_declaration(env)
3003 def analyse_types(self, env, use_temp = 0):
3004 self.rhs.analyse_types(env)
3006 self.rhs = self.rhs.coerce_to_temp(env)
3008 self.rhs = self.rhs.coerce_to_simple(env)
3009 from ExprNodes import CloneNode
3010 self.coerced_rhs_list = []
3011 for lhs in self.lhs_list:
3012 lhs.analyse_target_types(env)
3013 lhs.gil_assignment_check(env)
3014 rhs = CloneNode(self.rhs)
3015 rhs = rhs.coerce_to(lhs.type, env)
3016 self.coerced_rhs_list.append(rhs)
3018 def allocate_rhs_temps(self, env):
3019 self.rhs.allocate_temps(env)
3021 def allocate_lhs_temps(self, env):
3022 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
3023 rhs.allocate_temps(env)
3024 lhs.allocate_target_temps(env, rhs)
3025 #lhs.release_target_temp(env)
3026 #rhs.release_temp(env)
3027 self.rhs.release_temp(env)
3029 def generate_rhs_evaluation_code(self, code):
3030 self.rhs.generate_evaluation_code(code)
3032 def generate_assignment_code(self, code):
3033 for i in range(len(self.lhs_list)):
3034 lhs = self.lhs_list[i]
3035 rhs = self.coerced_rhs_list[i]
3036 rhs.generate_evaluation_code(code)
3037 lhs.generate_assignment_code(rhs, code)
3038 # Assignment has disposed of the cloned RHS
3039 self.rhs.generate_disposal_code(code)
3040 self.rhs.free_temps(code)
3042 def annotate(self, code):
3043 for i in range(len(self.lhs_list)):
3044 lhs = self.lhs_list[i].annotate(code)
3045 rhs = self.coerced_rhs_list[i].annotate(code)
3046 self.rhs.annotate(code)
3049 class ParallelAssignmentNode(AssignmentNode):
3050 # A combined packing/unpacking assignment:
3054 # This has been rearranged by the parser into
3056 # a = d ; b = e ; c = f
3058 # but we must evaluate all the right hand sides
3059 # before assigning to any of the left hand sides.
3061 # stats [AssignmentNode] The constituent assignments
3063 child_attrs = ["stats"]
3065 def analyse_declarations(self, env):
3066 for stat in self.stats:
3067 stat.analyse_declarations(env)
3069 def analyse_expressions(self, env):
3070 for stat in self.stats:
3071 stat.analyse_types(env, use_temp = 1)
3072 stat.allocate_rhs_temps(env)
3073 for stat in self.stats:
3074 stat.allocate_lhs_temps(env)
3076 # def analyse_expressions(self, env):
3077 # for stat in self.stats:
3078 # stat.analyse_expressions_1(env, use_temp = 1)
3079 # for stat in self.stats:
3080 # stat.analyse_expressions_2(env)
3082 def generate_execution_code(self, code):
3083 for stat in self.stats:
3084 stat.generate_rhs_evaluation_code(code)
3085 for stat in self.stats:
3086 stat.generate_assignment_code(code)
3088 def annotate(self, code):
3089 for stat in self.stats:
3093 class InPlaceAssignmentNode(AssignmentNode):
3094 # An in place arithmatic operand:
3100 # lhs ExprNode Left hand side
3101 # rhs ExprNode Right hand side
3102 # op char one of "+-*/%^&|"
3103 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3105 # This code is a bit tricky because in order to obey Python
3106 # semantics the sub-expressions (e.g. indices) of the lhs must
3107 # not be evaluated twice. So we must re-use the values calculated
3108 # in evaluation phase for the assignment phase as well.
3109 # Fortunately, the type of the lhs node is fairly constrained
3110 # (it must be a NameNode, AttributeNode, or IndexNode).
3112 child_attrs = ["lhs", "rhs"]
3115 def analyse_declarations(self, env):
3116 self.lhs.analyse_target_declaration(env)
3118 def analyse_types(self, env):
3119 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3120 self.rhs.analyse_types(env)
3121 self.lhs.analyse_target_types(env)
3122 if Options.incref_local_binop and self.dup.type.is_pyobject:
3123 self.dup = self.dup.coerce_to_temp(env)
3125 def allocate_rhs_temps(self, env):
3127 if self.lhs.type.is_pyobject:
3128 self.rhs = self.rhs.coerce_to_pyobject(env)
3129 elif self.rhs.type.is_pyobject:
3130 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3131 if self.lhs.type.is_pyobject:
3132 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3133 self.result_value.allocate_temps(env)
3135 # self.rhs = self.rhs.coerce_to_temp(env)
3136 self.rhs.allocate_temps(env)
3137 self.dup.allocate_subexpr_temps(env)
3138 self.dup.allocate_temp(env)
3140 def allocate_lhs_temps(self, env):
3141 self.lhs.allocate_target_temps(env, self.rhs)
3142 # self.lhs.release_target_temp(env)
3143 self.dup.release_temp(env)
3144 if self.dup.is_temp:
3145 self.dup.release_subexpr_temps(env)
3146 # self.rhs.release_temp(env)
3147 if self.lhs.type.is_pyobject:
3148 self.result_value.release_temp(env)
3150 def generate_execution_code(self, code):
3152 self.rhs.generate_evaluation_code(code)
3153 self.dup.generate_subexpr_evaluation_code(code)
3154 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3155 # This is because we're manually messing with subexpr nodes
3156 if self.dup.is_temp:
3157 self.dup.allocate_temp_result(code)
3158 # self.dup.generate_result_code is run only if it is not buffer access
3159 if self.operator == "**":
3163 if self.lhs.type.is_pyobject:
3164 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3165 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3166 self.dup.generate_result_code(code)
3168 "%s = %s(%s, %s%s); %s" % (
3169 self.result_value.result(),
3170 self.py_operation_function(),
3171 self.dup.py_result(),
3172 self.rhs.py_result(),
3174 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3175 code.put_gotref(self.result_value.py_result())
3176 self.result_value.generate_evaluation_code(code) # May be a type check...
3177 self.rhs.generate_disposal_code(code)
3178 self.rhs.free_temps(code)
3179 self.dup.generate_disposal_code(code)
3180 self.dup.free_temps(code)
3181 self.lhs.generate_assignment_code(self.result_value, code)
3183 c_op = self.operator
3187 error(self.pos, "No C inplace power operator")
3188 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3189 error(self.pos, "Inplace operators not implemented for complex types.")
3191 # have to do assignment directly to avoid side-effects
3192 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3193 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3195 self.dup.generate_result_code(code)
3196 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3197 self.rhs.generate_disposal_code(code)
3198 self.rhs.free_temps(code)
3199 if self.dup.is_temp:
3200 self.dup.generate_subexpr_disposal_code(code)
3201 self.dup.free_subexpr_temps(code)
3203 def create_dup_node(self, env):
3206 self.dup.analyse_types(env)
3207 if isinstance(self.lhs, ExprNodes.NameNode):
3208 target_lhs = ExprNodes.NameNode(self.dup.pos,
3209 name = self.dup.name,
3210 is_temp = self.dup.is_temp,
3211 entry = self.dup.entry)
3212 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3213 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3214 obj = ExprNodes.CloneNode(self.lhs.obj),
3215 attribute = self.dup.attribute,
3216 is_temp = self.dup.is_temp)
3217 elif isinstance(self.lhs, ExprNodes.IndexNode):
3219 index = ExprNodes.CloneNode(self.lhs.index)
3222 if self.lhs.indices:
3223 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3226 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3227 base = ExprNodes.CloneNode(self.dup.base),
3230 is_temp = self.dup.is_temp)
3233 self.lhs = target_lhs
3236 def py_operation_function(self):
3237 return self.py_functions[self.operator]
3240 "|": "PyNumber_InPlaceOr",
3241 "^": "PyNumber_InPlaceXor",
3242 "&": "PyNumber_InPlaceAnd",
3243 "+": "PyNumber_InPlaceAdd",
3244 "-": "PyNumber_InPlaceSubtract",
3245 "*": "PyNumber_InPlaceMultiply",
3246 "/": "PyNumber_InPlaceDivide",
3247 "%": "PyNumber_InPlaceRemainder",
3248 "<<": "PyNumber_InPlaceLshift",
3249 ">>": "PyNumber_InPlaceRshift",
3250 "**": "PyNumber_InPlacePower",
3251 "//": "PyNumber_InPlaceFloorDivide",
3254 def annotate(self, code):
3255 self.lhs.annotate(code)
3256 self.rhs.annotate(code)
3257 self.dup.annotate(code)
3260 class PrintStatNode(StatNode):
3263 # arg_tuple TupleNode
3264 # append_newline boolean
3266 child_attrs = ["arg_tuple"]
3268 def analyse_expressions(self, env):
3269 self.arg_tuple.analyse_expressions(env)
3270 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3271 self.arg_tuple.release_temp(env)
3272 env.use_utility_code(printing_utility_code)
3273 if len(self.arg_tuple.args) == 1 and self.append_newline:
3274 env.use_utility_code(printing_one_utility_code)
3277 gil_message = "Python print statement"
3279 def generate_execution_code(self, code):
3280 if len(self.arg_tuple.args) == 1 and self.append_newline:
3281 arg = self.arg_tuple.args[0]
3282 arg.generate_evaluation_code(code)
3285 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3287 code.error_goto(self.pos)))
3288 arg.generate_disposal_code(code)
3289 arg.free_temps(code)
3291 self.arg_tuple.generate_evaluation_code(code)
3293 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3294 self.arg_tuple.py_result(),
3295 self.append_newline,
3296 code.error_goto(self.pos)))
3297 self.arg_tuple.generate_disposal_code(code)
3298 self.arg_tuple.free_temps(code)
3300 def annotate(self, code):
3301 self.arg_tuple.annotate(code)
3304 class ExecStatNode(StatNode):
3309 child_attrs = ["args"]
3311 def analyse_expressions(self, env):
3312 for i, arg in enumerate(self.args):
3313 arg.analyse_expressions(env)
3314 arg = arg.coerce_to_pyobject(env)
3315 arg.release_temp(env)
3317 self.temp_result = env.allocate_temp_pyobject()
3318 env.release_temp(self.temp_result)
3319 env.use_utility_code(Builtin.pyexec_utility_code)
3322 gil_message = "Python exec statement"
3324 def generate_execution_code(self, code):
3326 for arg in self.args:
3327 arg.generate_evaluation_code(code)
3328 args.append( arg.py_result() )
3329 args = tuple(args + ['0', '0'][:3-len(args)])
3330 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3331 (self.temp_result,) + args))
3332 for arg in self.args:
3333 arg.generate_disposal_code(code)
3334 arg.free_temps(code)
3336 code.error_goto_if_null(self.temp_result, self.pos))
3337 code.put_gotref(self.temp_result)
3338 code.put_decref_clear(self.temp_result, py_object_type)
3340 def annotate(self, code):
3341 for arg in self.args:
3345 class DelStatNode(StatNode):
3350 child_attrs = ["args"]
3352 def analyse_declarations(self, env):
3353 for arg in self.args:
3354 arg.analyse_target_declaration(env)
3356 def analyse_expressions(self, env):
3357 for arg in self.args:
3358 arg.analyse_target_expression(env, None)
3359 if arg.type.is_pyobject:
3362 error(arg.pos, "Deletion of non-Python object")
3363 #arg.release_target_temp(env)
3365 gil_message = "Deleting Python object"
3367 def generate_execution_code(self, code):
3368 for arg in self.args:
3369 if arg.type.is_pyobject:
3370 arg.generate_deletion_code(code)
3371 # else error reported earlier
3373 def annotate(self, code):
3374 for arg in self.args:
3378 class PassStatNode(StatNode):
3383 def analyse_expressions(self, env):
3386 def generate_execution_code(self, code):
3390 class BreakStatNode(StatNode):
3394 def analyse_expressions(self, env):
3397 def generate_execution_code(self, code):
3398 if not code.break_label:
3399 error(self.pos, "break statement not inside loop")
3401 code.put_goto(code.break_label)
3404 class ContinueStatNode(StatNode):
3408 def analyse_expressions(self, env):
3411 def generate_execution_code(self, code):
3412 if code.funcstate.in_try_finally:
3413 error(self.pos, "continue statement inside try of try...finally")
3414 elif not code.continue_label:
3415 error(self.pos, "continue statement not inside loop")
3417 code.put_goto(code.continue_label)
3420 class ReturnStatNode(StatNode):
3423 # value ExprNode or None
3424 # return_type PyrexType
3425 # temps_in_use [Entry] Temps in use at time of return
3427 child_attrs = ["value"]
3429 def analyse_expressions(self, env):
3430 return_type = env.return_type
3431 self.return_type = return_type
3432 self.temps_in_use = env.temps_in_use()
3434 error(self.pos, "Return not inside a function body")
3437 self.value.analyse_types(env)
3438 if return_type.is_void or return_type.is_returncode:
3439 error(self.value.pos,
3440 "Return with value in void function")
3442 self.value = self.value.coerce_to(env.return_type, env)
3443 self.value.allocate_temps(env)
3444 self.value.release_temp(env)
3446 if (not return_type.is_void
3447 and not return_type.is_pyobject
3448 and not return_type.is_returncode):
3449 error(self.pos, "Return value required")
3450 if return_type.is_pyobject:
3453 gil_message = "Returning Python object"
3455 def generate_execution_code(self, code):
3456 code.mark_pos(self.pos)
3457 if not self.return_type:
3458 # error reported earlier
3460 if self.return_type.is_pyobject:
3461 code.put_xdecref(Naming.retval_cname,
3464 self.value.generate_evaluation_code(code)
3465 self.value.make_owned_reference(code)
3468 Naming.retval_cname,
3469 self.value.result_as(self.return_type)))
3470 self.value.generate_post_assignment_code(code)
3471 self.value.free_temps(code)
3473 if self.return_type.is_pyobject:
3474 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3475 elif self.return_type.is_returncode:
3478 Naming.retval_cname,
3479 self.return_type.default_value))
3480 # free temps the old way
3481 for entry in self.temps_in_use:
3482 code.put_var_decref_clear(entry)
3483 # free temps the new way
3484 for cname, type in code.funcstate.temps_holding_reference():
3485 code.put_decref_clear(cname, type)
3488 # code.return_label)
3489 code.put_goto(code.return_label)
3491 def annotate(self, code):
3493 self.value.annotate(code)
3496 class RaiseStatNode(StatNode):
3499 # exc_type ExprNode or None
3500 # exc_value ExprNode or None
3501 # exc_tb ExprNode or None
3503 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3505 def analyse_expressions(self, env):
3507 self.exc_type.analyse_types(env)
3508 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3509 self.exc_type.allocate_temps(env)
3511 self.exc_value.analyse_types(env)
3512 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3513 self.exc_value.allocate_temps(env)
3515 self.exc_tb.analyse_types(env)
3516 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3517 self.exc_tb.allocate_temps(env)
3519 self.exc_type.release_temp(env)
3521 self.exc_value.release_temp(env)
3523 self.exc_tb.release_temp(env)
3524 env.use_utility_code(raise_utility_code)
3525 env.use_utility_code(restore_exception_utility_code)
3528 gil_message = "Raising exception"
3530 def generate_execution_code(self, code):
3532 self.exc_type.generate_evaluation_code(code)
3533 type_code = self.exc_type.py_result()
3537 self.exc_value.generate_evaluation_code(code)
3538 value_code = self.exc_value.py_result()
3542 self.exc_tb.generate_evaluation_code(code)
3543 tb_code = self.exc_tb.py_result()
3546 if self.exc_type or self.exc_value or self.exc_tb:
3548 "__Pyx_Raise(%s, %s, %s);" % (
3555 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3557 obj.generate_disposal_code(code)
3558 obj.free_temps(code)
3560 code.error_goto(self.pos))
3562 def annotate(self, code):
3564 self.exc_type.annotate(code)
3566 self.exc_value.annotate(code)
3568 self.exc_tb.annotate(code)
3571 class ReraiseStatNode(StatNode):
3575 def analyse_expressions(self, env):
3577 env.use_utility_code(raise_utility_code)
3578 env.use_utility_code(restore_exception_utility_code)
3580 gil_message = "Raising exception"
3582 def generate_execution_code(self, code):
3583 vars = code.funcstate.exc_vars
3585 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3586 code.putln(code.error_goto(self.pos))
3588 error(self.pos, "Reraise not inside except clause")
3591 class AssertStatNode(StatNode):
3595 # value ExprNode or None
3597 child_attrs = ["cond", "value"]
3599 def analyse_expressions(self, env):
3600 self.cond = self.cond.analyse_boolean_expression(env)
3602 self.value.analyse_types(env)
3603 self.value = self.value.coerce_to_pyobject(env)
3604 self.value.allocate_temps(env)
3605 self.cond.release_temp(env)
3607 self.value.release_temp(env)
3609 #env.recycle_pending_temps() # TEMPORARY
3611 gil_message = "Raising exception"
3613 def generate_execution_code(self, code):
3614 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3615 self.cond.generate_evaluation_code(code)
3617 "if (unlikely(!%s)) {" %
3620 self.value.generate_evaluation_code(code)
3622 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3623 self.value.py_result())
3624 self.value.generate_disposal_code(code)
3625 self.value.free_temps(code)
3628 "PyErr_SetNone(PyExc_AssertionError);")
3630 code.error_goto(self.pos))
3633 self.cond.generate_disposal_code(code)
3634 self.cond.free_temps(code)
3635 code.putln("#endif")
3637 def annotate(self, code):
3638 self.cond.annotate(code)
3640 self.value.annotate(code)
3643 class IfStatNode(StatNode):
3646 # if_clauses [IfClauseNode]
3647 # else_clause StatNode or None
3649 child_attrs = ["if_clauses", "else_clause"]
3651 def analyse_control_flow(self, env):
3652 env.start_branching(self.pos)
3653 for if_clause in self.if_clauses:
3654 if_clause.analyse_control_flow(env)
3655 env.next_branch(if_clause.end_pos())
3656 if self.else_clause:
3657 self.else_clause.analyse_control_flow(env)
3658 env.finish_branching(self.end_pos())
3660 def analyse_declarations(self, env):
3661 for if_clause in self.if_clauses:
3662 if_clause.analyse_declarations(env)
3663 if self.else_clause:
3664 self.else_clause.analyse_declarations(env)
3666 def analyse_expressions(self, env):
3667 for if_clause in self.if_clauses:
3668 if_clause.analyse_expressions(env)
3669 if self.else_clause:
3670 self.else_clause.analyse_expressions(env)
3672 def generate_execution_code(self, code):
3673 code.mark_pos(self.pos)
3674 end_label = code.new_label()
3675 for if_clause in self.if_clauses:
3676 if_clause.generate_execution_code(code, end_label)
3677 if self.else_clause:
3678 code.putln("/*else*/ {")
3679 self.else_clause.generate_execution_code(code)
3681 code.put_label(end_label)
3683 def annotate(self, code):
3684 for if_clause in self.if_clauses:
3685 if_clause.annotate(code)
3686 if self.else_clause:
3687 self.else_clause.annotate(code)
3690 class IfClauseNode(Node):
3691 # if or elif clause in an if statement
3693 # condition ExprNode
3696 child_attrs = ["condition", "body"]
3698 def analyse_control_flow(self, env):
3699 self.body.analyse_control_flow(env)
3701 def analyse_declarations(self, env):
3702 self.condition.analyse_declarations(env)
3703 self.body.analyse_declarations(env)
3705 def analyse_expressions(self, env):
3707 self.condition.analyse_temp_boolean_expression(env)
3708 self.condition.release_temp(env)
3709 self.body.analyse_expressions(env)
3711 def generate_execution_code(self, code, end_label):
3712 self.condition.generate_evaluation_code(code)
3715 self.condition.result())
3716 self.condition.generate_disposal_code(code)
3717 self.condition.free_temps(code)
3718 self.body.generate_execution_code(code)
3722 code.put_goto(end_label)
3725 def annotate(self, code):
3726 self.condition.annotate(code)
3727 self.body.annotate(code)
3730 class SwitchCaseNode(StatNode):
3731 # Generated in the optimization of an if-elif-else node
3733 # conditions [ExprNode]
3736 child_attrs = ['conditions', 'body']
3738 def generate_execution_code(self, code):
3739 for cond in self.conditions:
3740 code.mark_pos(cond.pos)
3741 code.putln("case %s:" % cond.calculate_result_code())
3742 self.body.generate_execution_code(code)
3743 code.putln("break;")
3745 def annotate(self, code):
3746 for cond in self.conditions:
3748 self.body.annotate(code)
3750 class SwitchStatNode(StatNode):
3751 # Generated in the optimization of an if-elif-else node
3754 # cases [SwitchCaseNode]
3755 # else_clause StatNode or None
3757 child_attrs = ['test', 'cases', 'else_clause']
3759 def generate_execution_code(self, code):
3760 code.putln("switch (%s) {" % self.test.calculate_result_code())
3761 for case in self.cases:
3762 case.generate_execution_code(code)
3763 if self.else_clause is not None:
3764 code.putln("default:")
3765 self.else_clause.generate_execution_code(code)
3766 code.putln("break;")
3769 def annotate(self, code):
3770 self.test.annotate(code)
3771 for case in self.cases:
3773 if self.else_clause is not None:
3774 self.else_clause.annotate(code)
3776 class LoopNode(object):
3778 def analyse_control_flow(self, env):
3779 env.start_branching(self.pos)
3780 self.body.analyse_control_flow(env)
3781 env.next_branch(self.body.end_pos())
3782 if self.else_clause:
3783 self.else_clause.analyse_control_flow(env)
3784 env.finish_branching(self.end_pos())
3787 class WhileStatNode(LoopNode, StatNode):
3790 # condition ExprNode
3792 # else_clause StatNode
3794 child_attrs = ["condition", "body", "else_clause"]
3796 def analyse_declarations(self, env):
3797 self.body.analyse_declarations(env)
3798 if self.else_clause:
3799 self.else_clause.analyse_declarations(env)
3801 def analyse_expressions(self, env):
3803 self.condition.analyse_temp_boolean_expression(env)
3804 self.condition.release_temp(env)
3805 #env.recycle_pending_temps() # TEMPORARY
3806 self.body.analyse_expressions(env)
3807 if self.else_clause:
3808 self.else_clause.analyse_expressions(env)
3810 def generate_execution_code(self, code):
3811 old_loop_labels = code.new_loop_labels()
3814 self.condition.generate_evaluation_code(code)
3815 self.condition.generate_disposal_code(code)
3818 self.condition.result())
3819 self.condition.free_temps(code)
3820 self.body.generate_execution_code(code)
3821 code.put_label(code.continue_label)
3823 break_label = code.break_label
3824 code.set_loop_labels(old_loop_labels)
3825 if self.else_clause:
3826 code.putln("/*else*/ {")
3827 self.else_clause.generate_execution_code(code)
3829 code.put_label(break_label)
3831 def annotate(self, code):
3832 self.condition.annotate(code)
3833 self.body.annotate(code)
3834 if self.else_clause:
3835 self.else_clause.annotate(code)
3838 def ForStatNode(pos, **kw):
3839 if 'iterator' in kw:
3840 return ForInStatNode(pos, **kw)
3842 return ForFromStatNode(pos, **kw)
3844 class ForInStatNode(LoopNode, StatNode):
3848 # iterator IteratorNode
3850 # else_clause StatNode
3851 # item NextNode used internally
3853 child_attrs = ["target", "iterator", "body", "else_clause"]
3856 def analyse_declarations(self, env):
3857 self.target.analyse_target_declaration(env)
3858 self.body.analyse_declarations(env)
3859 if self.else_clause:
3860 self.else_clause.analyse_declarations(env)
3862 def analyse_expressions(self, env):
3864 self.target.analyse_target_types(env)
3865 self.iterator.analyse_expressions(env)
3866 self.item = ExprNodes.NextNode(self.iterator, env)
3867 self.item = self.item.coerce_to(self.target.type, env)
3868 self.item.allocate_temps(env)
3869 self.target.allocate_target_temps(env, self.item)
3870 #self.item.release_temp(env)
3871 #self.target.release_target_temp(env)
3872 self.body.analyse_expressions(env)
3873 if self.else_clause:
3874 self.else_clause.analyse_expressions(env)
3875 self.iterator.release_temp(env)
3877 def generate_execution_code(self, code):
3878 old_loop_labels = code.new_loop_labels()
3879 self.iterator.allocate_counter_temp(code)
3880 self.iterator.generate_evaluation_code(code)
3883 self.item.generate_evaluation_code(code)
3884 self.target.generate_assignment_code(self.item, code)
3885 self.body.generate_execution_code(code)
3886 code.put_label(code.continue_label)
3889 break_label = code.break_label
3890 code.set_loop_labels(old_loop_labels)
3891 if self.else_clause:
3892 code.putln("/*else*/ {")
3893 self.else_clause.generate_execution_code(code)
3895 code.put_label(break_label)
3896 self.iterator.release_counter_temp(code)
3897 self.iterator.generate_disposal_code(code)
3898 self.iterator.free_temps(code)
3900 def annotate(self, code):
3901 self.target.annotate(code)
3902 self.iterator.annotate(code)
3903 self.body.annotate(code)
3904 if self.else_clause:
3905 self.else_clause.annotate(code)
3906 self.item.annotate(code)
3909 class ForFromStatNode(LoopNode, StatNode):
3910 # for name from expr rel name rel expr
3917 # step ExprNode or None
3919 # else_clause StatNode or None
3925 # loopvar_node ExprNode (usually a NameNode or temp node)
3926 # py_loopvar_node PyTempNode or None
3927 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3929 is_py_target = False
3931 py_loopvar_node = None
3934 def analyse_declarations(self, env):
3935 self.target.analyse_target_declaration(env)
3936 self.body.analyse_declarations(env)
3937 if self.else_clause:
3938 self.else_clause.analyse_declarations(env)
3940 def analyse_expressions(self, env):
3942 self.target.analyse_target_types(env)
3943 self.bound1.analyse_types(env)
3944 self.bound2.analyse_types(env)
3945 if self.step is not None:
3946 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3947 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3948 self.step.analyse_types(env)
3950 target_type = self.target.type
3951 if self.target.type.is_numeric:
3952 loop_type = self.target.type
3954 loop_type = PyrexTypes.c_int_type
3955 if not self.bound1.type.is_pyobject:
3956 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3957 if not self.bound2.type.is_pyobject:
3958 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3959 if self.step is not None and not self.step.type.is_pyobject:
3960 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3961 self.bound1 = self.bound1.coerce_to(loop_type, env)
3962 self.bound2 = self.bound2.coerce_to(loop_type, env)
3963 if not self.bound2.is_literal:
3964 self.bound2 = self.bound2.coerce_to_temp(env)
3965 if self.step is not None:
3966 self.step = self.step.coerce_to(loop_type, env)
3967 if not self.step.is_literal:
3968 self.step = self.step.coerce_to_temp(env)
3970 target_type = self.target.type
3971 if not (target_type.is_pyobject or target_type.is_numeric):
3972 error(self.target.pos,
3973 "for-from loop variable must be c numeric type or Python object")
3974 if target_type.is_numeric:
3975 self.is_py_target = False
3976 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3977 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3978 self.loopvar_node = self.target
3979 self.py_loopvar_node = None
3981 self.is_py_target = True
3982 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3983 c_loopvar_node.allocate_temps(env)
3984 self.loopvar_node = c_loopvar_node
3985 self.py_loopvar_node = \
3986 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3987 self.bound1.allocate_temps(env)
3988 self.bound2.allocate_temps(env)
3989 if self.step is not None:
3990 self.step.allocate_temps(env)
3991 if self.is_py_target:
3992 self.py_loopvar_node.allocate_temps(env)
3993 self.target.allocate_target_temps(env, self.py_loopvar_node)
3994 #self.target.release_target_temp(env)
3995 #self.py_loopvar_node.release_temp(env)
3996 self.body.analyse_expressions(env)
3997 if self.is_py_target:
3998 c_loopvar_node.release_temp(env)
3999 if self.else_clause:
4000 self.else_clause.analyse_expressions(env)
4001 self.bound1.release_temp(env)
4002 self.bound2.release_temp(env)
4003 if self.step is not None:
4004 self.step.release_temp(env)
4006 def generate_execution_code(self, code):
4007 old_loop_labels = code.new_loop_labels()
4008 from_range = self.from_range
4009 self.bound1.generate_evaluation_code(code)
4010 self.bound2.generate_evaluation_code(code)
4011 offset, incop = self.relation_table[self.relation1]
4012 if self.step is not None:
4013 self.step.generate_evaluation_code(code)
4014 step = self.step.result()
4015 incop = "%s=%s" % (incop[0], step)
4017 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4019 loopvar_name = self.loopvar_node.result()
4021 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4023 self.bound1.result(), offset,
4024 loopvar_name, self.relation2, self.bound2.result(),
4025 loopvar_name, incop))
4026 if self.py_loopvar_node:
4027 self.py_loopvar_node.generate_evaluation_code(code)
4028 self.target.generate_assignment_code(self.py_loopvar_node, code)
4030 code.putln("%s = %s;" % (
4031 self.target.result(), loopvar_name))
4032 self.body.generate_execution_code(code)
4033 code.put_label(code.continue_label)
4034 if self.py_loopvar_node:
4035 # This mess is to make for..from loops with python targets behave
4036 # exactly like those with C targets with regards to re-assignment
4037 # of the loop variable.
4039 if self.target.entry.is_pyglobal:
4040 # We know target is a NameNode, this is the only ugly case.
4041 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4042 target_node.result_code = code.funcstate.allocate_temp(py_object_type, False)
4043 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4044 target_node.result_code,
4045 Naming.module_cname,
4046 self.target.entry.interned_cname,
4047 code.error_goto_if_null(target_node.result_code, self.target.pos)))
4048 code.put_gotref(target_node.result_code)
4050 target_node = self.target
4051 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4052 from_py_node.temp_code = loopvar_name
4053 from_py_node.generate_result_code(code)
4054 if self.target.entry.is_pyglobal:
4055 code.put_decref_clear(target_node.result_code, py_object_type)
4056 code.funcstate.release_temp(target_node.result_code)
4058 if self.py_loopvar_node:
4059 # This is potentially wasteful, but we don't want the semantics to
4060 # depend on whether or not the loop is a python type.
4061 self.py_loopvar_node.generate_evaluation_code(code)
4062 self.target.generate_assignment_code(self.py_loopvar_node, code)
4063 break_label = code.break_label
4064 code.set_loop_labels(old_loop_labels)
4065 if self.else_clause:
4066 code.putln("/*else*/ {")
4067 self.else_clause.generate_execution_code(code)
4069 code.put_label(break_label)
4070 self.bound1.generate_disposal_code(code)
4071 self.bound1.free_temps(code)
4072 self.bound2.generate_disposal_code(code)
4073 self.bound2.free_temps(code)
4074 if self.step is not None:
4075 self.step.generate_disposal_code(code)
4076 self.step.free_temps(code)
4078 code.funcstate.release_temp(loopvar_name)
4081 # {relop : (initial offset, increment op)}
4088 def annotate(self, code):
4089 self.target.annotate(code)
4090 self.bound1.annotate(code)
4091 self.bound2.annotate(code)
4093 self.bound2.annotate(code)
4094 self.body.annotate(code)
4095 if self.else_clause:
4096 self.else_clause.annotate(code)
4099 class WithStatNode(StatNode):
4101 Represents a Python with statement.
4103 This is only used at parse tree level; and is not present in
4104 analysis or generation phases.
4106 # manager The with statement manager object
4107 # target Node (lhs expression)
4109 child_attrs = ["manager", "target", "body"]
4111 class TryExceptStatNode(StatNode):
4112 # try .. except statement
4115 # except_clauses [ExceptClauseNode]
4116 # else_clause StatNode or None
4117 # cleanup_list [Entry] old style temps to clean up on error
4119 child_attrs = ["body", "except_clauses", "else_clause"]
4121 def analyse_control_flow(self, env):
4122 env.start_branching(self.pos)
4123 self.body.analyse_control_flow(env)
4124 successful_try = env.control_flow # grab this for later
4125 env.next_branch(self.body.end_pos())
4126 env.finish_branching(self.body.end_pos())
4128 env.start_branching(self.except_clauses[0].pos)
4129 for except_clause in self.except_clauses:
4130 except_clause.analyse_control_flow(env)
4131 env.next_branch(except_clause.end_pos())
4133 # the else cause it executed only when the try clause finishes
4134 env.control_flow.incoming = successful_try
4135 if self.else_clause:
4136 self.else_clause.analyse_control_flow(env)
4137 env.finish_branching(self.end_pos())
4139 def analyse_declarations(self, env):
4140 self.body.analyse_declarations(env)
4141 for except_clause in self.except_clauses:
4142 except_clause.analyse_declarations(env)
4143 if self.else_clause:
4144 self.else_clause.analyse_declarations(env)
4146 env.use_utility_code(reset_exception_utility_code)
4148 def analyse_expressions(self, env):
4149 self.body.analyse_expressions(env)
4150 self.cleanup_list = env.free_temp_entries[:]
4151 default_clause_seen = 0
4152 for except_clause in self.except_clauses:
4153 except_clause.analyse_expressions(env)
4154 if default_clause_seen:
4155 error(except_clause.pos, "default 'except:' must be last")
4156 if not except_clause.pattern:
4157 default_clause_seen = 1
4158 self.has_default_clause = default_clause_seen
4159 if self.else_clause:
4160 self.else_clause.analyse_expressions(env)
4163 gil_message = "Try-except statement"
4165 def generate_execution_code(self, code):
4166 old_return_label = code.return_label
4167 old_break_label = code.break_label
4168 old_continue_label = code.continue_label
4169 old_error_label = code.new_error_label()
4170 our_error_label = code.error_label
4171 except_end_label = code.new_label('exception_handled')
4172 except_error_label = code.new_label('except_error')
4173 except_return_label = code.new_label('except_return')
4174 try_return_label = code.new_label('try_return')
4175 try_break_label = code.new_label('try_break')
4176 try_continue_label = code.new_label('try_continue')
4177 try_end_label = code.new_label('try_end')
4180 code.putln("PyObject %s;" %
4181 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4182 code.putln("__Pyx_ExceptionSave(%s);" %
4183 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4184 for var in Naming.exc_save_vars:
4185 code.put_xgotref(var)
4188 code.return_label = try_return_label
4189 code.break_label = try_break_label
4190 code.continue_label = try_continue_label
4191 self.body.generate_execution_code(code)
4194 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4195 code.error_label = except_error_label
4196 code.return_label = except_return_label
4197 if self.else_clause:
4200 self.else_clause.generate_execution_code(code)
4203 for var in Naming.exc_save_vars:
4204 code.put_xdecref_clear(var, py_object_type)
4205 code.put_goto(try_end_label)
4206 if code.label_used(try_return_label):
4207 code.put_label(try_return_label)
4208 for var in Naming.exc_save_vars:
4209 code.put_xdecref_clear(var, py_object_type)
4210 code.put_goto(old_return_label)
4211 code.put_label(our_error_label)
4212 code.put_var_xdecrefs_clear(self.cleanup_list)
4213 for temp_name, type in temps_to_clean_up:
4214 code.put_xdecref_clear(temp_name, type)
4215 for except_clause in self.except_clauses:
4216 except_clause.generate_handling_code(code, except_end_label)
4218 error_label_used = code.label_used(except_error_label)
4219 if error_label_used or not self.has_default_clause:
4220 if error_label_used:
4221 code.put_label(except_error_label)
4222 for var in Naming.exc_save_vars:
4223 code.put_xdecref(var, py_object_type)
4224 code.put_goto(old_error_label)
4226 if code.label_used(try_break_label):
4227 code.put_label(try_break_label)
4228 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4229 code.putln("__Pyx_ExceptionReset(%s);" %
4230 ', '.join(Naming.exc_save_vars))
4231 code.put_goto(old_break_label)
4233 if code.label_used(try_continue_label):
4234 code.put_label(try_continue_label)
4235 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4236 code.putln("__Pyx_ExceptionReset(%s);" %
4237 ', '.join(Naming.exc_save_vars))
4238 code.put_goto(old_continue_label)
4240 if code.label_used(except_return_label):
4241 code.put_label(except_return_label)
4242 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4243 code.putln("__Pyx_ExceptionReset(%s);" %
4244 ', '.join(Naming.exc_save_vars))
4245 code.put_goto(old_return_label)
4247 if code.label_used(except_end_label):
4248 code.put_label(except_end_label)
4249 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4250 code.putln("__Pyx_ExceptionReset(%s);" %
4251 ', '.join(Naming.exc_save_vars))
4252 code.put_label(try_end_label)
4255 code.return_label = old_return_label
4256 code.break_label = old_break_label
4257 code.continue_label = old_continue_label
4258 code.error_label = old_error_label
4260 def annotate(self, code):
4261 self.body.annotate(code)
4262 for except_node in self.except_clauses:
4263 except_node.annotate(code)
4264 if self.else_clause:
4265 self.else_clause.annotate(code)
4268 class ExceptClauseNode(Node):
4269 # Part of try ... except statement.
4272 # target ExprNode or None
4274 # excinfo_target NameNode or None optional target for exception info
4275 # match_flag string result of exception match
4276 # exc_value ExcValueNode used internally
4277 # function_name string qualified name of enclosing function
4278 # exc_vars (string * 3) local exception variables
4280 # excinfo_target is never set by the parser, but can be set by a transform
4281 # in order to extract more extensive information about the exception as a
4282 # sys.exc_info()-style tuple into a target variable
4284 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4287 excinfo_target = None
4289 def analyse_declarations(self, env):
4291 self.target.analyse_target_declaration(env)
4292 if self.excinfo_target is not None:
4293 self.excinfo_target.analyse_target_declaration(env)
4294 self.body.analyse_declarations(env)
4296 def analyse_expressions(self, env):
4298 genv = env.global_scope()
4299 self.function_name = env.qualified_name
4301 self.pattern.analyse_expressions(env)
4302 self.pattern = self.pattern.coerce_to_pyobject(env)
4303 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4304 self.pattern.release_temp(env)
4305 env.release_temp(self.match_flag)
4307 if self.target or self.excinfo_target:
4308 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4310 self.exc_vars = None
4313 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4314 self.exc_value.allocate_temps(env)
4315 self.target.analyse_target_expression(env, self.exc_value)
4316 if self.excinfo_target is not None:
4318 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4319 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4320 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4321 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4323 self.excinfo_tuple.analyse_expressions(env)
4324 self.excinfo_tuple.allocate_temps(env)
4325 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4327 self.body.analyse_expressions(env)
4330 for var in self.exc_vars:
4331 env.release_temp(var)
4333 def generate_handling_code(self, code, end_label):
4334 code.mark_pos(self.pos)
4336 self.pattern.generate_evaluation_code(code)
4338 "%s = PyErr_ExceptionMatches(%s);" % (
4340 self.pattern.py_result()))
4341 self.pattern.generate_disposal_code(code)
4342 self.pattern.free_temps(code)
4347 code.putln("/*except:*/ {")
4350 exc_vars = self.exc_vars
4351 elif not getattr(self.body, 'stats', True):
4352 # most simple case: no exception variable, empty body (pass)
4353 # => reset the exception state, done
4354 code.putln("PyErr_Restore(0,0,0);")
4355 code.put_goto(end_label)
4359 # during type analysis, we didn't know if we need the
4360 # exception value, but apparently, we do
4361 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4365 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4366 # We always have to fetch the exception value even if
4367 # there is no target, because this also normalises the
4368 # exception and stores it in the thread state.
4369 code.globalstate.use_utility_code(get_exception_utility_code)
4370 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4371 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4372 code.error_goto(self.pos)))
4376 self.exc_value.generate_evaluation_code(code)
4377 self.target.generate_assignment_code(self.exc_value, code)
4378 if self.excinfo_target is not None:
4379 self.excinfo_tuple.generate_evaluation_code(code)
4380 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4383 old_break_label, old_continue_label = code.break_label, code.continue_label
4384 code.break_label = code.new_label('except_break')
4385 code.continue_label = code.new_label('except_continue')
4387 old_exc_vars = code.funcstate.exc_vars
4388 code.funcstate.exc_vars = exc_vars
4389 self.body.generate_execution_code(code)
4390 code.funcstate.exc_vars = old_exc_vars
4391 for var in exc_vars:
4392 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4393 code.put_goto(end_label)
4395 if code.label_used(code.break_label):
4396 code.put_label(code.break_label)
4397 for var in exc_vars:
4398 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4399 code.put_goto(old_break_label)
4400 code.break_label = old_break_label
4402 if code.label_used(code.continue_label):
4403 code.put_label(code.continue_label)
4404 for var in exc_vars:
4405 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4406 code.put_goto(old_continue_label)
4407 code.continue_label = old_continue_label
4409 if not self.exc_vars:
4410 # clean up locally allocated temps
4411 for temp in exc_vars:
4412 code.funcstate.release_temp(temp)
4417 def annotate(self, code):
4419 self.pattern.annotate(code)
4421 self.target.annotate(code)
4422 self.body.annotate(code)
4425 class TryFinallyStatNode(StatNode):
4426 # try ... finally statement
4429 # finally_clause StatNode
4431 # cleanup_list [Entry] old_style temps to clean up on error
4433 # The plan is that we funnel all continue, break
4434 # return and error gotos into the beginning of the
4435 # finally block, setting a variable to remember which
4436 # one we're doing. At the end of the finally block, we
4437 # switch on the variable to figure out where to go.
4438 # In addition, if we're doing an error, we save the
4439 # exception on entry to the finally block and restore
4442 child_attrs = ["body", "finally_clause"]
4444 preserve_exception = 1
4446 disallow_continue_in_try_finally = 0
4447 # There doesn't seem to be any point in disallowing
4448 # continue in the try block, since we have no problem
4451 def create_analysed(pos, env, body, finally_clause):
4452 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4453 node.cleanup_list = []
4455 create_analysed = staticmethod(create_analysed)
4457 def analyse_control_flow(self, env):
4458 env.start_branching(self.pos)
4459 self.body.analyse_control_flow(env)
4460 env.next_branch(self.body.end_pos())
4461 env.finish_branching(self.body.end_pos())
4462 self.finally_clause.analyse_control_flow(env)
4464 def analyse_declarations(self, env):
4465 self.body.analyse_declarations(env)
4466 self.finally_clause.analyse_declarations(env)
4468 def analyse_expressions(self, env):
4469 self.body.analyse_expressions(env)
4470 self.cleanup_list = env.free_temp_entries[:]
4471 self.finally_clause.analyse_expressions(env)
4474 gil_message = "Try-finally statement"
4476 def generate_execution_code(self, code):
4477 old_error_label = code.error_label
4478 old_labels = code.all_new_labels()
4479 new_labels = code.get_all_labels()
4480 new_error_label = code.error_label
4481 catch_label = code.new_label()
4484 if self.disallow_continue_in_try_finally:
4485 was_in_try_finally = code.funcstate.in_try_finally
4486 code.funcstate.in_try_finally = 1
4487 self.body.generate_execution_code(code)
4488 if self.disallow_continue_in_try_finally:
4489 code.funcstate.in_try_finally = was_in_try_finally
4492 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4496 error_label_used = 0
4497 for i, new_label in enumerate(new_labels):
4498 if new_label in code.labels_used:
4499 cases_used.append(i)
4500 if new_label == new_error_label:
4501 error_label_used = 1
4502 error_label_case = i
4506 if error_label_used and self.preserve_exception:
4508 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4510 "int %s;" % Naming.exc_lineno_name)
4511 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4512 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4513 code.putln(exc_var_init_zero)
4515 exc_var_init_zero = None
4516 code.use_label(catch_label)
4518 "__pyx_why = 0; goto %s;" % catch_label)
4519 for i in cases_used:
4520 new_label = new_labels[i]
4521 #if new_label and new_label != "<try>":
4522 if new_label == new_error_label and self.preserve_exception:
4523 self.put_error_catcher(code,
4524 new_error_label, i+1, catch_label, temps_to_clean_up)
4526 code.put('%s: ' % new_label)
4527 if exc_var_init_zero:
4528 code.putln(exc_var_init_zero)
4529 code.putln("__pyx_why = %s; goto %s;" % (
4532 code.put_label(catch_label)
4533 code.set_all_labels(old_labels)
4534 if error_label_used:
4535 code.new_error_label()
4536 finally_error_label = code.error_label
4537 self.finally_clause.generate_execution_code(code)
4538 if error_label_used:
4539 if finally_error_label in code.labels_used and self.preserve_exception:
4540 over_label = code.new_label()
4541 code.put_goto(over_label);
4542 code.put_label(finally_error_label)
4543 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4544 for var in Naming.exc_vars:
4545 code.putln("Py_XDECREF(%s);" % var)
4547 code.put_goto(old_error_label)
4548 code.put_label(over_label)
4549 code.error_label = old_error_label
4552 "switch (__pyx_why) {")
4553 for i in cases_used:
4554 old_label = old_labels[i]
4555 if old_label == old_error_label and self.preserve_exception:
4556 self.put_error_uncatcher(code, i+1, old_error_label)
4558 code.use_label(old_label)
4560 "case %s: goto %s;" % (
4568 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4569 code.globalstate.use_utility_code(restore_exception_utility_code)
4576 code.put_var_xdecrefs_clear(self.cleanup_list)
4577 for temp_name, type in temps_to_clean_up:
4578 code.put_xdecref_clear(temp_name, type)
4580 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4584 Naming.exc_lineno_name, Naming.lineno_cname))
4588 code.put_goto(catch_label)
4592 def put_error_uncatcher(self, code, i, error_label):
4593 code.globalstate.use_utility_code(restore_exception_utility_code)
4598 "__Pyx_ErrRestore(%s, %s, %s);" %
4602 Naming.lineno_cname, Naming.exc_lineno_name))
4603 for var in Naming.exc_vars:
4607 code.put_goto(error_label)
4611 def annotate(self, code):
4612 self.body.annotate(code)
4613 self.finally_clause.annotate(code)
4616 class GILStatNode(TryFinallyStatNode):
4617 # 'with gil' or 'with nogil' statement
4619 # state string 'gil' or 'nogil'
4623 preserve_exception = 0
4625 def __init__(self, pos, state, body):
4627 TryFinallyStatNode.__init__(self, pos,
4629 finally_clause = GILExitNode(pos, state = state))
4631 def analyse_expressions(self, env):
4632 env.use_utility_code(force_init_threads_utility_code)
4633 was_nogil = env.nogil
4635 TryFinallyStatNode.analyse_expressions(self, env)
4636 env.nogil = was_nogil
4638 def gil_check(self, env):
4641 def generate_execution_code(self, code):
4642 code.mark_pos(self.pos)
4643 if self.state == 'gil':
4644 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4646 code.putln("{ PyThreadState *_save;")
4647 code.putln("Py_UNBLOCK_THREADS")
4648 TryFinallyStatNode.generate_execution_code(self, code)
4652 class GILExitNode(StatNode):
4653 # Used as the 'finally' block in a GILStatNode
4655 # state string 'gil' or 'nogil'
4659 def analyse_expressions(self, env):
4662 def generate_execution_code(self, code):
4663 if self.state == 'gil':
4664 code.putln("PyGILState_Release();")
4666 code.putln("Py_BLOCK_THREADS")
4669 class CImportStatNode(StatNode):
4672 # module_name string Qualified name of module being imported
4673 # as_name string or None Name specified in "as" clause, if any
4677 def analyse_declarations(self, env):
4678 if not env.is_module_scope:
4679 error(self.pos, "cimport only allowed at module level")
4681 module_scope = env.find_module(self.module_name, self.pos)
4682 if "." in self.module_name:
4683 names = [EncodedString(name) for name in self.module_name.split(".")]
4685 top_module_scope = env.context.find_submodule(top_name)
4686 module_scope = top_module_scope
4687 for name in names[1:]:
4688 submodule_scope = module_scope.find_submodule(name)
4689 module_scope.declare_module(name, submodule_scope, self.pos)
4690 module_scope = submodule_scope
4692 env.declare_module(self.as_name, module_scope, self.pos)
4694 env.declare_module(top_name, top_module_scope, self.pos)
4696 name = self.as_name or self.module_name
4697 env.declare_module(name, module_scope, self.pos)
4699 def analyse_expressions(self, env):
4702 def generate_execution_code(self, code):
4706 class FromCImportStatNode(StatNode):
4707 # from ... cimport statement
4709 # module_name string Qualified name of module
4710 # imported_names [(pos, name, as_name, kind)] Names to be imported
4714 def analyse_declarations(self, env):
4715 if not env.is_module_scope:
4716 error(self.pos, "cimport only allowed at module level")
4718 module_scope = env.find_module(self.module_name, self.pos)
4719 env.add_imported_module(module_scope)
4720 for pos, name, as_name, kind in self.imported_names:
4722 for local_name, entry in module_scope.entries.items():
4723 env.add_imported_entry(local_name, entry, pos)
4725 entry = module_scope.lookup(name)
4727 if kind and not self.declaration_matches(entry, kind):
4728 entry.redeclared(pos)
4730 if kind == 'struct' or kind == 'union':
4731 entry = module_scope.declare_struct_or_union(name,
4732 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4733 elif kind == 'class':
4734 entry = module_scope.declare_c_class(name, pos = pos,
4735 module_name = self.module_name)
4737 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4738 if submodule_scope.parent_module is module_scope:
4739 env.declare_module(as_name or name, submodule_scope, self.pos)
4741 error(pos, "Name '%s' not declared in module '%s'"
4742 % (name, self.module_name))
4745 local_name = as_name or name
4746 env.add_imported_entry(local_name, entry, pos)
4748 def declaration_matches(self, entry, kind):
4749 if not entry.is_type:
4753 if not type.is_extension_type:
4756 if not type.is_struct_or_union:
4758 if kind != type.kind:
4762 def analyse_expressions(self, env):
4765 def generate_execution_code(self, code):
4769 class FromImportStatNode(StatNode):
4770 # from ... import statement
4773 # items [(string, NameNode)]
4774 # interned_items [(string, NameNode, ExprNode)]
4775 # item PyTempNode used internally
4776 # import_star boolean used internally
4778 child_attrs = ["module"]
4781 def analyse_declarations(self, env):
4782 for name, target in self.items:
4784 if not env.is_module_scope:
4785 error(self.pos, "import * only allowed at module level")
4787 env.has_import_star = 1
4788 self.import_star = 1
4790 target.analyse_target_declaration(env)
4792 def analyse_expressions(self, env):
4794 self.module.analyse_expressions(env)
4795 self.item = ExprNodes.PyTempNode(self.pos, env)
4796 self.item.allocate_temp(env)
4797 self.interned_items = []
4798 for name, target in self.items:
4800 for _, entry in env.entries.items():
4801 if not entry.is_type and entry.type.is_extension_type:
4802 env.use_utility_code(ExprNodes.type_test_utility_code)
4805 entry = env.lookup(target.name)
4806 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4807 continue # already cimported
4808 target.analyse_target_expression(env, None)
4809 if target.type is py_object_type:
4812 coerced_item = self.item.coerce_to(target.type, env)
4813 self.interned_items.append(
4814 (env.intern_identifier(name), target, coerced_item))
4815 #target.release_target_temp(env) # was release_temp ?!?
4816 self.module.release_temp(env)
4817 self.item.release_temp(env)
4819 def generate_execution_code(self, code):
4820 self.module.generate_evaluation_code(code)
4821 if self.import_star:
4823 'if (%s(%s) < 0) %s;' % (
4825 self.module.py_result(),
4826 code.error_goto(self.pos)))
4827 for cname, target, coerced_item in self.interned_items:
4829 '%s = PyObject_GetAttr(%s, %s); %s' % (
4831 self.module.py_result(),
4833 code.error_goto_if_null(self.item.result(), self.pos)))
4834 code.put_gotref(self.item.py_result())
4835 if coerced_item is None:
4836 target.generate_assignment_code(self.item, code)
4838 coerced_item.allocate_temp_result(code)
4839 coerced_item.generate_result_code(code)
4840 target.generate_assignment_code(coerced_item, code)
4841 if self.item.result() != coerced_item.result():
4842 code.put_decref_clear(self.item.result(), self.item.type)
4843 self.module.generate_disposal_code(code)
4844 self.module.free_temps(code)
4848 #------------------------------------------------------------------------------------
4850 # Runtime support code
4852 #------------------------------------------------------------------------------------
4854 utility_function_predeclarations = \
4857 #define INLINE __inline__
4859 #define INLINE __inline
4864 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4868 static int %(skip_dispatch_cname)s = 0;
4870 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4872 if Options.gcc_branch_hints:
4873 branch_prediction_macros = \
4876 /* Test for GCC > 2.95 */
4877 #if __GNUC__ > 2 || \
4878 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4879 #define likely(x) __builtin_expect(!!(x), 1)
4880 #define unlikely(x) __builtin_expect(!!(x), 0)
4881 #else /* __GNUC__ > 2 ... */
4882 #define likely(x) (x)
4883 #define unlikely(x) (x)
4884 #endif /* __GNUC__ > 2 ... */
4885 #else /* __GNUC__ */
4886 #define likely(x) (x)
4887 #define unlikely(x) (x)
4888 #endif /* __GNUC__ */
4891 branch_prediction_macros = \
4893 #define likely(x) (x)
4894 #define unlikely(x) (x)
4897 #get_name_predeclaration = \
4898 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4900 #get_name_interned_predeclaration = \
4901 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4903 #------------------------------------------------------------------------------------
4905 printing_utility_code = UtilityCode(
4907 static int __Pyx_Print(PyObject *, int); /*proto*/
4908 #if PY_MAJOR_VERSION >= 3
4909 static PyObject* %s = 0;
4910 static PyObject* %s = 0;
4912 """ % (Naming.print_function, Naming.print_function_kwargs),
4914 #if PY_MAJOR_VERSION < 3
4915 static PyObject *__Pyx_GetStdout(void) {
4916 PyObject *f = PySys_GetObject((char *)"stdout");
4918 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4923 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4928 if (!(f = __Pyx_GetStdout()))
4930 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4931 if (PyFile_SoftSpace(f, 1)) {
4932 if (PyFile_WriteString(" ", f) < 0)
4935 v = PyTuple_GET_ITEM(arg_tuple, i);
4936 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4938 if (PyString_Check(v)) {
4939 char *s = PyString_AsString(v);
4940 Py_ssize_t len = PyString_Size(v);
4942 isspace(Py_CHARMASK(s[len-1])) &&
4944 PyFile_SoftSpace(f, 0);
4948 if (PyFile_WriteString("\n", f) < 0)
4950 PyFile_SoftSpace(f, 0);
4955 #else /* Python 3 has a print function */
4957 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4958 PyObject* kwargs = 0;
4959 PyObject* result = 0;
4960 PyObject* end_string;
4961 if (!%(PRINT_FUNCTION)s) {
4962 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4963 if (!%(PRINT_FUNCTION)s)
4967 if (!%(PRINT_KWARGS)s) {
4968 %(PRINT_KWARGS)s = PyDict_New();
4969 if (!%(PRINT_KWARGS)s)
4971 end_string = PyUnicode_FromStringAndSize(" ", 1);
4974 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4975 Py_DECREF(end_string);
4978 Py_DECREF(end_string);
4980 kwargs = %(PRINT_KWARGS)s;
4982 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4990 """ % {'BUILTINS' : Naming.builtins_cname,
4991 'PRINT_FUNCTION' : Naming.print_function,
4992 'PRINT_KWARGS' : Naming.print_function_kwargs}
4996 printing_one_utility_code = UtilityCode(
4998 static int __Pyx_PrintOne(PyObject *o); /*proto*/
5001 #if PY_MAJOR_VERSION < 3
5003 static int __Pyx_PrintOne(PyObject *o) {
5005 if (!(f = __Pyx_GetStdout()))
5007 if (PyFile_SoftSpace(f, 0)) {
5008 if (PyFile_WriteString(" ", f) < 0)
5011 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5013 if (PyFile_WriteString("\n", f) < 0)
5016 /* the line below is just to avoid compiler
5017 * compiler warnings about unused functions */
5018 return __Pyx_Print(NULL, 0);
5021 #else /* Python 3 has a print function */
5023 static int __Pyx_PrintOne(PyObject *o) {
5025 PyObject* arg_tuple = PyTuple_New(1);
5026 if (unlikely(!arg_tuple))
5029 PyTuple_SET_ITEM(arg_tuple, 0, o);
5030 res = __Pyx_Print(arg_tuple, 1);
5031 Py_DECREF(arg_tuple);
5037 requires=[printing_utility_code])
5041 #------------------------------------------------------------------------------------
5043 # The following function is based on do_raise() from ceval.c.
5045 raise_utility_code = UtilityCode(
5047 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5050 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5054 /* First, check the traceback argument, replacing None with NULL. */
5055 if (tb == Py_None) {
5059 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5060 PyErr_SetString(PyExc_TypeError,
5061 "raise: arg 3 must be a traceback or None");
5064 /* Next, replace a missing value with None */
5065 if (value == NULL) {
5069 #if PY_VERSION_HEX < 0x02050000
5070 if (!PyClass_Check(type))
5072 if (!PyType_Check(type))
5075 /* Raising an instance. The value should be a dummy. */
5076 if (value != Py_None) {
5077 PyErr_SetString(PyExc_TypeError,
5078 "instance exception may not have a separate value");
5081 /* Normalize to raise <class>, <instance> */
5084 #if PY_VERSION_HEX < 0x02050000
5085 if (PyInstance_Check(type)) {
5086 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5091 PyErr_SetString(PyExc_TypeError,
5092 "raise: exception must be an old-style class or instance");
5096 type = (PyObject*) Py_TYPE(type);
5098 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5099 PyErr_SetString(PyExc_TypeError,
5100 "raise: exception class must be a subclass of BaseException");
5105 __Pyx_ErrRestore(type, value, tb);
5115 #------------------------------------------------------------------------------------
5117 reraise_utility_code = UtilityCode(
5119 static void __Pyx_ReRaise(void); /*proto*/
5122 static void __Pyx_ReRaise(void) {
5123 PyThreadState *tstate = PyThreadState_GET();
5124 PyObject* tmp_type = tstate->curexc_type;
5125 PyObject* tmp_value = tstate->curexc_value;
5126 PyObject* tmp_tb = tstate->curexc_traceback;
5127 tstate->curexc_type = tstate->exc_type;
5128 tstate->curexc_value = tstate->exc_value;
5129 tstate->curexc_traceback = tstate->exc_traceback;
5130 tstate->exc_type = 0;
5131 tstate->exc_value = 0;
5132 tstate->exc_traceback = 0;
5133 Py_XDECREF(tmp_type);
5134 Py_XDECREF(tmp_value);
5139 #------------------------------------------------------------------------------------
5141 arg_type_test_utility_code = UtilityCode(
5143 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5144 const char *name, int exact); /*proto*/
5147 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5148 const char *name, int exact)
5151 PyErr_Format(PyExc_SystemError, "Missing type object");
5154 if (none_allowed && obj == Py_None) return 1;
5156 if (Py_TYPE(obj) == type) return 1;
5159 if (PyObject_TypeCheck(obj, type)) return 1;
5161 PyErr_Format(PyExc_TypeError,
5162 "Argument '%s' has incorrect type (expected %s, got %s)",
5163 name, type->tp_name, Py_TYPE(obj)->tp_name);
5168 #------------------------------------------------------------------------------------
5170 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5171 # many or too few positional arguments were found. This handles
5172 # Py_ssize_t formatting correctly.
5174 raise_argtuple_invalid_utility_code = UtilityCode(
5176 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5177 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5180 static void __Pyx_RaiseArgtupleInvalid(
5181 const char* func_name,
5185 Py_ssize_t num_found)
5187 Py_ssize_t num_expected;
5188 const char *number, *more_or_less;
5190 if (num_found < num_min) {
5191 num_expected = num_min;
5192 more_or_less = "at least";
5194 num_expected = num_max;
5195 more_or_less = "at most";
5198 more_or_less = "exactly";
5200 number = (num_expected == 1) ? "" : "s";
5201 PyErr_Format(PyExc_TypeError,
5202 #if PY_VERSION_HEX < 0x02050000
5203 "%s() takes %s %d positional argument%s (%d given)",
5205 "%s() takes %s %zd positional argument%s (%zd given)",
5207 func_name, more_or_less, num_expected, number, num_found);
5211 raise_keyword_required_utility_code = UtilityCode(
5213 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5216 static INLINE void __Pyx_RaiseKeywordRequired(
5217 const char* func_name,
5220 PyErr_Format(PyExc_TypeError,
5221 #if PY_MAJOR_VERSION >= 3
5222 "%s() needs keyword-only argument %U", func_name, kw_name);
5224 "%s() needs keyword-only argument %s", func_name,
5225 PyString_AS_STRING(kw_name));
5230 raise_double_keywords_utility_code = UtilityCode(
5232 static void __Pyx_RaiseDoubleKeywordsError(
5233 const char* func_name, PyObject* kw_name); /*proto*/
5236 static void __Pyx_RaiseDoubleKeywordsError(
5237 const char* func_name,
5240 PyErr_Format(PyExc_TypeError,
5241 #if PY_MAJOR_VERSION >= 3
5242 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5244 "%s() got multiple values for keyword argument '%s'", func_name,
5245 PyString_AS_STRING(kw_name));
5250 #------------------------------------------------------------------------------------
5252 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5253 # were passed to a function, or if any keywords were passed to a
5254 # function that does not accept them.
5256 keyword_string_check_utility_code = UtilityCode(
5258 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5259 const char* function_name, int kw_allowed); /*proto*/
5262 static INLINE int __Pyx_CheckKeywordStrings(
5264 const char* function_name,
5269 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5270 #if PY_MAJOR_VERSION < 3
5271 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5273 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5275 goto invalid_keyword_type;
5277 if ((!kw_allowed) && unlikely(key))
5278 goto invalid_keyword;
5280 invalid_keyword_type:
5281 PyErr_Format(PyExc_TypeError,
5282 "%s() keywords must be strings", function_name);
5285 PyErr_Format(PyExc_TypeError,
5286 #if PY_MAJOR_VERSION < 3
5287 "%s() got an unexpected keyword argument '%s'",
5288 function_name, PyString_AsString(key));
5290 "%s() got an unexpected keyword argument '%U'",
5291 function_name, key);
5297 #------------------------------------------------------------------------------------
5299 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5300 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5301 # keywords will raise an invalid keyword error.
5303 # Three kinds of errors are checked: 1) non-string keywords, 2)
5304 # unexpected keywords and 3) overlap with positional arguments.
5306 # If num_posargs is greater 0, it denotes the number of positional
5307 # arguments that were passed and that must therefore not appear
5308 # amongst the keywords as well.
5310 # This method does not check for required keyword arguments.
5313 parse_keywords_utility_code = UtilityCode(
5315 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5316 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5317 const char* function_name); /*proto*/
5320 static int __Pyx_ParseOptionalKeywords(
5322 PyObject **argnames[],
5325 Py_ssize_t num_pos_args,
5326 const char* function_name)
5328 PyObject *key = 0, *value = 0;
5331 PyObject*** first_kw_arg = argnames + num_pos_args;
5333 while (PyDict_Next(kwds, &pos, &key, &value)) {
5334 name = first_kw_arg;
5335 while (*name && (**name != key)) name++;
5337 values[name-argnames] = value;
5339 #if PY_MAJOR_VERSION < 3
5340 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5342 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5344 goto invalid_keyword_type;
5346 for (name = first_kw_arg; *name; name++) {
5347 #if PY_MAJOR_VERSION >= 3
5348 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5349 PyUnicode_Compare(**name, key) == 0) break;
5351 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5352 _PyString_Eq(**name, key)) break;
5356 values[name-argnames] = value;
5358 /* unexpected keyword found */
5359 for (name=argnames; name != first_kw_arg; name++) {
5360 if (**name == key) goto arg_passed_twice;
5361 #if PY_MAJOR_VERSION >= 3
5362 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5363 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5365 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5366 _PyString_Eq(**name, key)) goto arg_passed_twice;
5370 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5372 goto invalid_keyword;
5380 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5382 invalid_keyword_type:
5383 PyErr_Format(PyExc_TypeError,
5384 "%s() keywords must be strings", function_name);
5387 PyErr_Format(PyExc_TypeError,
5388 #if PY_MAJOR_VERSION < 3
5389 "%s() got an unexpected keyword argument '%s'",
5390 function_name, PyString_AsString(key));
5392 "%s() got an unexpected keyword argument '%U'",
5393 function_name, key);
5400 #------------------------------------------------------------------------------------
5402 traceback_utility_code = UtilityCode(
5404 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5407 #include "compile.h"
5408 #include "frameobject.h"
5409 #include "traceback.h"
5411 static void __Pyx_AddTraceback(const char *funcname) {
5412 PyObject *py_srcfile = 0;
5413 PyObject *py_funcname = 0;
5414 PyObject *py_globals = 0;
5415 PyObject *empty_string = 0;
5416 PyCodeObject *py_code = 0;
5417 PyFrameObject *py_frame = 0;
5419 #if PY_MAJOR_VERSION < 3
5420 py_srcfile = PyString_FromString(%(FILENAME)s);
5422 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5424 if (!py_srcfile) goto bad;
5426 #if PY_MAJOR_VERSION < 3
5427 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5429 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5433 #if PY_MAJOR_VERSION < 3
5434 py_funcname = PyString_FromString(funcname);
5436 py_funcname = PyUnicode_FromString(funcname);
5439 if (!py_funcname) goto bad;
5440 py_globals = PyModule_GetDict(%(GLOBALS)s);
5441 if (!py_globals) goto bad;
5442 #if PY_MAJOR_VERSION < 3
5443 empty_string = PyString_FromStringAndSize("", 0);
5445 empty_string = PyBytes_FromStringAndSize("", 0);
5447 if (!empty_string) goto bad;
5448 py_code = PyCode_New(
5449 0, /*int argcount,*/
5450 #if PY_MAJOR_VERSION >= 3
5451 0, /*int kwonlyargcount,*/
5454 0, /*int stacksize,*/
5456 empty_string, /*PyObject *code,*/
5457 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5458 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5459 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5460 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5461 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5462 py_srcfile, /*PyObject *filename,*/
5463 py_funcname, /*PyObject *name,*/
5464 %(LINENO)s, /*int firstlineno,*/
5465 empty_string /*PyObject *lnotab*/
5467 if (!py_code) goto bad;
5468 py_frame = PyFrame_New(
5469 PyThreadState_GET(), /*PyThreadState *tstate,*/
5470 py_code, /*PyCodeObject *code,*/
5471 py_globals, /*PyObject *globals,*/
5472 0 /*PyObject *locals*/
5474 if (!py_frame) goto bad;
5475 py_frame->f_lineno = %(LINENO)s;
5476 PyTraceBack_Here(py_frame);
5478 Py_XDECREF(py_srcfile);
5479 Py_XDECREF(py_funcname);
5480 Py_XDECREF(empty_string);
5481 Py_XDECREF(py_code);
5482 Py_XDECREF(py_frame);
5485 'FILENAME': Naming.filename_cname,
5486 'LINENO': Naming.lineno_cname,
5487 'CFILENAME': Naming.cfilenm_cname,
5488 'CLINENO': Naming.clineno_cname,
5489 'GLOBALS': Naming.module_cname,
5490 'EMPTY_TUPLE' : Naming.empty_tuple,
5493 restore_exception_utility_code = UtilityCode(
5495 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5496 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5499 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5500 PyObject *tmp_type, *tmp_value, *tmp_tb;
5501 PyThreadState *tstate = PyThreadState_GET();
5503 #if PY_MAJOR_VERSION >= 3
5504 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5505 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5506 tmp_type = tstate->exc_type;
5507 tmp_value = tstate->exc_value;
5508 tmp_tb = tstate->exc_traceback;
5509 PyErr_NormalizeException(&type, &value, &tb);
5510 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5511 tstate->exc_type = 0;
5512 tstate->exc_value = 0;
5513 tstate->exc_traceback = 0;
5514 PyException_SetContext(value, tmp_value);
5515 Py_DECREF(tmp_type);
5520 tmp_type = tstate->curexc_type;
5521 tmp_value = tstate->curexc_value;
5522 tmp_tb = tstate->curexc_traceback;
5523 tstate->curexc_type = type;
5524 tstate->curexc_value = value;
5525 tstate->curexc_traceback = tb;
5526 Py_XDECREF(tmp_type);
5527 Py_XDECREF(tmp_value);
5531 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5532 PyThreadState *tstate = PyThreadState_GET();
5533 *type = tstate->curexc_type;
5534 *value = tstate->curexc_value;
5535 *tb = tstate->curexc_traceback;
5537 tstate->curexc_type = 0;
5538 tstate->curexc_value = 0;
5539 tstate->curexc_traceback = 0;
5544 #------------------------------------------------------------------------------------
5546 unraisable_exception_utility_code = UtilityCode(
5548 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5551 static void __Pyx_WriteUnraisable(const char *name) {
5552 PyObject *old_exc, *old_val, *old_tb;
5554 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5555 #if PY_MAJOR_VERSION < 3
5556 ctx = PyString_FromString(name);
5558 ctx = PyUnicode_FromString(name);
5560 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5562 PyErr_WriteUnraisable(Py_None);
5564 PyErr_WriteUnraisable(ctx);
5569 requires=[restore_exception_utility_code])
5571 #------------------------------------------------------------------------------------
5573 set_vtable_utility_code = UtilityCode(
5575 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5578 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5579 PyObject *pycobj = 0;
5582 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5585 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5598 #------------------------------------------------------------------------------------
5600 get_vtable_utility_code = UtilityCode(
5602 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5605 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5609 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5612 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5613 if (!*(void **)vtabptr)
5626 #------------------------------------------------------------------------------------
5628 init_string_tab_utility_code = UtilityCode(
5630 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5633 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5635 #if PY_MAJOR_VERSION < 3
5636 if (t->is_unicode && (!t->is_identifier)) {
5637 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5638 } else if (t->intern) {
5639 *t->p = PyString_InternFromString(t->s);
5641 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5643 #else /* Python 3+ has unicode identifiers */
5644 if (t->is_identifier || (t->is_unicode && t->intern)) {
5645 *t->p = PyUnicode_InternFromString(t->s);
5646 } else if (t->is_unicode) {
5647 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5649 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5660 #------------------------------------------------------------------------------------
5662 get_exception_utility_code = UtilityCode(
5664 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5667 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5668 PyObject *tmp_type, *tmp_value, *tmp_tb;
5669 PyThreadState *tstate = PyThreadState_GET();
5670 *type = tstate->curexc_type;
5671 *value = tstate->curexc_value;
5672 *tb = tstate->curexc_traceback;
5673 tstate->curexc_type = 0;
5674 tstate->curexc_value = 0;
5675 tstate->curexc_traceback = 0;
5676 PyErr_NormalizeException(type, value, tb);
5677 if (PyErr_Occurred())
5682 tmp_type = tstate->exc_type;
5683 tmp_value = tstate->exc_value;
5684 tmp_tb = tstate->exc_traceback;
5685 tstate->exc_type = *type;
5686 tstate->exc_value = *value;
5687 tstate->exc_traceback = *tb;
5688 /* Make sure tstate is in a consistent state when we XDECREF
5689 these objects (XDECREF may run arbitrary code). */
5690 Py_XDECREF(tmp_type);
5691 Py_XDECREF(tmp_value);
5703 #------------------------------------------------------------------------------------
5705 reset_exception_utility_code = UtilityCode(
5707 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5708 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5711 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5712 PyThreadState *tstate = PyThreadState_GET();
5713 *type = tstate->exc_type;
5714 *value = tstate->exc_value;
5715 *tb = tstate->exc_traceback;
5721 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5722 PyObject *tmp_type, *tmp_value, *tmp_tb;
5723 PyThreadState *tstate = PyThreadState_GET();
5724 tmp_type = tstate->exc_type;
5725 tmp_value = tstate->exc_value;
5726 tmp_tb = tstate->exc_traceback;
5727 tstate->exc_type = type;
5728 tstate->exc_value = value;
5729 tstate->exc_traceback = tb;
5730 Py_XDECREF(tmp_type);
5731 Py_XDECREF(tmp_value);
5736 #------------------------------------------------------------------------------------
5738 force_init_threads_utility_code = UtilityCode(
5740 #ifndef __PYX_FORCE_INIT_THREADS
5741 #if PY_VERSION_HEX < 0x02040200
5742 #define __PYX_FORCE_INIT_THREADS 1
5744 #define __PYX_FORCE_INIT_THREADS 0
5749 #------------------------------------------------------------------------------------