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
1007 def analyse_default_values(self, env):
1008 genv = env.global_scope()
1009 for arg in self.args:
1012 if not hasattr(arg, 'default_entry'):
1013 arg.default.analyse_types(env)
1014 arg.default = arg.default.coerce_to(arg.type, genv)
1015 if arg.default.is_literal:
1016 arg.default_entry = arg.default
1017 arg.default_result_code = arg.default.calculate_result_code()
1018 if arg.default.type != arg.type and not arg.type.is_int:
1019 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
1021 arg.default.allocate_temps(genv)
1022 arg.default_entry = genv.add_default_value(arg.type)
1023 if arg.type.is_pyobject:
1024 arg.default_entry.init = 0
1025 arg.default_entry.used = 1
1026 arg.default_result_code = arg.default_entry.cname
1029 "This argument cannot have a default value")
1032 def need_gil_acquisition(self, lenv):
1035 def create_local_scope(self, env):
1037 while env.is_py_class_scope or env.is_c_class_scope:
1038 env = env.outer_scope
1039 if self.needs_closure:
1040 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1042 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1043 lenv.return_type = self.return_type
1044 type = self.entry.type
1045 if type.is_cfunction:
1046 lenv.nogil = type.nogil and not type.with_gil
1047 self.local_scope = lenv
1048 lenv.directives = env.directives
1051 def generate_function_definitions(self, env, code):
1054 lenv = self.local_scope
1056 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1057 self.entry.scope.is_c_class_scope)
1059 if code.globalstate.directives['profile'] is None:
1060 profile = 'inline' not in self.modifiers
1062 profile = code.globalstate.directives['profile']
1063 if profile and lenv.nogil:
1064 error(self.pos, "Cannot profile nogil function.")
1066 code.globalstate.use_utility_code(trace_utility_code)
1068 # Generate C code for header and body of function
1069 code.enter_cfunc_scope()
1070 code.return_from_error_cleanup_label = code.new_label()
1072 # ----- Top-level constants used by this function
1073 code.mark_pos(self.pos)
1074 self.generate_interned_num_decls(lenv, code)
1075 self.generate_interned_string_decls(lenv, code)
1076 self.generate_py_string_decls(lenv, code)
1077 self.generate_cached_builtins_decls(lenv, code)
1079 #code.put_var_declarations(lenv.const_entries, static = 1)
1080 self.generate_const_definitions(lenv, code)
1081 # ----- Function header
1084 self.py_func.generate_function_header(code,
1085 with_pymethdef = env.is_py_class_scope,
1087 self.generate_function_header(code,
1088 with_pymethdef = env.is_py_class_scope)
1089 # ----- Local variable declarations
1090 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1091 self.generate_argument_declarations(lenv, code)
1092 if self.needs_closure:
1093 code.putln("/* TODO: declare and create scope object */")
1094 code.put_var_declarations(lenv.var_entries)
1096 if not self.return_type.is_void:
1097 if self.return_type.is_pyobject:
1101 (self.return_type.declaration_code(
1102 Naming.retval_cname),
1104 tempvardecl_code = code.insertion_point()
1105 self.generate_keyword_list(code)
1106 # ----- Extern library function declarations
1107 lenv.generate_library_function_declarations(code)
1108 # ----- GIL acquisition
1109 acquire_gil = self.need_gil_acquisition(lenv)
1111 env.use_utility_code(force_init_threads_utility_code)
1112 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1113 # ----- Automatic lead-ins for certain special functions
1115 code.put_trace_call(self.entry.name, self.pos)
1117 code.put_setup_refcount_context(self.entry.name)
1118 if is_getbuffer_slot:
1119 self.getbuffer_init(code)
1120 # ----- Fetch arguments
1121 self.generate_argument_parsing_code(env, code)
1122 # If an argument is assigned to in the body, we must
1123 # incref it to properly keep track of refcounts.
1124 for entry in lenv.arg_entries:
1125 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1126 code.put_var_incref(entry)
1127 # ----- Initialise local variables
1128 for entry in lenv.var_entries:
1129 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1130 code.put_init_var_to_py_none(entry)
1131 # ----- Initialise local buffer auxiliary variables
1132 for entry in lenv.var_entries + lenv.arg_entries:
1133 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1134 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1135 # ----- Check and convert arguments
1136 self.generate_argument_type_tests(code)
1137 # ----- Acquire buffer arguments
1138 for entry in lenv.arg_entries:
1139 if entry.type.is_buffer:
1140 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1141 # ----- Function body
1142 self.body.generate_execution_code(code)
1143 # ----- Default return value
1145 if self.return_type.is_pyobject:
1146 #if self.return_type.is_extension_type:
1147 # lhs = "(PyObject *)%s" % Naming.retval_cname
1149 lhs = Naming.retval_cname
1150 code.put_init_to_py_none(lhs, self.return_type)
1152 val = self.return_type.default_value
1154 code.putln("%s = %s;" % (Naming.retval_cname, val))
1155 # ----- Error cleanup
1156 if code.error_label in code.labels_used:
1157 code.put_goto(code.return_label)
1158 code.put_label(code.error_label)
1159 # cleanup temps the old way
1160 code.put_var_xdecrefs(lenv.temp_entries)
1161 # cleanup temps the new way
1162 for cname, type in code.funcstate.all_managed_temps():
1163 code.put_xdecref(cname, type)
1165 # Clean up buffers -- this calls a Python function
1166 # so need to save and restore error state
1167 buffers_present = len(lenv.buffer_entries) > 0
1169 code.globalstate.use_utility_code(restore_exception_utility_code)
1170 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1171 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1172 for entry in lenv.buffer_entries:
1173 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1174 #code.putln("%s = 0;" % entry.cname)
1175 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1177 err_val = self.error_value()
1178 exc_check = self.caller_will_check_exceptions()
1179 if err_val is not None or exc_check:
1180 # TODO: Fix exception tracing (though currently unused by cProfile).
1181 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1182 # code.put_trace_exception()
1183 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1185 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1186 % self.entry.qualified_name, 0)
1188 '__Pyx_WriteUnraisable("%s");' %
1189 self.entry.qualified_name)
1190 env.use_utility_code(unraisable_exception_utility_code)
1191 env.use_utility_code(restore_exception_utility_code)
1192 default_retval = self.return_type.default_value
1193 if err_val is None and default_retval:
1194 err_val = default_retval
1195 if err_val is not None:
1198 Naming.retval_cname,
1201 if is_getbuffer_slot:
1202 self.getbuffer_error_cleanup(code)
1204 # If we are using the non-error cleanup section we should
1205 # jump past it if we have an error. The if-test below determine
1206 # whether this section is used.
1207 if buffers_present or is_getbuffer_slot:
1208 code.put_goto(code.return_from_error_cleanup_label)
1211 # ----- Non-error return cleanup
1212 code.put_label(code.return_label)
1213 for entry in lenv.buffer_entries:
1215 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1216 if is_getbuffer_slot:
1217 self.getbuffer_normal_cleanup(code)
1218 # ----- Return cleanup for both error and no-error return
1219 code.put_label(code.return_from_error_cleanup_label)
1220 if not Options.init_local_none:
1221 for entry in lenv.var_entries:
1222 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1223 entry.xdecref_cleanup = 1
1224 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1225 # Decref any increfed args
1226 for entry in lenv.arg_entries:
1227 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1228 code.put_var_decref(entry)
1230 # code.putln("/* TODO: decref scope object */")
1232 # This code is duplicated in ModuleNode.generate_module_init_func
1234 default_retval = self.return_type.default_value
1235 err_val = self.error_value()
1236 if err_val is None and default_retval:
1237 err_val = default_retval
1238 if self.return_type.is_pyobject:
1239 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1241 code.put_finish_refcount_context()
1243 if self.entry.is_special and self.entry.name == "__hash__":
1244 # Returning -1 for __hash__ is supposed to signal an error
1245 # We do as Python instances and coerce -1 into -2.
1246 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
1249 if self.return_type.is_pyobject:
1250 code.put_trace_return(Naming.retval_cname)
1252 code.put_trace_return("Py_None")
1255 code.putln("PyGILState_Release(_save);")
1257 if not self.return_type.is_void:
1258 code.putln("return %s;" % Naming.retval_cname)
1261 # ----- Go back and insert temp variable declarations
1262 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1263 tempvardecl_code.put_temp_declarations(code.funcstate)
1264 # ----- Python version
1265 code.exit_cfunc_scope()
1267 self.py_func.generate_function_definitions(env, code)
1268 self.generate_wrapper_functions(code)
1270 def declare_argument(self, env, arg):
1271 if arg.type.is_void:
1272 error(arg.pos, "Invalid use of 'void'")
1273 elif not arg.type.is_complete() and not arg.type.is_array:
1275 "Argument type '%s' is incomplete" % arg.type)
1276 return env.declare_arg(arg.name, arg.type, arg.pos)
1278 def generate_wrapper_functions(self, code):
1281 def generate_execution_code(self, code):
1282 # Evaluate and store argument default values
1283 for arg in self.args:
1284 default = arg.default
1286 if not default.is_literal:
1287 default.generate_evaluation_code(code)
1288 default.make_owned_reference(code)
1291 arg.default_entry.cname,
1292 default.result_as(arg.default_entry.type)))
1293 if default.is_temp and default.type.is_pyobject:
1294 code.putln("%s = 0;" % default.result())
1295 default.free_temps(code)
1296 code.put_var_giveref(arg.default_entry)
1297 # For Python class methods, create and store function object
1299 self.assmt.generate_execution_code(code)
1302 # Special code for the __getbuffer__ function
1304 def getbuffer_init(self, code):
1305 info = self.local_scope.arg_entries[1].cname
1306 # Python 3.0 betas have a bug in memoryview which makes it call
1307 # getbuffer with a NULL parameter. For now we work around this;
1308 # the following line should be removed when this bug is fixed.
1309 code.putln("if (%s == NULL) return 0;" % info)
1310 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1311 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1313 def getbuffer_error_cleanup(self, code):
1314 info = self.local_scope.arg_entries[1].cname
1315 code.put_gotref("%s->obj" % info)
1316 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1319 def getbuffer_normal_cleanup(self, code):
1320 info = self.local_scope.arg_entries[1].cname
1321 code.putln("if (%s->obj == Py_None) {" % info)
1322 code.put_gotref("Py_None")
1323 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1326 class CFuncDefNode(FuncDefNode):
1327 # C function definition.
1329 # modifiers ['inline']
1330 # visibility 'private' or 'public' or 'extern'
1331 # base_type CBaseTypeNode
1332 # declarator CDeclaratorNode
1335 # decorators [DecoratorNode] list of decorators
1337 # with_gil boolean Acquire GIL around body
1339 # py_func wrapper for calling from Python
1340 # overridable whether or not this is a cpdef function
1341 # inline_in_pxd whether this is an inline function in a pxd file
1343 child_attrs = ["base_type", "declarator", "body", "py_func"]
1345 inline_in_pxd = False
1347 directive_locals = {}
1349 def unqualified_name(self):
1350 return self.entry.name
1352 def analyse_declarations(self, env):
1353 self.directive_locals.update(env.directives['locals'])
1354 base_type = self.base_type.analyse(env)
1355 # The 2 here is because we need both function and argument names.
1356 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1357 if not type.is_cfunction:
1359 "Suite attached to non-function declaration")
1360 # Remember the actual type according to the function header
1361 # written here, because the type in the symbol table entry
1362 # may be different if we're overriding a C method inherited
1363 # from the base type of an extension type.
1365 type.is_overridable = self.overridable
1366 declarator = self.declarator
1367 while not hasattr(declarator, 'args'):
1368 declarator = declarator.base
1369 self.args = declarator.args
1370 for formal_arg, type_arg in zip(self.args, type.args):
1371 formal_arg.type = type_arg.type
1372 formal_arg.name = type_arg.name
1373 formal_arg.cname = type_arg.cname
1374 name = name_declarator.name
1375 cname = name_declarator.cname
1376 self.entry = env.declare_cfunction(
1377 name, type, self.pos,
1378 cname = cname, visibility = self.visibility,
1379 defining = self.body is not None,
1380 api = self.api, modifiers = self.modifiers)
1381 self.entry.inline_func_in_pxd = self.inline_in_pxd
1382 self.return_type = type.return_type
1384 if self.overridable and not env.is_module_scope:
1385 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1386 # An error will be produced in the cdef function
1387 self.overridable = False
1389 if self.overridable:
1391 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1392 self.py_func = DefNode(pos = self.pos,
1393 name = self.entry.name,
1396 starstar_arg = None,
1398 body = py_func_body,
1400 self.py_func.is_module_scope = env.is_module_scope
1401 self.py_func.analyse_declarations(env)
1402 self.entry.as_variable = self.py_func.entry
1403 # Reset scope entry the above cfunction
1404 env.entries[name] = self.entry
1405 self.py_func.interned_attr_cname = env.intern_identifier(
1406 self.py_func.entry.name)
1407 if not env.is_module_scope or Options.lookup_module_cpdef:
1408 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1409 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1411 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1413 args = self.type.args
1414 if omit_optional_args:
1415 args = args[:len(args) - self.type.optional_arg_count]
1416 arg_names = [arg.name for arg in args]
1418 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1420 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1421 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1422 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1423 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)
1424 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1426 def declare_arguments(self, env):
1427 for arg in self.type.args:
1429 error(arg.pos, "Missing argument name")
1430 self.declare_argument(env, arg)
1432 def need_gil_acquisition(self, lenv):
1434 with_gil = self.type.with_gil
1435 if type.nogil and not with_gil:
1436 if type.return_type.is_pyobject:
1438 "Function with Python return type cannot be declared nogil")
1439 for entry in lenv.var_entries + lenv.temp_entries:
1440 if entry.type.is_pyobject:
1441 error(self.pos, "Function declared nogil has Python locals or temporaries")
1444 def analyse_expressions(self, env):
1445 self.local_scope.directives = env.directives
1446 self.analyse_default_values(env)
1447 if self.py_func is not None:
1448 self.py_func.analyse_expressions(env)
1450 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1453 visibility = self.entry.visibility
1454 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1455 arg_decls.append(arg.declaration_code())
1456 if with_dispatch and self.overridable:
1457 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1458 if type.optional_arg_count and with_opt_args:
1459 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1460 if type.has_varargs:
1461 arg_decls.append("...")
1463 arg_decls = ["void"]
1465 cname = self.entry.func_cname
1466 entity = type.function_header_code(cname, ', '.join(arg_decls))
1467 if visibility == 'public':
1468 dll_linkage = "DL_EXPORT"
1471 header = self.return_type.declaration_code(entity,
1472 dll_linkage = dll_linkage)
1473 if visibility == 'extern':
1474 storage_class = "%s " % Naming.extern_c_macro
1475 elif visibility == 'public':
1478 storage_class = "static "
1479 code.putln("%s%s %s {" % (
1481 ' '.join(self.modifiers).upper(), # macro forms
1484 def generate_argument_declarations(self, env, code):
1485 for arg in self.args:
1487 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1489 def generate_keyword_list(self, code):
1492 def generate_argument_parsing_code(self, env, code):
1494 if self.type.optional_arg_count:
1495 code.putln('if (%s) {' % Naming.optional_args_cname)
1496 for arg in self.args:
1498 # FIXME: simple name prefixing doesn't work when
1499 # argument name mangling is in place
1500 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1501 declarator = arg.declarator
1502 while not hasattr(declarator, 'name'):
1503 declarator = declarator.base
1504 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1506 for _ in range(self.type.optional_arg_count):
1510 def generate_argument_conversion_code(self, code):
1513 def generate_argument_type_tests(self, code):
1514 # Generate type tests for args whose type in a parent
1515 # class is a supertype of the declared type.
1516 for arg in self.type.args:
1517 if arg.needs_type_test:
1518 self.generate_arg_type_test(arg, code)
1520 def generate_arg_type_test(self, arg, code):
1521 # Generate type test for one argument.
1522 if arg.type.typeobj_is_available():
1523 typeptr_cname = arg.type.typeptr_cname
1524 arg_code = "((PyObject *)%s)" % arg.cname
1526 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1531 type.is_builtin_type,
1532 code.error_goto(arg.pos)))
1534 error(arg.pos, "Cannot test type of extern C class "
1535 "without type object name specification")
1537 def error_value(self):
1538 if self.return_type.is_pyobject:
1542 return self.entry.type.exception_value
1544 def caller_will_check_exceptions(self):
1545 return self.entry.type.exception_check
1547 def generate_wrapper_functions(self, code):
1548 # If the C signature of a function has changed, we need to generate
1549 # wrappers to put in the slots here.
1552 func_type = entry.type
1553 while entry.prev_entry is not None:
1555 entry = entry.prev_entry
1556 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1558 self.generate_function_header(code,
1560 with_dispatch = entry.type.is_overridable,
1561 with_opt_args = entry.type.optional_arg_count,
1562 cname = entry.func_cname)
1563 if not self.return_type.is_void:
1565 args = self.type.args
1566 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1567 if entry.type.is_overridable:
1568 arglist.append(Naming.skip_dispatch_cname)
1569 elif func_type.is_overridable:
1571 if entry.type.optional_arg_count:
1572 arglist.append(Naming.optional_args_cname)
1573 elif func_type.optional_arg_count:
1574 arglist.append('NULL')
1575 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1579 class PyArgDeclNode(Node):
1580 # Argument which must be a Python object (used
1581 # for * and ** arguments).
1584 # entry Symtab.Entry
1588 class DecoratorNode(Node):
1591 # decorator NameNode or CallNode
1592 child_attrs = ['decorator']
1595 class DefNode(FuncDefNode):
1596 # A Python function definition.
1598 # name string the Python name of the function
1599 # decorators [DecoratorNode] list of decorators
1600 # args [CArgDeclNode] formal arguments
1601 # star_arg PyArgDeclNode or None * argument
1602 # starstar_arg PyArgDeclNode or None ** argument
1603 # doc EncodedString or None
1606 # The following subnode is constructed internally
1607 # when the def statement is inside a Python class definition.
1609 # assmt AssignmentNode Function construction/assignment
1611 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1615 num_required_kw_args = 0
1616 reqd_kw_flags_cname = "0"
1622 def __init__(self, pos, **kwds):
1623 FuncDefNode.__init__(self, pos, **kwds)
1625 for arg in self.args:
1632 self.num_kwonly_args = k
1633 self.num_required_kw_args = rk
1634 self.num_required_args = r
1636 def as_cfunction(self, cfunc=None, scope=None):
1638 error(self.star_arg.pos, "cdef function cannot have star argument")
1639 if self.starstar_arg:
1640 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1643 for formal_arg in self.args:
1644 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1645 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1647 type = py_object_type,
1648 pos = formal_arg.pos))
1649 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1651 has_varargs = False,
1652 exception_value = None,
1653 exception_check = False,
1656 is_overridable = True)
1657 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1659 cfunc_type = cfunc.type
1660 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1661 error(self.pos, "wrong number of arguments")
1662 error(declarator.pos, "previous declaration here")
1663 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1664 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1665 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1666 formal_arg.type = type_arg.type
1667 formal_arg.name_declarator = name_declarator
1669 if cfunc_type.exception_value is None:
1670 exception_value = None
1672 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1673 declarator = CFuncDeclaratorNode(self.pos,
1674 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1676 has_varargs = False,
1677 exception_check = cfunc_type.exception_check,
1678 exception_value = exception_value,
1679 with_gil = cfunc_type.with_gil,
1680 nogil = cfunc_type.nogil)
1681 return CFuncDefNode(self.pos,
1683 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1684 declarator = declarator,
1687 overridable = cfunc_type.is_overridable,
1689 with_gil = cfunc_type.with_gil,
1690 nogil = cfunc_type.nogil,
1691 visibility = 'private',
1693 directive_locals = getattr(cfunc, 'directive_locals', {}))
1695 def analyse_declarations(self, env):
1696 directive_locals = self.directive_locals = env.directives['locals']
1697 for arg in self.args:
1698 if hasattr(arg, 'name'):
1700 name_declarator = None
1702 base_type = arg.base_type.analyse(env)
1703 name_declarator, type = \
1704 arg.declarator.analyse(base_type, env)
1705 arg.name = name_declarator.name
1706 if arg.name in directive_locals:
1707 type_node = directive_locals[arg.name]
1708 other_type = type_node.analyse_as_type(env)
1709 if other_type is None:
1710 error(type_node.pos, "Not a type")
1711 elif (type is not PyrexTypes.py_object_type
1712 and not type.same_as(other_type)):
1713 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1714 error(type_node.pos, "Previous declaration here")
1717 if name_declarator and name_declarator.cname:
1719 "Python function argument cannot have C name specification")
1720 arg.type = type.as_argument_type()
1722 arg.needs_conversion = 0
1723 arg.needs_type_test = 0
1725 if arg.not_none and not arg.type.is_extension_type:
1727 "Only extension type arguments can have 'not None'")
1728 self.declare_pyfunction(env)
1729 self.analyse_signature(env)
1730 self.return_type = self.entry.signature.return_type()
1732 def analyse_signature(self, env):
1733 any_type_tests_needed = 0
1734 if self.entry.is_special:
1735 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1736 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1737 # Use the simpler calling signature for zero- and one-argument functions.
1738 if self.entry.signature is TypeSlots.pyfunction_signature:
1739 if len(self.args) == 0:
1740 self.entry.signature = TypeSlots.pyfunction_noargs
1741 elif len(self.args) == 1:
1742 if self.args[0].default is None and not self.args[0].kw_only:
1743 self.entry.signature = TypeSlots.pyfunction_onearg
1744 elif self.entry.signature is TypeSlots.pymethod_signature:
1745 if len(self.args) == 1:
1746 self.entry.signature = TypeSlots.unaryfunc
1747 elif len(self.args) == 2:
1748 if self.args[1].default is None and not self.args[1].kw_only:
1749 self.entry.signature = TypeSlots.ibinaryfunc
1750 sig = self.entry.signature
1751 nfixed = sig.num_fixed_args()
1752 for i in range(nfixed):
1753 if i < len(self.args):
1756 if sig.is_self_arg(i):
1758 arg.hdr_type = arg.type = env.parent_type
1759 arg.needs_conversion = 0
1761 arg.hdr_type = sig.fixed_arg_type(i)
1762 if not arg.type.same_as(arg.hdr_type):
1763 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1764 arg.needs_type_test = 1
1765 any_type_tests_needed = 1
1767 arg.needs_conversion = 1
1768 if arg.needs_conversion:
1769 arg.hdr_cname = Naming.arg_prefix + arg.name
1771 arg.hdr_cname = Naming.var_prefix + arg.name
1773 self.bad_signature()
1775 if nfixed < len(self.args):
1776 if not sig.has_generic_args:
1777 self.bad_signature()
1778 for arg in self.args:
1779 if arg.is_generic and \
1780 (arg.type.is_extension_type or arg.type.is_builtin_type):
1781 arg.needs_type_test = 1
1782 any_type_tests_needed = 1
1783 if any_type_tests_needed:
1784 env.use_utility_code(arg_type_test_utility_code)
1786 def bad_signature(self):
1787 sig = self.entry.signature
1788 expected_str = "%d" % sig.num_fixed_args()
1789 if sig.has_generic_args:
1790 expected_str = expected_str + " or more"
1792 if name.startswith("__") and name.endswith("__"):
1793 desc = "Special method"
1797 "%s %s has wrong number of arguments "
1798 "(%d declared, %s expected)" % (
1799 desc, self.name, len(self.args), expected_str))
1801 def signature_has_nongeneric_args(self):
1802 argcount = len(self.args)
1803 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1807 def signature_has_generic_args(self):
1808 return self.entry.signature.has_generic_args
1810 def declare_pyfunction(self, env):
1811 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1813 entry = env.lookup_here(self.name)
1814 if entry and entry.type.is_cfunction and not self.is_wrapper:
1815 warning(self.pos, "Overriding cdef method with def method.", 5)
1816 entry = env.declare_pyfunction(self.name, self.pos)
1818 prefix = env.scope_prefix
1819 entry.func_cname = \
1820 Naming.pyfunc_prefix + prefix + name
1821 entry.pymethdef_cname = \
1822 Naming.pymethdef_prefix + prefix + name
1823 if Options.docstrings:
1824 entry.doc = embed_position(self.pos, self.doc)
1826 Naming.funcdoc_prefix + prefix + name
1830 def declare_arguments(self, env):
1831 for arg in self.args:
1833 error(arg.pos, "Missing argument name")
1834 if arg.needs_conversion:
1835 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1836 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1837 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1838 if arg.type.is_pyobject:
1839 arg.entry.init = "0"
1840 arg.entry.init_to_none = 0
1842 arg.entry = self.declare_argument(env, arg)
1844 arg.entry.is_self_arg = arg.is_self_arg
1845 if not arg.is_self_arg:
1846 arg.name_entry = env.get_string_const(
1847 arg.name, identifier = True)
1848 env.add_py_string(arg.name_entry, identifier = True)
1850 if arg.is_self_arg or \
1851 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1852 arg.entry.is_declared_generic = 1
1853 self.declare_python_arg(env, self.star_arg)
1854 self.declare_python_arg(env, self.starstar_arg)
1856 def declare_python_arg(self, env, arg):
1858 entry = env.declare_var(arg.name,
1859 PyrexTypes.py_object_type, arg.pos)
1862 entry.init_to_none = 0
1863 entry.xdecref_cleanup = 1
1865 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1867 def analyse_expressions(self, env):
1868 self.local_scope.directives = env.directives
1869 self.analyse_default_values(env)
1870 if env.is_py_class_scope:
1871 self.synthesize_assignment_node(env)
1873 def synthesize_assignment_node(self, env):
1875 self.assmt = SingleAssignmentNode(self.pos,
1876 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1877 rhs = ExprNodes.UnboundMethodNode(self.pos,
1878 class_cname = env.class_obj_cname,
1879 function = ExprNodes.PyCFunctionNode(self.pos,
1880 pymethdef_cname = self.entry.pymethdef_cname)))
1881 self.assmt.analyse_declarations(env)
1882 self.assmt.analyse_expressions(env)
1884 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1886 sig = self.entry.signature
1887 if sig.has_dummy_arg:
1888 arg_code_list.append(
1889 "PyObject *%s" % Naming.self_cname)
1890 for arg in self.args:
1891 if not arg.is_generic:
1893 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1895 arg_code_list.append(
1896 arg.hdr_type.declaration_code(arg.hdr_cname))
1897 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1898 arg_code_list.append("PyObject *unused")
1899 if sig.has_generic_args:
1900 arg_code_list.append(
1901 "PyObject *%s, PyObject *%s"
1902 % (Naming.args_cname, Naming.kwds_cname))
1903 arg_code = ", ".join(arg_code_list)
1904 dc = self.return_type.declaration_code(self.entry.func_cname)
1905 header = "static %s(%s)" % (dc, arg_code)
1906 code.putln("%s; /*proto*/" % header)
1909 if self.entry.doc and Options.docstrings:
1910 docstr = self.entry.doc
1911 if not isinstance(docstr, str):
1912 docstr = docstr.utf8encode()
1914 'static char %s[] = "%s";' % (
1915 self.entry.doc_cname,
1916 split_docstring(escape_byte_string(docstr))))
1919 "static PyMethodDef %s = " %
1920 self.entry.pymethdef_cname)
1921 code.put_pymethoddef(self.entry, ";")
1922 code.putln("%s {" % header)
1924 def generate_argument_declarations(self, env, code):
1925 for arg in self.args:
1926 if arg.is_generic: # or arg.needs_conversion:
1927 if arg.needs_conversion:
1928 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1930 code.put_var_declaration(arg.entry)
1932 def generate_keyword_list(self, code):
1933 if self.signature_has_generic_args() and \
1934 self.signature_has_nongeneric_args():
1936 "static PyObject **%s[] = {" %
1937 Naming.pykwdlist_cname)
1938 for arg in self.args:
1940 code.put('&%s,' % arg.name_entry.pystring_cname)
1943 def generate_argument_parsing_code(self, env, code):
1944 # Generate PyArg_ParseTuple call for generic
1945 # arguments, if any.
1946 if self.entry.signature.has_dummy_arg:
1947 # get rid of unused argument warning
1948 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1950 old_error_label = code.new_error_label()
1951 our_error_label = code.error_label
1952 end_label = code.new_label("argument_unpacking_done")
1954 has_kwonly_args = self.num_kwonly_args > 0
1955 has_star_or_kw_args = self.star_arg is not None \
1956 or self.starstar_arg is not None or has_kwonly_args
1958 for arg in self.args:
1959 if not arg.type.is_pyobject and arg.type.from_py_function is None:
1960 arg.type.create_from_py_utility_code(env)
1962 if not self.signature_has_generic_args():
1963 if has_star_or_kw_args:
1964 error(self.pos, "This method cannot have * or keyword arguments")
1965 self.generate_argument_conversion_code(code)
1967 elif not self.signature_has_nongeneric_args():
1968 # func(*args) or func(**kw) or func(*args, **kw)
1969 self.generate_stararg_copy_code(code)
1972 positional_args = []
1975 for arg in self.args:
1976 arg_entry = arg.entry
1980 if not arg.is_self_arg:
1982 kw_only_args.append(arg)
1984 positional_args.append(arg)
1986 kw_only_args.append(arg)
1989 error(arg.pos, "Non-default argument following default argument")
1990 elif not arg.is_self_arg:
1991 positional_args.append(arg)
1993 self.generate_tuple_and_keyword_parsing_code(
1994 positional_args, kw_only_args, end_label, code)
1996 code.error_label = old_error_label
1997 if code.label_used(our_error_label):
1998 if not code.label_used(end_label):
1999 code.put_goto(end_label)
2000 code.put_label(our_error_label)
2001 if has_star_or_kw_args:
2002 self.generate_arg_decref(self.star_arg, code)
2003 if self.starstar_arg:
2004 if self.starstar_arg.entry.xdecref_cleanup:
2005 code.put_var_xdecref(self.starstar_arg.entry)
2007 code.put_var_decref(self.starstar_arg.entry)
2008 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2009 code.putln("return %s;" % self.error_value())
2010 if code.label_used(end_label):
2011 code.put_label(end_label)
2013 def generate_arg_assignment(self, arg, item, code):
2014 if arg.type.is_pyobject:
2016 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2017 code.putln("%s = %s;" % (arg.entry.cname, item))
2019 func = arg.type.from_py_function
2021 code.putln("%s = %s(%s); %s" % (
2025 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2027 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2029 def generate_arg_xdecref(self, arg, code):
2031 code.put_var_xdecref(arg.entry)
2033 def generate_arg_decref(self, arg, code):
2035 code.put_var_decref(arg.entry)
2037 def generate_stararg_copy_code(self, code):
2038 if not self.star_arg:
2039 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2040 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2042 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2043 self.name.utf8encode(), Naming.args_cname, self.error_value()))
2046 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2048 if self.starstar_arg:
2050 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2052 kwarg_check = "%s" % Naming.kwds_cname
2054 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2055 Naming.kwds_cname, Naming.kwds_cname)
2057 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2058 kwarg_check, Naming.kwds_cname, self.name,
2059 bool(self.starstar_arg), self.error_value()))
2061 if self.starstar_arg:
2062 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2063 self.starstar_arg.entry.cname,
2066 code.putln("if (unlikely(!%s)) return %s;" % (
2067 self.starstar_arg.entry.cname, self.error_value()))
2068 self.starstar_arg.entry.xdecref_cleanup = 0
2069 code.put_gotref(self.starstar_arg.entry.cname)
2073 code.put_incref(Naming.args_cname, py_object_type)
2074 code.putln("%s = %s;" % (
2075 self.star_arg.entry.cname,
2077 self.star_arg.entry.xdecref_cleanup = 0
2079 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2080 kw_only_args, success_label, code):
2081 argtuple_error_label = code.new_label("argtuple_error")
2083 min_positional_args = self.num_required_args - self.num_required_kw_args
2084 if len(self.args) > 0 and self.args[0].is_self_arg:
2085 min_positional_args -= 1
2086 max_positional_args = len(positional_args)
2087 has_fixed_positional_count = not self.star_arg and \
2088 min_positional_args == max_positional_args
2090 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2091 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2092 if self.num_required_kw_args:
2093 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2095 if self.starstar_arg or self.star_arg:
2096 self.generate_stararg_init_code(max_positional_args, code)
2098 # --- optimised code when we receive keyword arguments
2099 if self.num_required_kw_args:
2100 likely_hint = "likely"
2102 likely_hint = "unlikely"
2103 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2104 self.generate_keyword_unpacking_code(
2105 min_positional_args, max_positional_args,
2106 has_fixed_positional_count,
2107 positional_args, kw_only_args, argtuple_error_label, code)
2109 # --- optimised code when we do not receive any keyword arguments
2110 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2111 # Python raises arg tuple related errors first, so we must
2112 # check the length here
2113 if min_positional_args == max_positional_args and not self.star_arg:
2117 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2118 Naming.args_cname, compare, min_positional_args))
2119 code.put_goto(argtuple_error_label)
2121 if self.num_required_kw_args:
2122 # pure error case: keywords required but not passed
2123 if max_positional_args > min_positional_args and not self.star_arg:
2124 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2125 Naming.args_cname, max_positional_args))
2126 code.put_goto(argtuple_error_label)
2127 code.putln('} else {')
2128 for i, arg in enumerate(kw_only_args):
2130 # required keyword-only argument missing
2131 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2132 self.name.utf8encode(),
2133 arg.name_entry.pystring_cname))
2134 code.putln(code.error_goto(self.pos))
2137 elif min_positional_args == max_positional_args:
2138 # parse the exact number of positional arguments from the
2140 code.putln('} else {')
2141 for i, arg in enumerate(positional_args):
2142 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2143 self.generate_arg_assignment(arg, item, code)
2144 self.generate_arg_default_assignments(code)
2147 # parse the positional arguments from the variable length
2149 code.putln('} else {')
2150 self.generate_arg_default_assignments(code)
2151 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2153 code.putln('default:')
2154 reversed_args = list(enumerate(positional_args))[::-1]
2155 for i, arg in reversed_args:
2156 if i >= min_positional_args-1:
2157 if min_positional_args > 1:
2158 code.putln('case %2d:' % (i+1)) # pure code beautification
2160 code.put('case %2d: ' % (i+1))
2161 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2162 self.generate_arg_assignment(arg, item, code)
2163 if min_positional_args == 0:
2164 code.put('case 0: ')
2165 code.putln('break;')
2167 if min_positional_args:
2168 for i in range(min_positional_args-1, -1, -1):
2169 code.putln('case %2d:' % i)
2170 code.put_goto(argtuple_error_label)
2172 code.put('default: ')
2173 code.put_goto(argtuple_error_label)
2178 if code.label_used(argtuple_error_label):
2179 code.put_goto(success_label)
2180 code.put_label(argtuple_error_label)
2181 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2182 self.name.utf8encode(), has_fixed_positional_count,
2183 min_positional_args, max_positional_args,
2185 code.putln(code.error_goto(self.pos))
2187 def generate_arg_default_assignments(self, code):
2188 for arg in self.args:
2189 if arg.is_generic and arg.default:
2193 arg.default_result_code))
2195 def generate_stararg_init_code(self, max_positional_args, code):
2196 if self.starstar_arg:
2197 self.starstar_arg.entry.xdecref_cleanup = 0
2198 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2199 self.starstar_arg.entry.cname,
2200 self.starstar_arg.entry.cname,
2201 self.error_value()))
2202 code.put_gotref(self.starstar_arg.entry.cname)
2204 self.star_arg.entry.xdecref_cleanup = 0
2205 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2207 max_positional_args))
2208 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2209 self.star_arg.entry.cname, Naming.args_cname,
2210 max_positional_args, Naming.args_cname))
2211 code.put_gotref(self.star_arg.entry.cname)
2212 if self.starstar_arg:
2214 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2215 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2216 code.putln('return %s;' % self.error_value())
2219 code.putln("if (unlikely(!%s)) return %s;" % (
2220 self.star_arg.entry.cname, self.error_value()))
2221 code.putln('} else {')
2222 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2223 code.put_incref(Naming.empty_tuple, py_object_type)
2226 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2227 has_fixed_positional_count, positional_args,
2228 kw_only_args, argtuple_error_label, code):
2229 all_args = tuple(positional_args) + tuple(kw_only_args)
2230 max_args = len(all_args)
2233 for i, arg in enumerate(all_args):
2234 if arg.default and arg.type.is_pyobject:
2235 default_value = arg.default_result_code
2236 if arg.type is not PyrexTypes.py_object_type:
2237 default_value = "(PyObject*)"+default_value
2238 default_args.append((i, default_value))
2240 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2242 # it looks funny to separate the init-to-0 from setting the
2243 # default value, but C89 needs this
2244 code.putln("PyObject* values[%d] = {%s};" % (
2245 max_args, ','.join(['0']*max_args)))
2246 for i, default_value in default_args:
2247 code.putln('values[%d] = %s;' % (i, default_value))
2249 # parse the tuple and check that it's not too long
2250 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2252 code.putln('default:')
2253 for i in range(max_positional_args-1, -1, -1):
2254 code.put('case %2d: ' % (i+1))
2255 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2256 i, Naming.args_cname, i))
2257 code.putln('case 0: break;')
2258 if not self.star_arg:
2259 code.put('default: ') # more arguments than allowed
2260 code.put_goto(argtuple_error_label)
2263 # now fill up the positional/required arguments with values
2265 if self.num_required_args or max_positional_args > 0:
2266 last_required_arg = -1
2267 for i, arg in enumerate(all_args):
2269 last_required_arg = i
2270 if last_required_arg < max_positional_args:
2271 last_required_arg = max_positional_args-1
2272 num_required_args = self.num_required_args
2273 if max_positional_args > 0:
2274 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2275 for i, arg in enumerate(all_args[:last_required_arg+1]):
2276 if max_positional_args > 0 and i <= max_positional_args:
2277 if self.star_arg and i == max_positional_args:
2278 code.putln('default:')
2280 code.putln('case %2d:' % i)
2283 # handled separately below
2285 code.putln('if (kw_args > %d) {' % num_required_args)
2286 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2287 Naming.kwds_cname, arg.name_entry.pystring_cname))
2288 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2291 num_required_args -= 1
2292 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2293 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2294 code.putln('if (likely(values[%d])) kw_args--;' % i);
2295 if i < min_positional_args:
2297 # special case: we know arg 0 is missing
2299 code.put_goto(argtuple_error_label)
2301 # print the correct number of values (args or
2302 # kwargs) that were passed into positional
2303 # arguments up to this point
2304 code.putln('else {')
2305 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2306 self.name.utf8encode(), has_fixed_positional_count,
2307 min_positional_args, max_positional_args, i))
2308 code.putln(code.error_goto(self.pos))
2311 code.putln('else {')
2312 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2313 self.name.utf8encode(), arg.name_entry.pystring_cname))
2314 code.putln(code.error_goto(self.pos))
2316 if max_positional_args > 0:
2319 if kw_only_args and not self.starstar_arg:
2320 # unpack optional keyword-only arguments
2321 # checking for interned strings in a dict is faster than iterating
2322 # but it's too likely that we must iterate if we expect **kwargs
2324 for i, arg in enumerate(all_args[max_positional_args:]):
2325 if not arg.kw_only or not arg.default:
2327 optional_args.append((i+max_positional_args, arg))
2329 # this mimics an unrolled loop so that we can "break" out of it
2330 code.putln('while (kw_args > 0) {')
2331 code.putln('PyObject* value;')
2332 for i, arg in optional_args:
2334 'value = PyDict_GetItem(%s, %s);' % (
2335 Naming.kwds_cname, arg.name_entry.pystring_cname))
2337 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2338 code.putln('break;')
2341 code.putln('if (unlikely(kw_args > 0)) {')
2342 # non-positional/-required kw args left in dict: default args,
2343 # kw-only args, **kwargs or error
2345 # This is sort of a catch-all: except for checking required
2346 # arguments, this will always do the right thing for unpacking
2347 # keyword arguments, so that we can concentrate on optimising
2348 # common cases above.
2349 if max_positional_args == 0:
2352 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2353 Naming.args_cname, max_positional_args,
2354 Naming.args_cname, max_positional_args))
2355 pos_arg_count = "used_pos_args"
2357 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2358 code.globalstate.use_utility_code(parse_keywords_utility_code)
2360 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2362 Naming.pykwdlist_cname,
2363 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2365 self.name.utf8encode()))
2366 code.putln(code.error_goto(self.pos))
2369 # convert arg values to their final type and assign them
2370 for i, arg in enumerate(all_args):
2371 if arg.default and not arg.type.is_pyobject:
2372 code.putln("if (values[%d]) {" % i)
2373 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2374 if arg.default and not arg.type.is_pyobject:
2375 code.putln('} else {')
2379 arg.default_result_code))
2382 def generate_argument_conversion_code(self, code):
2383 # Generate code to convert arguments from
2384 # signature type to declared type, if needed.
2385 for arg in self.args:
2386 if arg.needs_conversion:
2387 self.generate_arg_conversion(arg, code)
2389 def generate_arg_conversion(self, arg, code):
2390 # Generate conversion code for one argument.
2391 old_type = arg.hdr_type
2393 if old_type.is_pyobject:
2395 code.putln("if (%s) {" % arg.hdr_cname)
2397 code.putln("assert(%s); {" % arg.hdr_cname)
2398 self.generate_arg_conversion_from_pyobject(arg, code)
2400 elif new_type.is_pyobject:
2401 self.generate_arg_conversion_to_pyobject(arg, code)
2403 if new_type.assignable_from(old_type):
2405 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2408 "Cannot convert 1 argument from '%s' to '%s'" %
2409 (old_type, new_type))
2411 def generate_arg_conversion_from_pyobject(self, arg, code):
2413 func = new_type.from_py_function
2414 # copied from CoerceFromPyTypeNode
2416 code.putln("%s = %s(%s); %s" % (
2420 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2423 "Cannot convert Python object argument to type '%s'"
2426 def generate_arg_conversion_to_pyobject(self, arg, code):
2427 old_type = arg.hdr_type
2428 func = old_type.to_py_function
2430 code.putln("%s = %s(%s); %s" % (
2434 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2435 code.put_var_gotref(arg.entry)
2438 "Cannot convert argument of type '%s' to Python object"
2441 def generate_argument_type_tests(self, code):
2442 # Generate type tests for args whose signature
2443 # type is PyObject * and whose declared type is
2444 # a subtype thereof.
2445 for arg in self.args:
2446 if arg.needs_type_test:
2447 self.generate_arg_type_test(arg, code)
2449 def generate_arg_type_test(self, arg, code):
2450 # Generate type test for one argument.
2451 if arg.type.typeobj_is_available():
2452 typeptr_cname = arg.type.typeptr_cname
2453 arg_code = "((PyObject *)%s)" % arg.entry.cname
2455 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2460 arg.type.is_builtin_type,
2461 code.error_goto(arg.pos)))
2463 error(arg.pos, "Cannot test type of extern C class "
2464 "without type object name specification")
2466 def error_value(self):
2467 return self.entry.signature.error_value
2469 def caller_will_check_exceptions(self):
2472 class OverrideCheckNode(StatNode):
2473 # A Node for dispatching to the def method if it
2482 child_attrs = ['body']
2486 def analyse_expressions(self, env):
2487 self.args = env.arg_entries
2488 if self.py_func.is_module_scope:
2493 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2494 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2495 call_node = ExprNodes.SimpleCallNode(self.pos,
2496 function=self.func_node,
2497 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2498 self.body = ReturnStatNode(self.pos, value=call_node)
2499 self.body.analyse_expressions(env)
2501 def generate_execution_code(self, code):
2502 # Check to see if we are an extension type
2503 if self.py_func.is_module_scope:
2504 self_arg = "((PyObject *)%s)" % Naming.module_cname
2506 self_arg = "((PyObject *)%s)" % self.args[0].cname
2507 code.putln("/* Check if called by wrapper */")
2508 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2509 code.putln("/* Check if overriden in Python */")
2510 if self.py_func.is_module_scope:
2511 code.putln("else {")
2513 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2514 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2515 # need to get attribute manually--scope would return cdef method
2516 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2517 code.put_gotref(self.func_node.py_result())
2518 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2519 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2520 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2521 self.body.generate_execution_code(code)
2523 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2526 class ClassDefNode(StatNode, BlockNode):
2529 class PyClassDefNode(ClassDefNode):
2530 # A Python class definition.
2532 # name EncodedString Name of the class
2533 # doc string or None
2534 # body StatNode Attribute definition code
2535 # entry Symtab.Entry
2536 # scope PyClassScope
2538 # The following subnodes are constructed internally:
2540 # dict DictNode Class dictionary
2541 # classobj ClassNode Class object
2542 # target NameNode Variable to assign class object to
2544 child_attrs = ["body", "dict", "classobj", "target"]
2546 def __init__(self, pos, name, bases, doc, body):
2547 StatNode.__init__(self, pos)
2552 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2553 if self.doc and Options.docstrings:
2554 doc = embed_position(self.pos, self.doc)
2555 doc_node = ExprNodes.StringNode(pos, value = doc)
2558 self.classobj = ExprNodes.ClassNode(pos, name = name,
2559 bases = bases, dict = self.dict, doc = doc_node)
2560 self.target = ExprNodes.NameNode(pos, name = name)
2562 def as_cclass(self):
2564 Return this node as if it were declared as an extension class
2566 bases = self.classobj.bases.args
2568 base_class_name = None
2569 base_class_module = None
2570 elif len(bases) == 1:
2573 from ExprNodes import AttributeNode, NameNode
2574 while isinstance(base, AttributeNode):
2575 path.insert(0, base.attribute)
2577 if isinstance(base, NameNode):
2578 path.insert(0, base.name)
2579 base_class_name = path[-1]
2581 base_class_module = u'.'.join(path[:-1])
2583 base_class_module = None
2585 error(self.classobj.bases.args.pos, "Invalid base class")
2587 error(self.classobj.bases.args.pos, "C class may only have one base class")
2590 return CClassDefNode(self.pos,
2591 visibility = 'private',
2593 class_name = self.name,
2594 base_class_module = base_class_module,
2595 base_class_name = base_class_name,
2600 def create_scope(self, env):
2602 while env.is_py_class_scope or env.is_c_class_scope:
2603 env = env.outer_scope
2604 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2607 def analyse_declarations(self, env):
2608 self.target.analyse_target_declaration(env)
2609 cenv = self.create_scope(env)
2610 cenv.directives = env.directives
2611 cenv.class_obj_cname = self.target.entry.cname
2612 self.body.analyse_declarations(cenv)
2614 def analyse_expressions(self, env):
2615 self.dict.analyse_expressions(env)
2616 self.classobj.analyse_expressions(env)
2617 genv = env.global_scope()
2619 cenv.class_dict_cname = self.dict.result()
2620 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2621 self.body.analyse_expressions(cenv)
2622 self.target.analyse_target_expression(env, self.classobj)
2623 self.dict.release_temp(env)
2624 #self.classobj.release_temp(env)
2625 #self.target.release_target_temp(env)
2627 def generate_function_definitions(self, env, code):
2628 self.generate_py_string_decls(self.scope, code)
2629 self.body.generate_function_definitions(self.scope, code)
2631 def generate_execution_code(self, code):
2632 self.dict.generate_evaluation_code(code)
2633 self.classobj.generate_evaluation_code(code)
2634 self.body.generate_execution_code(code)
2635 self.target.generate_assignment_code(self.classobj, code)
2636 self.dict.generate_disposal_code(code)
2637 self.dict.free_temps(code)
2640 class CClassDefNode(ClassDefNode):
2641 # An extension type definition.
2643 # visibility 'private' or 'public' or 'extern'
2644 # typedef_flag boolean
2646 # module_name string or None For import of extern type objects
2647 # class_name string Unqualified name of class
2648 # as_name string or None Name to declare as in this scope
2649 # base_class_module string or None Module containing the base class
2650 # base_class_name string or None Name of the base class
2651 # objstruct_name string or None Specified C name of object struct
2652 # typeobj_name string or None Specified C name of type object
2653 # in_pxd boolean Is in a .pxd file
2654 # doc string or None
2655 # body StatNode or None
2656 # entry Symtab.Entry
2657 # base_type PyExtensionType or None
2658 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2659 # buffer_defaults_pos
2661 child_attrs = ["body"]
2662 buffer_defaults_node = None
2663 buffer_defaults_pos = None
2664 typedef_flag = False
2666 objstruct_name = None
2669 def analyse_declarations(self, env):
2670 #print "CClassDefNode.analyse_declarations:", self.class_name
2671 #print "...visibility =", self.visibility
2672 #print "...module_name =", self.module_name
2675 if self.buffer_defaults_node:
2676 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2677 env, [], self.buffer_defaults_node,
2678 need_complete=False)
2680 buffer_defaults = None
2682 if env.in_cinclude and not self.objstruct_name:
2683 error(self.pos, "Object struct name specification required for "
2684 "C class defined in 'extern from' block")
2685 self.base_type = None
2686 # Now that module imports are cached, we need to
2687 # import the modules for extern classes.
2688 if self.module_name:
2690 for module in env.cimported_modules:
2691 if module.name == self.module_name:
2692 self.module = module
2693 if self.module is None:
2694 self.module = ModuleScope(self.module_name, None, env.context)
2695 self.module.has_extern_class = 1
2696 env.add_imported_module(self.module)
2698 if self.base_class_name:
2699 if self.base_class_module:
2700 base_class_scope = env.find_module(self.base_class_module, self.pos)
2702 base_class_scope = env
2703 if self.base_class_name == 'object':
2704 # extension classes are special and don't need to inherit from object
2705 if base_class_scope is None or base_class_scope.lookup('object') is None:
2706 self.base_class_name = None
2707 self.base_class_module = None
2708 base_class_scope = None
2709 if base_class_scope:
2710 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2711 if base_class_entry:
2712 if not base_class_entry.is_type:
2713 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2714 elif not base_class_entry.type.is_extension_type:
2715 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2716 elif not base_class_entry.type.is_complete():
2717 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2719 self.base_type = base_class_entry.type
2720 has_body = self.body is not None
2721 if self.module_name and self.visibility != 'extern':
2722 module_path = self.module_name.split(".")
2723 home_scope = env.find_imported_module(module_path, self.pos)
2729 if self.visibility == 'extern':
2730 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2731 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2733 self.entry = home_scope.declare_c_class(
2734 name = self.class_name,
2736 defining = has_body and self.in_pxd,
2737 implementing = has_body and not self.in_pxd,
2738 module_name = self.module_name,
2739 base_type = self.base_type,
2740 objstruct_cname = self.objstruct_name,
2741 typeobj_cname = self.typeobj_name,
2742 visibility = self.visibility,
2743 typedef_flag = self.typedef_flag,
2745 buffer_defaults = buffer_defaults)
2746 if home_scope is not env and self.visibility == 'extern':
2747 env.add_imported_entry(self.class_name, self.entry, pos)
2748 scope = self.entry.type.scope
2749 if scope is not None:
2750 scope.directives = env.directives
2752 if self.doc and Options.docstrings:
2753 scope.doc = embed_position(self.pos, self.doc)
2756 self.body.analyse_declarations(scope)
2760 scope.implemented = 1
2761 env.allocate_vtable_names(self.entry)
2763 def analyse_expressions(self, env):
2765 scope = self.entry.type.scope
2766 self.body.analyse_expressions(scope)
2768 def generate_function_definitions(self, env, code):
2769 self.generate_py_string_decls(self.entry.type.scope, code)
2771 self.body.generate_function_definitions(
2772 self.entry.type.scope, code)
2774 def generate_execution_code(self, code):
2775 # This is needed to generate evaluation code for
2776 # default values of method arguments.
2778 self.body.generate_execution_code(code)
2780 def annotate(self, code):
2782 self.body.annotate(code)
2785 class PropertyNode(StatNode):
2786 # Definition of a property in an extension type.
2789 # doc EncodedString or None Doc string
2792 child_attrs = ["body"]
2794 def analyse_declarations(self, env):
2795 entry = env.declare_property(self.name, self.doc, self.pos)
2797 if self.doc and Options.docstrings:
2798 doc_entry = env.get_string_const(
2799 self.doc, identifier = False)
2800 entry.doc_cname = doc_entry.cname
2801 entry.scope.directives = env.directives
2802 self.body.analyse_declarations(entry.scope)
2804 def analyse_expressions(self, env):
2805 self.body.analyse_expressions(env)
2807 def generate_function_definitions(self, env, code):
2808 self.body.generate_function_definitions(env, code)
2810 def generate_execution_code(self, code):
2813 def annotate(self, code):
2814 self.body.annotate(code)
2817 class GlobalNode(StatNode):
2818 # Global variable declaration.
2824 def analyse_declarations(self, env):
2825 for name in self.names:
2826 env.declare_global(name, self.pos)
2828 def analyse_expressions(self, env):
2831 def generate_execution_code(self, code):
2835 class ExprStatNode(StatNode):
2836 # Expression used as a statement.
2840 child_attrs = ["expr"]
2842 def analyse_declarations(self, env):
2844 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2845 func = self.expr.function.as_cython_attribute()
2846 if func == u'declare':
2847 args, kwds = self.expr.explicit_args_kwds()
2849 error(self.expr.pos, "Variable names must be specified.")
2850 for var, type_node in kwds.key_value_pairs:
2851 type = type_node.analyse_as_type(env)
2853 error(type_node.pos, "Unknown type")
2855 env.declare_var(var.value, type, var.pos, is_cdef = True)
2856 self.__class__ = PassStatNode
2858 def analyse_expressions(self, env):
2859 self.expr.analyse_expressions(env)
2860 self.expr.release_temp(env)
2862 def generate_execution_code(self, code):
2863 self.expr.generate_evaluation_code(code)
2864 if not self.expr.is_temp and self.expr.result():
2865 code.putln("%s;" % self.expr.result())
2866 self.expr.generate_disposal_code(code)
2867 self.expr.free_temps(code)
2869 def annotate(self, code):
2870 self.expr.annotate(code)
2873 class AssignmentNode(StatNode):
2874 # Abstract base class for assignment nodes.
2876 # The analyse_expressions and generate_execution_code
2877 # phases of assignments are split into two sub-phases
2878 # each, to enable all the right hand sides of a
2879 # parallel assignment to be evaluated before assigning
2880 # to any of the left hand sides.
2882 def analyse_expressions(self, env):
2883 self.analyse_types(env)
2884 self.allocate_rhs_temps(env)
2885 self.allocate_lhs_temps(env)
2887 # def analyse_expressions(self, env):
2888 # self.analyse_expressions_1(env)
2889 # self.analyse_expressions_2(env)
2891 def generate_execution_code(self, code):
2892 self.generate_rhs_evaluation_code(code)
2893 self.generate_assignment_code(code)
2896 class SingleAssignmentNode(AssignmentNode):
2897 # The simplest case:
2901 # lhs ExprNode Left hand side
2902 # rhs ExprNode Right hand side
2903 # first bool Is this guaranteed the first assignment to lhs?
2905 child_attrs = ["lhs", "rhs"]
2907 declaration_only = False
2909 def analyse_declarations(self, env):
2912 # handle declarations of the form x = cython.foo()
2913 if isinstance(self.rhs, ExprNodes.CallNode):
2914 func_name = self.rhs.function.as_cython_attribute()
2916 args, kwds = self.rhs.explicit_args_kwds()
2918 if func_name in ['declare', 'typedef']:
2919 if len(args) > 2 or kwds is not None:
2920 error(rhs.pos, "Can only declare one type at a time.")
2922 type = args[0].analyse_as_type(env)
2924 error(args[0].pos, "Unknown type")
2927 if func_name == 'declare':
2928 if isinstance(lhs, ExprNodes.NameNode):
2929 vars = [(lhs.name, lhs.pos)]
2930 elif isinstance(lhs, ExprNodes.TupleNode):
2931 vars = [(var.name, var.pos) for var in lhs.args]
2933 error(lhs.pos, "Invalid declaration")
2935 for var, pos in vars:
2936 env.declare_var(var, type, pos, is_cdef = True)
2941 self.declaration_only = True
2943 self.declaration_only = True
2944 if not isinstance(lhs, ExprNodes.NameNode):
2945 error(lhs.pos, "Invalid declaration.")
2946 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2948 elif func_name in ['struct', 'union']:
2949 self.declaration_only = True
2950 if len(args) > 0 or kwds is None:
2951 error(rhs.pos, "Struct or union members must be given by name.")
2954 for member, type_node in kwds.key_value_pairs:
2955 type = type_node.analyse_as_type(env)
2957 error(type_node.pos, "Unknown type")
2959 members.append((member.value, type, member.pos))
2960 if len(members) < len(kwds.key_value_pairs):
2962 if not isinstance(self.lhs, ExprNodes.NameNode):
2963 error(self.lhs.pos, "Invalid declaration.")
2964 name = self.lhs.name
2965 scope = StructOrUnionScope(name)
2966 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2967 for member, type, pos in members:
2968 scope.declare_var(member, type, pos)
2970 if self.declaration_only:
2973 self.lhs.analyse_target_declaration(env)
2975 def analyse_types(self, env, use_temp = 0):
2976 self.rhs.analyse_types(env)
2977 self.lhs.analyse_target_types(env)
2978 self.lhs.gil_assignment_check(env)
2979 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2981 self.rhs = self.rhs.coerce_to_temp(env)
2983 def allocate_rhs_temps(self, env):
2984 self.rhs.allocate_temps(env)
2986 def allocate_lhs_temps(self, env):
2987 self.lhs.allocate_target_temps(env, self.rhs)
2988 #self.lhs.release_target_temp(env)
2989 #self.rhs.release_temp(env)
2991 def generate_rhs_evaluation_code(self, code):
2992 self.rhs.generate_evaluation_code(code)
2994 def generate_assignment_code(self, code):
2995 self.lhs.generate_assignment_code(self.rhs, code)
2997 def annotate(self, code):
2998 self.lhs.annotate(code)
2999 self.rhs.annotate(code)
3002 class CascadedAssignmentNode(AssignmentNode):
3003 # An assignment with multiple left hand sides:
3007 # lhs_list [ExprNode] Left hand sides
3008 # rhs ExprNode Right hand sides
3012 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3014 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3015 coerced_rhs_list = None
3017 def analyse_declarations(self, env):
3018 for lhs in self.lhs_list:
3019 lhs.analyse_target_declaration(env)
3021 def analyse_types(self, env, use_temp = 0):
3022 self.rhs.analyse_types(env)
3024 self.rhs = self.rhs.coerce_to_temp(env)
3026 self.rhs = self.rhs.coerce_to_simple(env)
3027 from ExprNodes import CloneNode
3028 self.coerced_rhs_list = []
3029 for lhs in self.lhs_list:
3030 lhs.analyse_target_types(env)
3031 lhs.gil_assignment_check(env)
3032 rhs = CloneNode(self.rhs)
3033 rhs = rhs.coerce_to(lhs.type, env)
3034 self.coerced_rhs_list.append(rhs)
3036 def allocate_rhs_temps(self, env):
3037 self.rhs.allocate_temps(env)
3039 def allocate_lhs_temps(self, env):
3040 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
3041 rhs.allocate_temps(env)
3042 lhs.allocate_target_temps(env, rhs)
3043 #lhs.release_target_temp(env)
3044 #rhs.release_temp(env)
3045 self.rhs.release_temp(env)
3047 def generate_rhs_evaluation_code(self, code):
3048 self.rhs.generate_evaluation_code(code)
3050 def generate_assignment_code(self, code):
3051 for i in range(len(self.lhs_list)):
3052 lhs = self.lhs_list[i]
3053 rhs = self.coerced_rhs_list[i]
3054 rhs.generate_evaluation_code(code)
3055 lhs.generate_assignment_code(rhs, code)
3056 # Assignment has disposed of the cloned RHS
3057 self.rhs.generate_disposal_code(code)
3058 self.rhs.free_temps(code)
3060 def annotate(self, code):
3061 for i in range(len(self.lhs_list)):
3062 lhs = self.lhs_list[i].annotate(code)
3063 rhs = self.coerced_rhs_list[i].annotate(code)
3064 self.rhs.annotate(code)
3067 class ParallelAssignmentNode(AssignmentNode):
3068 # A combined packing/unpacking assignment:
3072 # This has been rearranged by the parser into
3074 # a = d ; b = e ; c = f
3076 # but we must evaluate all the right hand sides
3077 # before assigning to any of the left hand sides.
3079 # stats [AssignmentNode] The constituent assignments
3081 child_attrs = ["stats"]
3083 def analyse_declarations(self, env):
3084 for stat in self.stats:
3085 stat.analyse_declarations(env)
3087 def analyse_expressions(self, env):
3088 for stat in self.stats:
3089 stat.analyse_types(env, use_temp = 1)
3090 stat.allocate_rhs_temps(env)
3091 for stat in self.stats:
3092 stat.allocate_lhs_temps(env)
3094 # def analyse_expressions(self, env):
3095 # for stat in self.stats:
3096 # stat.analyse_expressions_1(env, use_temp = 1)
3097 # for stat in self.stats:
3098 # stat.analyse_expressions_2(env)
3100 def generate_execution_code(self, code):
3101 for stat in self.stats:
3102 stat.generate_rhs_evaluation_code(code)
3103 for stat in self.stats:
3104 stat.generate_assignment_code(code)
3106 def annotate(self, code):
3107 for stat in self.stats:
3111 class InPlaceAssignmentNode(AssignmentNode):
3112 # An in place arithmatic operand:
3118 # lhs ExprNode Left hand side
3119 # rhs ExprNode Right hand side
3120 # op char one of "+-*/%^&|"
3121 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3123 # This code is a bit tricky because in order to obey Python
3124 # semantics the sub-expressions (e.g. indices) of the lhs must
3125 # not be evaluated twice. So we must re-use the values calculated
3126 # in evaluation phase for the assignment phase as well.
3127 # Fortunately, the type of the lhs node is fairly constrained
3128 # (it must be a NameNode, AttributeNode, or IndexNode).
3130 child_attrs = ["lhs", "rhs"]
3133 def analyse_declarations(self, env):
3134 self.lhs.analyse_target_declaration(env)
3136 def analyse_types(self, env):
3137 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3138 self.rhs.analyse_types(env)
3139 self.lhs.analyse_target_types(env)
3140 if Options.incref_local_binop and self.dup.type.is_pyobject:
3141 self.dup = self.dup.coerce_to_temp(env)
3143 def allocate_rhs_temps(self, env):
3145 if self.lhs.type.is_pyobject:
3146 self.rhs = self.rhs.coerce_to_pyobject(env)
3147 elif self.rhs.type.is_pyobject:
3148 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3149 if self.lhs.type.is_pyobject:
3150 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3151 self.result_value.allocate_temps(env)
3153 # self.rhs = self.rhs.coerce_to_temp(env)
3154 self.rhs.allocate_temps(env)
3155 self.dup.allocate_subexpr_temps(env)
3156 self.dup.allocate_temp(env)
3158 def allocate_lhs_temps(self, env):
3159 self.lhs.allocate_target_temps(env, self.rhs)
3160 # self.lhs.release_target_temp(env)
3161 self.dup.release_temp(env)
3162 if self.dup.is_temp:
3163 self.dup.release_subexpr_temps(env)
3164 # self.rhs.release_temp(env)
3165 if self.lhs.type.is_pyobject:
3166 self.result_value.release_temp(env)
3168 def generate_execution_code(self, code):
3170 self.rhs.generate_evaluation_code(code)
3171 self.dup.generate_subexpr_evaluation_code(code)
3172 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3173 # This is because we're manually messing with subexpr nodes
3174 if self.dup.is_temp:
3175 self.dup.allocate_temp_result(code)
3176 # self.dup.generate_result_code is run only if it is not buffer access
3177 if self.operator == "**":
3181 if self.lhs.type.is_pyobject:
3182 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3183 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3184 self.dup.generate_result_code(code)
3186 "%s = %s(%s, %s%s); %s" % (
3187 self.result_value.result(),
3188 self.py_operation_function(),
3189 self.dup.py_result(),
3190 self.rhs.py_result(),
3192 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3193 code.put_gotref(self.result_value.py_result())
3194 self.result_value.generate_evaluation_code(code) # May be a type check...
3195 self.rhs.generate_disposal_code(code)
3196 self.rhs.free_temps(code)
3197 self.dup.generate_disposal_code(code)
3198 self.dup.free_temps(code)
3199 self.lhs.generate_assignment_code(self.result_value, code)
3201 c_op = self.operator
3205 error(self.pos, "No C inplace power operator")
3206 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3207 error(self.pos, "Inplace operators not implemented for complex types.")
3209 # have to do assignment directly to avoid side-effects
3210 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3211 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3213 self.dup.generate_result_code(code)
3214 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3215 self.rhs.generate_disposal_code(code)
3216 self.rhs.free_temps(code)
3217 if self.dup.is_temp:
3218 self.dup.generate_subexpr_disposal_code(code)
3219 self.dup.free_subexpr_temps(code)
3221 def create_dup_node(self, env):
3224 self.dup.analyse_types(env)
3225 if isinstance(self.lhs, ExprNodes.NameNode):
3226 target_lhs = ExprNodes.NameNode(self.dup.pos,
3227 name = self.dup.name,
3228 is_temp = self.dup.is_temp,
3229 entry = self.dup.entry)
3230 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3231 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3232 obj = ExprNodes.CloneNode(self.lhs.obj),
3233 attribute = self.dup.attribute,
3234 is_temp = self.dup.is_temp)
3235 elif isinstance(self.lhs, ExprNodes.IndexNode):
3237 index = ExprNodes.CloneNode(self.lhs.index)
3240 if self.lhs.indices:
3241 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3244 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3245 base = ExprNodes.CloneNode(self.dup.base),
3248 is_temp = self.dup.is_temp)
3251 self.lhs = target_lhs
3254 def py_operation_function(self):
3255 return self.py_functions[self.operator]
3258 "|": "PyNumber_InPlaceOr",
3259 "^": "PyNumber_InPlaceXor",
3260 "&": "PyNumber_InPlaceAnd",
3261 "+": "PyNumber_InPlaceAdd",
3262 "-": "PyNumber_InPlaceSubtract",
3263 "*": "PyNumber_InPlaceMultiply",
3264 "/": "PyNumber_InPlaceDivide",
3265 "%": "PyNumber_InPlaceRemainder",
3266 "<<": "PyNumber_InPlaceLshift",
3267 ">>": "PyNumber_InPlaceRshift",
3268 "**": "PyNumber_InPlacePower",
3269 "//": "PyNumber_InPlaceFloorDivide",
3272 def annotate(self, code):
3273 self.lhs.annotate(code)
3274 self.rhs.annotate(code)
3275 self.dup.annotate(code)
3278 class PrintStatNode(StatNode):
3281 # arg_tuple TupleNode
3282 # append_newline boolean
3284 child_attrs = ["arg_tuple"]
3286 def analyse_expressions(self, env):
3287 self.arg_tuple.analyse_expressions(env)
3288 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3289 self.arg_tuple.release_temp(env)
3290 env.use_utility_code(printing_utility_code)
3291 if len(self.arg_tuple.args) == 1 and self.append_newline:
3292 env.use_utility_code(printing_one_utility_code)
3295 gil_message = "Python print statement"
3297 def generate_execution_code(self, code):
3298 if len(self.arg_tuple.args) == 1 and self.append_newline:
3299 arg = self.arg_tuple.args[0]
3300 arg.generate_evaluation_code(code)
3303 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3305 code.error_goto(self.pos)))
3306 arg.generate_disposal_code(code)
3307 arg.free_temps(code)
3309 self.arg_tuple.generate_evaluation_code(code)
3311 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3312 self.arg_tuple.py_result(),
3313 self.append_newline,
3314 code.error_goto(self.pos)))
3315 self.arg_tuple.generate_disposal_code(code)
3316 self.arg_tuple.free_temps(code)
3318 def annotate(self, code):
3319 self.arg_tuple.annotate(code)
3322 class ExecStatNode(StatNode):
3327 child_attrs = ["args"]
3329 def analyse_expressions(self, env):
3330 for i, arg in enumerate(self.args):
3331 arg.analyse_expressions(env)
3332 arg = arg.coerce_to_pyobject(env)
3333 arg.release_temp(env)
3335 self.temp_result = env.allocate_temp_pyobject()
3336 env.release_temp(self.temp_result)
3337 env.use_utility_code(Builtin.pyexec_utility_code)
3340 gil_message = "Python exec statement"
3342 def generate_execution_code(self, code):
3344 for arg in self.args:
3345 arg.generate_evaluation_code(code)
3346 args.append( arg.py_result() )
3347 args = tuple(args + ['0', '0'][:3-len(args)])
3348 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3349 (self.temp_result,) + args))
3350 for arg in self.args:
3351 arg.generate_disposal_code(code)
3352 arg.free_temps(code)
3354 code.error_goto_if_null(self.temp_result, self.pos))
3355 code.put_gotref(self.temp_result)
3356 code.put_decref_clear(self.temp_result, py_object_type)
3358 def annotate(self, code):
3359 for arg in self.args:
3363 class DelStatNode(StatNode):
3368 child_attrs = ["args"]
3370 def analyse_declarations(self, env):
3371 for arg in self.args:
3372 arg.analyse_target_declaration(env)
3374 def analyse_expressions(self, env):
3375 for arg in self.args:
3376 arg.analyse_target_expression(env, None)
3377 if arg.type.is_pyobject:
3380 error(arg.pos, "Deletion of non-Python object")
3381 #arg.release_target_temp(env)
3383 gil_message = "Deleting Python object"
3385 def generate_execution_code(self, code):
3386 for arg in self.args:
3387 if arg.type.is_pyobject:
3388 arg.generate_deletion_code(code)
3389 # else error reported earlier
3391 def annotate(self, code):
3392 for arg in self.args:
3396 class PassStatNode(StatNode):
3401 def analyse_expressions(self, env):
3404 def generate_execution_code(self, code):
3408 class BreakStatNode(StatNode):
3412 def analyse_expressions(self, env):
3415 def generate_execution_code(self, code):
3416 if not code.break_label:
3417 error(self.pos, "break statement not inside loop")
3419 code.put_goto(code.break_label)
3422 class ContinueStatNode(StatNode):
3426 def analyse_expressions(self, env):
3429 def generate_execution_code(self, code):
3430 if code.funcstate.in_try_finally:
3431 error(self.pos, "continue statement inside try of try...finally")
3432 elif not code.continue_label:
3433 error(self.pos, "continue statement not inside loop")
3435 code.put_goto(code.continue_label)
3438 class ReturnStatNode(StatNode):
3441 # value ExprNode or None
3442 # return_type PyrexType
3443 # temps_in_use [Entry] Temps in use at time of return
3445 child_attrs = ["value"]
3447 def analyse_expressions(self, env):
3448 return_type = env.return_type
3449 self.return_type = return_type
3450 self.temps_in_use = env.temps_in_use()
3452 error(self.pos, "Return not inside a function body")
3455 self.value.analyse_types(env)
3456 if return_type.is_void or return_type.is_returncode:
3457 error(self.value.pos,
3458 "Return with value in void function")
3460 self.value = self.value.coerce_to(env.return_type, env)
3461 self.value.allocate_temps(env)
3462 self.value.release_temp(env)
3464 if (not return_type.is_void
3465 and not return_type.is_pyobject
3466 and not return_type.is_returncode):
3467 error(self.pos, "Return value required")
3468 if return_type.is_pyobject:
3471 gil_message = "Returning Python object"
3473 def generate_execution_code(self, code):
3474 code.mark_pos(self.pos)
3475 if not self.return_type:
3476 # error reported earlier
3478 if self.return_type.is_pyobject:
3479 code.put_xdecref(Naming.retval_cname,
3482 self.value.generate_evaluation_code(code)
3483 self.value.make_owned_reference(code)
3486 Naming.retval_cname,
3487 self.value.result_as(self.return_type)))
3488 self.value.generate_post_assignment_code(code)
3489 self.value.free_temps(code)
3491 if self.return_type.is_pyobject:
3492 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3493 elif self.return_type.is_returncode:
3496 Naming.retval_cname,
3497 self.return_type.default_value))
3498 # free temps the old way
3499 for entry in self.temps_in_use:
3500 code.put_var_decref_clear(entry)
3501 # free temps the new way
3502 for cname, type in code.funcstate.temps_holding_reference():
3503 code.put_decref_clear(cname, type)
3506 # code.return_label)
3507 code.put_goto(code.return_label)
3509 def annotate(self, code):
3511 self.value.annotate(code)
3514 class RaiseStatNode(StatNode):
3517 # exc_type ExprNode or None
3518 # exc_value ExprNode or None
3519 # exc_tb ExprNode or None
3521 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3523 def analyse_expressions(self, env):
3525 self.exc_type.analyse_types(env)
3526 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3527 self.exc_type.allocate_temps(env)
3529 self.exc_value.analyse_types(env)
3530 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3531 self.exc_value.allocate_temps(env)
3533 self.exc_tb.analyse_types(env)
3534 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3535 self.exc_tb.allocate_temps(env)
3537 self.exc_type.release_temp(env)
3539 self.exc_value.release_temp(env)
3541 self.exc_tb.release_temp(env)
3542 env.use_utility_code(raise_utility_code)
3543 env.use_utility_code(restore_exception_utility_code)
3546 gil_message = "Raising exception"
3548 def generate_execution_code(self, code):
3550 self.exc_type.generate_evaluation_code(code)
3551 type_code = self.exc_type.py_result()
3555 self.exc_value.generate_evaluation_code(code)
3556 value_code = self.exc_value.py_result()
3560 self.exc_tb.generate_evaluation_code(code)
3561 tb_code = self.exc_tb.py_result()
3564 if self.exc_type or self.exc_value or self.exc_tb:
3566 "__Pyx_Raise(%s, %s, %s);" % (
3573 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3575 obj.generate_disposal_code(code)
3576 obj.free_temps(code)
3578 code.error_goto(self.pos))
3580 def annotate(self, code):
3582 self.exc_type.annotate(code)
3584 self.exc_value.annotate(code)
3586 self.exc_tb.annotate(code)
3589 class ReraiseStatNode(StatNode):
3593 def analyse_expressions(self, env):
3595 env.use_utility_code(raise_utility_code)
3596 env.use_utility_code(restore_exception_utility_code)
3598 gil_message = "Raising exception"
3600 def generate_execution_code(self, code):
3601 vars = code.funcstate.exc_vars
3603 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3604 code.putln(code.error_goto(self.pos))
3606 error(self.pos, "Reraise not inside except clause")
3609 class AssertStatNode(StatNode):
3613 # value ExprNode or None
3615 child_attrs = ["cond", "value"]
3617 def analyse_expressions(self, env):
3618 self.cond = self.cond.analyse_boolean_expression(env)
3620 self.value.analyse_types(env)
3621 self.value = self.value.coerce_to_pyobject(env)
3622 self.value.allocate_temps(env)
3623 self.cond.release_temp(env)
3625 self.value.release_temp(env)
3627 #env.recycle_pending_temps() # TEMPORARY
3629 gil_message = "Raising exception"
3631 def generate_execution_code(self, code):
3632 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3633 self.cond.generate_evaluation_code(code)
3635 "if (unlikely(!%s)) {" %
3638 self.value.generate_evaluation_code(code)
3640 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3641 self.value.py_result())
3642 self.value.generate_disposal_code(code)
3643 self.value.free_temps(code)
3646 "PyErr_SetNone(PyExc_AssertionError);")
3648 code.error_goto(self.pos))
3651 self.cond.generate_disposal_code(code)
3652 self.cond.free_temps(code)
3653 code.putln("#endif")
3655 def annotate(self, code):
3656 self.cond.annotate(code)
3658 self.value.annotate(code)
3661 class IfStatNode(StatNode):
3664 # if_clauses [IfClauseNode]
3665 # else_clause StatNode or None
3667 child_attrs = ["if_clauses", "else_clause"]
3669 def analyse_control_flow(self, env):
3670 env.start_branching(self.pos)
3671 for if_clause in self.if_clauses:
3672 if_clause.analyse_control_flow(env)
3673 env.next_branch(if_clause.end_pos())
3674 if self.else_clause:
3675 self.else_clause.analyse_control_flow(env)
3676 env.finish_branching(self.end_pos())
3678 def analyse_declarations(self, env):
3679 for if_clause in self.if_clauses:
3680 if_clause.analyse_declarations(env)
3681 if self.else_clause:
3682 self.else_clause.analyse_declarations(env)
3684 def analyse_expressions(self, env):
3685 for if_clause in self.if_clauses:
3686 if_clause.analyse_expressions(env)
3687 if self.else_clause:
3688 self.else_clause.analyse_expressions(env)
3690 def generate_execution_code(self, code):
3691 code.mark_pos(self.pos)
3692 end_label = code.new_label()
3693 for if_clause in self.if_clauses:
3694 if_clause.generate_execution_code(code, end_label)
3695 if self.else_clause:
3696 code.putln("/*else*/ {")
3697 self.else_clause.generate_execution_code(code)
3699 code.put_label(end_label)
3701 def annotate(self, code):
3702 for if_clause in self.if_clauses:
3703 if_clause.annotate(code)
3704 if self.else_clause:
3705 self.else_clause.annotate(code)
3708 class IfClauseNode(Node):
3709 # if or elif clause in an if statement
3711 # condition ExprNode
3714 child_attrs = ["condition", "body"]
3716 def analyse_control_flow(self, env):
3717 self.body.analyse_control_flow(env)
3719 def analyse_declarations(self, env):
3720 self.condition.analyse_declarations(env)
3721 self.body.analyse_declarations(env)
3723 def analyse_expressions(self, env):
3725 self.condition.analyse_temp_boolean_expression(env)
3726 self.condition.release_temp(env)
3727 self.body.analyse_expressions(env)
3729 def generate_execution_code(self, code, end_label):
3730 self.condition.generate_evaluation_code(code)
3733 self.condition.result())
3734 self.condition.generate_disposal_code(code)
3735 self.condition.free_temps(code)
3736 self.body.generate_execution_code(code)
3740 code.put_goto(end_label)
3743 def annotate(self, code):
3744 self.condition.annotate(code)
3745 self.body.annotate(code)
3748 class SwitchCaseNode(StatNode):
3749 # Generated in the optimization of an if-elif-else node
3751 # conditions [ExprNode]
3754 child_attrs = ['conditions', 'body']
3756 def generate_execution_code(self, code):
3757 for cond in self.conditions:
3758 code.mark_pos(cond.pos)
3759 code.putln("case %s:" % cond.calculate_result_code())
3760 self.body.generate_execution_code(code)
3761 code.putln("break;")
3763 def annotate(self, code):
3764 for cond in self.conditions:
3766 self.body.annotate(code)
3768 class SwitchStatNode(StatNode):
3769 # Generated in the optimization of an if-elif-else node
3772 # cases [SwitchCaseNode]
3773 # else_clause StatNode or None
3775 child_attrs = ['test', 'cases', 'else_clause']
3777 def generate_execution_code(self, code):
3778 code.putln("switch (%s) {" % self.test.calculate_result_code())
3779 for case in self.cases:
3780 case.generate_execution_code(code)
3781 if self.else_clause is not None:
3782 code.putln("default:")
3783 self.else_clause.generate_execution_code(code)
3784 code.putln("break;")
3787 def annotate(self, code):
3788 self.test.annotate(code)
3789 for case in self.cases:
3791 if self.else_clause is not None:
3792 self.else_clause.annotate(code)
3794 class LoopNode(object):
3796 def analyse_control_flow(self, env):
3797 env.start_branching(self.pos)
3798 self.body.analyse_control_flow(env)
3799 env.next_branch(self.body.end_pos())
3800 if self.else_clause:
3801 self.else_clause.analyse_control_flow(env)
3802 env.finish_branching(self.end_pos())
3805 class WhileStatNode(LoopNode, StatNode):
3808 # condition ExprNode
3810 # else_clause StatNode
3812 child_attrs = ["condition", "body", "else_clause"]
3814 def analyse_declarations(self, env):
3815 self.body.analyse_declarations(env)
3816 if self.else_clause:
3817 self.else_clause.analyse_declarations(env)
3819 def analyse_expressions(self, env):
3821 self.condition.analyse_temp_boolean_expression(env)
3822 self.condition.release_temp(env)
3823 #env.recycle_pending_temps() # TEMPORARY
3824 self.body.analyse_expressions(env)
3825 if self.else_clause:
3826 self.else_clause.analyse_expressions(env)
3828 def generate_execution_code(self, code):
3829 old_loop_labels = code.new_loop_labels()
3832 self.condition.generate_evaluation_code(code)
3833 self.condition.generate_disposal_code(code)
3836 self.condition.result())
3837 self.condition.free_temps(code)
3838 self.body.generate_execution_code(code)
3839 code.put_label(code.continue_label)
3841 break_label = code.break_label
3842 code.set_loop_labels(old_loop_labels)
3843 if self.else_clause:
3844 code.putln("/*else*/ {")
3845 self.else_clause.generate_execution_code(code)
3847 code.put_label(break_label)
3849 def annotate(self, code):
3850 self.condition.annotate(code)
3851 self.body.annotate(code)
3852 if self.else_clause:
3853 self.else_clause.annotate(code)
3856 def ForStatNode(pos, **kw):
3857 if 'iterator' in kw:
3858 return ForInStatNode(pos, **kw)
3860 return ForFromStatNode(pos, **kw)
3862 class ForInStatNode(LoopNode, StatNode):
3866 # iterator IteratorNode
3868 # else_clause StatNode
3869 # item NextNode used internally
3871 child_attrs = ["target", "iterator", "body", "else_clause"]
3874 def analyse_declarations(self, env):
3875 self.target.analyse_target_declaration(env)
3876 self.body.analyse_declarations(env)
3877 if self.else_clause:
3878 self.else_clause.analyse_declarations(env)
3880 def analyse_expressions(self, env):
3882 self.target.analyse_target_types(env)
3883 self.iterator.analyse_expressions(env)
3884 self.item = ExprNodes.NextNode(self.iterator, env)
3885 self.item = self.item.coerce_to(self.target.type, env)
3886 self.item.allocate_temps(env)
3887 self.target.allocate_target_temps(env, self.item)
3888 #self.item.release_temp(env)
3889 #self.target.release_target_temp(env)
3890 self.body.analyse_expressions(env)
3891 if self.else_clause:
3892 self.else_clause.analyse_expressions(env)
3893 self.iterator.release_temp(env)
3895 def generate_execution_code(self, code):
3896 old_loop_labels = code.new_loop_labels()
3897 self.iterator.allocate_counter_temp(code)
3898 self.iterator.generate_evaluation_code(code)
3901 self.item.generate_evaluation_code(code)
3902 self.target.generate_assignment_code(self.item, code)
3903 self.body.generate_execution_code(code)
3904 code.put_label(code.continue_label)
3907 break_label = code.break_label
3908 code.set_loop_labels(old_loop_labels)
3909 if self.else_clause:
3910 code.putln("/*else*/ {")
3911 self.else_clause.generate_execution_code(code)
3913 code.put_label(break_label)
3914 self.iterator.release_counter_temp(code)
3915 self.iterator.generate_disposal_code(code)
3916 self.iterator.free_temps(code)
3918 def annotate(self, code):
3919 self.target.annotate(code)
3920 self.iterator.annotate(code)
3921 self.body.annotate(code)
3922 if self.else_clause:
3923 self.else_clause.annotate(code)
3924 self.item.annotate(code)
3927 class ForFromStatNode(LoopNode, StatNode):
3928 # for name from expr rel name rel expr
3935 # step ExprNode or None
3937 # else_clause StatNode or None
3943 # loopvar_node ExprNode (usually a NameNode or temp node)
3944 # py_loopvar_node PyTempNode or None
3945 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3947 is_py_target = False
3949 py_loopvar_node = None
3952 def analyse_declarations(self, env):
3953 self.target.analyse_target_declaration(env)
3954 self.body.analyse_declarations(env)
3955 if self.else_clause:
3956 self.else_clause.analyse_declarations(env)
3958 def analyse_expressions(self, env):
3960 self.target.analyse_target_types(env)
3961 self.bound1.analyse_types(env)
3962 self.bound2.analyse_types(env)
3963 if self.step is not None:
3964 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3965 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3966 self.step.analyse_types(env)
3968 target_type = self.target.type
3969 if self.target.type.is_numeric:
3970 loop_type = self.target.type
3972 loop_type = PyrexTypes.c_int_type
3973 if not self.bound1.type.is_pyobject:
3974 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3975 if not self.bound2.type.is_pyobject:
3976 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3977 if self.step is not None and not self.step.type.is_pyobject:
3978 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3979 self.bound1 = self.bound1.coerce_to(loop_type, env)
3980 self.bound2 = self.bound2.coerce_to(loop_type, env)
3981 if not self.bound2.is_literal:
3982 self.bound2 = self.bound2.coerce_to_temp(env)
3983 if self.step is not None:
3984 self.step = self.step.coerce_to(loop_type, env)
3985 if not self.step.is_literal:
3986 self.step = self.step.coerce_to_temp(env)
3988 target_type = self.target.type
3989 if not (target_type.is_pyobject or target_type.is_numeric):
3990 error(self.target.pos,
3991 "for-from loop variable must be c numeric type or Python object")
3992 if target_type.is_numeric:
3993 self.is_py_target = False
3994 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3995 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3996 self.loopvar_node = self.target
3997 self.py_loopvar_node = None
3999 self.is_py_target = True
4000 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4001 c_loopvar_node.allocate_temps(env)
4002 self.loopvar_node = c_loopvar_node
4003 self.py_loopvar_node = \
4004 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4005 self.bound1.allocate_temps(env)
4006 self.bound2.allocate_temps(env)
4007 if self.step is not None:
4008 self.step.allocate_temps(env)
4009 if self.is_py_target:
4010 self.py_loopvar_node.allocate_temps(env)
4011 self.target.allocate_target_temps(env, self.py_loopvar_node)
4012 #self.target.release_target_temp(env)
4013 #self.py_loopvar_node.release_temp(env)
4014 self.body.analyse_expressions(env)
4015 if self.is_py_target:
4016 c_loopvar_node.release_temp(env)
4017 if self.else_clause:
4018 self.else_clause.analyse_expressions(env)
4019 self.bound1.release_temp(env)
4020 self.bound2.release_temp(env)
4021 if self.step is not None:
4022 self.step.release_temp(env)
4024 def generate_execution_code(self, code):
4025 old_loop_labels = code.new_loop_labels()
4026 from_range = self.from_range
4027 self.bound1.generate_evaluation_code(code)
4028 self.bound2.generate_evaluation_code(code)
4029 offset, incop = self.relation_table[self.relation1]
4030 if self.step is not None:
4031 self.step.generate_evaluation_code(code)
4032 step = self.step.result()
4033 incop = "%s=%s" % (incop[0], step)
4035 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4037 loopvar_name = self.loopvar_node.result()
4039 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4041 self.bound1.result(), offset,
4042 loopvar_name, self.relation2, self.bound2.result(),
4043 loopvar_name, incop))
4044 if self.py_loopvar_node:
4045 self.py_loopvar_node.generate_evaluation_code(code)
4046 self.target.generate_assignment_code(self.py_loopvar_node, code)
4048 code.putln("%s = %s;" % (
4049 self.target.result(), loopvar_name))
4050 self.body.generate_execution_code(code)
4051 code.put_label(code.continue_label)
4052 if self.py_loopvar_node:
4053 # This mess is to make for..from loops with python targets behave
4054 # exactly like those with C targets with regards to re-assignment
4055 # of the loop variable.
4057 if self.target.entry.is_pyglobal:
4058 # We know target is a NameNode, this is the only ugly case.
4059 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4060 target_node.result_code = code.funcstate.allocate_temp(py_object_type, False)
4061 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4062 target_node.result_code,
4063 Naming.module_cname,
4064 self.target.entry.interned_cname,
4065 code.error_goto_if_null(target_node.result_code, self.target.pos)))
4066 code.put_gotref(target_node.result_code)
4068 target_node = self.target
4069 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4070 from_py_node.temp_code = loopvar_name
4071 from_py_node.generate_result_code(code)
4072 if self.target.entry.is_pyglobal:
4073 code.put_decref_clear(target_node.result_code, py_object_type)
4074 code.funcstate.release_temp(target_node.result_code)
4076 if self.py_loopvar_node:
4077 # This is potentially wasteful, but we don't want the semantics to
4078 # depend on whether or not the loop is a python type.
4079 self.py_loopvar_node.generate_evaluation_code(code)
4080 self.target.generate_assignment_code(self.py_loopvar_node, code)
4081 break_label = code.break_label
4082 code.set_loop_labels(old_loop_labels)
4083 if self.else_clause:
4084 code.putln("/*else*/ {")
4085 self.else_clause.generate_execution_code(code)
4087 code.put_label(break_label)
4088 self.bound1.generate_disposal_code(code)
4089 self.bound1.free_temps(code)
4090 self.bound2.generate_disposal_code(code)
4091 self.bound2.free_temps(code)
4092 if self.step is not None:
4093 self.step.generate_disposal_code(code)
4094 self.step.free_temps(code)
4096 code.funcstate.release_temp(loopvar_name)
4099 # {relop : (initial offset, increment op)}
4106 def annotate(self, code):
4107 self.target.annotate(code)
4108 self.bound1.annotate(code)
4109 self.bound2.annotate(code)
4111 self.bound2.annotate(code)
4112 self.body.annotate(code)
4113 if self.else_clause:
4114 self.else_clause.annotate(code)
4117 class WithStatNode(StatNode):
4119 Represents a Python with statement.
4121 This is only used at parse tree level; and is not present in
4122 analysis or generation phases.
4124 # manager The with statement manager object
4125 # target Node (lhs expression)
4127 child_attrs = ["manager", "target", "body"]
4129 class TryExceptStatNode(StatNode):
4130 # try .. except statement
4133 # except_clauses [ExceptClauseNode]
4134 # else_clause StatNode or None
4135 # cleanup_list [Entry] old style temps to clean up on error
4137 child_attrs = ["body", "except_clauses", "else_clause"]
4139 def analyse_control_flow(self, env):
4140 env.start_branching(self.pos)
4141 self.body.analyse_control_flow(env)
4142 successful_try = env.control_flow # grab this for later
4143 env.next_branch(self.body.end_pos())
4144 env.finish_branching(self.body.end_pos())
4146 env.start_branching(self.except_clauses[0].pos)
4147 for except_clause in self.except_clauses:
4148 except_clause.analyse_control_flow(env)
4149 env.next_branch(except_clause.end_pos())
4151 # the else cause it executed only when the try clause finishes
4152 env.control_flow.incoming = successful_try
4153 if self.else_clause:
4154 self.else_clause.analyse_control_flow(env)
4155 env.finish_branching(self.end_pos())
4157 def analyse_declarations(self, env):
4158 self.body.analyse_declarations(env)
4159 for except_clause in self.except_clauses:
4160 except_clause.analyse_declarations(env)
4161 if self.else_clause:
4162 self.else_clause.analyse_declarations(env)
4164 env.use_utility_code(reset_exception_utility_code)
4166 def analyse_expressions(self, env):
4167 self.body.analyse_expressions(env)
4168 self.cleanup_list = env.free_temp_entries[:]
4169 default_clause_seen = 0
4170 for except_clause in self.except_clauses:
4171 except_clause.analyse_expressions(env)
4172 if default_clause_seen:
4173 error(except_clause.pos, "default 'except:' must be last")
4174 if not except_clause.pattern:
4175 default_clause_seen = 1
4176 self.has_default_clause = default_clause_seen
4177 if self.else_clause:
4178 self.else_clause.analyse_expressions(env)
4181 gil_message = "Try-except statement"
4183 def generate_execution_code(self, code):
4184 old_return_label = code.return_label
4185 old_break_label = code.break_label
4186 old_continue_label = code.continue_label
4187 old_error_label = code.new_error_label()
4188 our_error_label = code.error_label
4189 except_end_label = code.new_label('exception_handled')
4190 except_error_label = code.new_label('except_error')
4191 except_return_label = code.new_label('except_return')
4192 try_return_label = code.new_label('try_return')
4193 try_break_label = code.new_label('try_break')
4194 try_continue_label = code.new_label('try_continue')
4195 try_end_label = code.new_label('try_end')
4198 code.putln("PyObject %s;" %
4199 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4200 code.putln("__Pyx_ExceptionSave(%s);" %
4201 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4202 for var in Naming.exc_save_vars:
4203 code.put_xgotref(var)
4206 code.return_label = try_return_label
4207 code.break_label = try_break_label
4208 code.continue_label = try_continue_label
4209 self.body.generate_execution_code(code)
4212 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4213 code.error_label = except_error_label
4214 code.return_label = except_return_label
4215 if self.else_clause:
4218 self.else_clause.generate_execution_code(code)
4221 for var in Naming.exc_save_vars:
4222 code.put_xdecref_clear(var, py_object_type)
4223 code.put_goto(try_end_label)
4224 if code.label_used(try_return_label):
4225 code.put_label(try_return_label)
4226 for var in Naming.exc_save_vars:
4227 code.put_xdecref_clear(var, py_object_type)
4228 code.put_goto(old_return_label)
4229 code.put_label(our_error_label)
4230 code.put_var_xdecrefs_clear(self.cleanup_list)
4231 for temp_name, type in temps_to_clean_up:
4232 code.put_xdecref_clear(temp_name, type)
4233 for except_clause in self.except_clauses:
4234 except_clause.generate_handling_code(code, except_end_label)
4236 error_label_used = code.label_used(except_error_label)
4237 if error_label_used or not self.has_default_clause:
4238 if error_label_used:
4239 code.put_label(except_error_label)
4240 for var in Naming.exc_save_vars:
4241 code.put_xdecref(var, py_object_type)
4242 code.put_goto(old_error_label)
4244 if code.label_used(try_break_label):
4245 code.put_label(try_break_label)
4246 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4247 code.putln("__Pyx_ExceptionReset(%s);" %
4248 ', '.join(Naming.exc_save_vars))
4249 code.put_goto(old_break_label)
4251 if code.label_used(try_continue_label):
4252 code.put_label(try_continue_label)
4253 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4254 code.putln("__Pyx_ExceptionReset(%s);" %
4255 ', '.join(Naming.exc_save_vars))
4256 code.put_goto(old_continue_label)
4258 if code.label_used(except_return_label):
4259 code.put_label(except_return_label)
4260 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4261 code.putln("__Pyx_ExceptionReset(%s);" %
4262 ', '.join(Naming.exc_save_vars))
4263 code.put_goto(old_return_label)
4265 if code.label_used(except_end_label):
4266 code.put_label(except_end_label)
4267 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4268 code.putln("__Pyx_ExceptionReset(%s);" %
4269 ', '.join(Naming.exc_save_vars))
4270 code.put_label(try_end_label)
4273 code.return_label = old_return_label
4274 code.break_label = old_break_label
4275 code.continue_label = old_continue_label
4276 code.error_label = old_error_label
4278 def annotate(self, code):
4279 self.body.annotate(code)
4280 for except_node in self.except_clauses:
4281 except_node.annotate(code)
4282 if self.else_clause:
4283 self.else_clause.annotate(code)
4286 class ExceptClauseNode(Node):
4287 # Part of try ... except statement.
4290 # target ExprNode or None
4292 # excinfo_target NameNode or None optional target for exception info
4293 # match_flag string result of exception match
4294 # exc_value ExcValueNode used internally
4295 # function_name string qualified name of enclosing function
4296 # exc_vars (string * 3) local exception variables
4298 # excinfo_target is never set by the parser, but can be set by a transform
4299 # in order to extract more extensive information about the exception as a
4300 # sys.exc_info()-style tuple into a target variable
4302 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4305 excinfo_target = None
4307 def analyse_declarations(self, env):
4309 self.target.analyse_target_declaration(env)
4310 if self.excinfo_target is not None:
4311 self.excinfo_target.analyse_target_declaration(env)
4312 self.body.analyse_declarations(env)
4314 def analyse_expressions(self, env):
4316 genv = env.global_scope()
4317 self.function_name = env.qualified_name
4319 self.pattern.analyse_expressions(env)
4320 self.pattern = self.pattern.coerce_to_pyobject(env)
4321 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4322 self.pattern.release_temp(env)
4323 env.release_temp(self.match_flag)
4325 if self.target or self.excinfo_target:
4326 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4328 self.exc_vars = None
4331 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4332 self.exc_value.allocate_temps(env)
4333 self.target.analyse_target_expression(env, self.exc_value)
4334 if self.excinfo_target is not None:
4336 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4337 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4338 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4339 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4341 self.excinfo_tuple.analyse_expressions(env)
4342 self.excinfo_tuple.allocate_temps(env)
4343 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4345 self.body.analyse_expressions(env)
4348 for var in self.exc_vars:
4349 env.release_temp(var)
4351 def generate_handling_code(self, code, end_label):
4352 code.mark_pos(self.pos)
4354 self.pattern.generate_evaluation_code(code)
4356 "%s = PyErr_ExceptionMatches(%s);" % (
4358 self.pattern.py_result()))
4359 self.pattern.generate_disposal_code(code)
4360 self.pattern.free_temps(code)
4365 code.putln("/*except:*/ {")
4368 exc_vars = self.exc_vars
4369 elif not getattr(self.body, 'stats', True):
4370 # most simple case: no exception variable, empty body (pass)
4371 # => reset the exception state, done
4372 code.putln("PyErr_Restore(0,0,0);")
4373 code.put_goto(end_label)
4377 # during type analysis, we didn't know if we need the
4378 # exception value, but apparently, we do
4379 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4383 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4384 # We always have to fetch the exception value even if
4385 # there is no target, because this also normalises the
4386 # exception and stores it in the thread state.
4387 code.globalstate.use_utility_code(get_exception_utility_code)
4388 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4389 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4390 code.error_goto(self.pos)))
4394 self.exc_value.generate_evaluation_code(code)
4395 self.target.generate_assignment_code(self.exc_value, code)
4396 if self.excinfo_target is not None:
4397 self.excinfo_tuple.generate_evaluation_code(code)
4398 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4401 old_break_label, old_continue_label = code.break_label, code.continue_label
4402 code.break_label = code.new_label('except_break')
4403 code.continue_label = code.new_label('except_continue')
4405 old_exc_vars = code.funcstate.exc_vars
4406 code.funcstate.exc_vars = exc_vars
4407 self.body.generate_execution_code(code)
4408 code.funcstate.exc_vars = old_exc_vars
4409 for var in exc_vars:
4410 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4411 code.put_goto(end_label)
4413 if code.label_used(code.break_label):
4414 code.put_label(code.break_label)
4415 for var in exc_vars:
4416 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4417 code.put_goto(old_break_label)
4418 code.break_label = old_break_label
4420 if code.label_used(code.continue_label):
4421 code.put_label(code.continue_label)
4422 for var in exc_vars:
4423 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4424 code.put_goto(old_continue_label)
4425 code.continue_label = old_continue_label
4427 if not self.exc_vars:
4428 # clean up locally allocated temps
4429 for temp in exc_vars:
4430 code.funcstate.release_temp(temp)
4435 def annotate(self, code):
4437 self.pattern.annotate(code)
4439 self.target.annotate(code)
4440 self.body.annotate(code)
4443 class TryFinallyStatNode(StatNode):
4444 # try ... finally statement
4447 # finally_clause StatNode
4449 # cleanup_list [Entry] old_style temps to clean up on error
4451 # The plan is that we funnel all continue, break
4452 # return and error gotos into the beginning of the
4453 # finally block, setting a variable to remember which
4454 # one we're doing. At the end of the finally block, we
4455 # switch on the variable to figure out where to go.
4456 # In addition, if we're doing an error, we save the
4457 # exception on entry to the finally block and restore
4460 child_attrs = ["body", "finally_clause"]
4462 preserve_exception = 1
4464 disallow_continue_in_try_finally = 0
4465 # There doesn't seem to be any point in disallowing
4466 # continue in the try block, since we have no problem
4469 def create_analysed(pos, env, body, finally_clause):
4470 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4471 node.cleanup_list = []
4473 create_analysed = staticmethod(create_analysed)
4475 def analyse_control_flow(self, env):
4476 env.start_branching(self.pos)
4477 self.body.analyse_control_flow(env)
4478 env.next_branch(self.body.end_pos())
4479 env.finish_branching(self.body.end_pos())
4480 self.finally_clause.analyse_control_flow(env)
4482 def analyse_declarations(self, env):
4483 self.body.analyse_declarations(env)
4484 self.finally_clause.analyse_declarations(env)
4486 def analyse_expressions(self, env):
4487 self.body.analyse_expressions(env)
4488 self.cleanup_list = env.free_temp_entries[:]
4489 self.finally_clause.analyse_expressions(env)
4492 gil_message = "Try-finally statement"
4494 def generate_execution_code(self, code):
4495 old_error_label = code.error_label
4496 old_labels = code.all_new_labels()
4497 new_labels = code.get_all_labels()
4498 new_error_label = code.error_label
4499 catch_label = code.new_label()
4502 if self.disallow_continue_in_try_finally:
4503 was_in_try_finally = code.funcstate.in_try_finally
4504 code.funcstate.in_try_finally = 1
4505 self.body.generate_execution_code(code)
4506 if self.disallow_continue_in_try_finally:
4507 code.funcstate.in_try_finally = was_in_try_finally
4510 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4514 error_label_used = 0
4515 for i, new_label in enumerate(new_labels):
4516 if new_label in code.labels_used:
4517 cases_used.append(i)
4518 if new_label == new_error_label:
4519 error_label_used = 1
4520 error_label_case = i
4524 if error_label_used and self.preserve_exception:
4526 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4528 "int %s;" % Naming.exc_lineno_name)
4529 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4530 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4531 code.putln(exc_var_init_zero)
4533 exc_var_init_zero = None
4534 code.use_label(catch_label)
4536 "__pyx_why = 0; goto %s;" % catch_label)
4537 for i in cases_used:
4538 new_label = new_labels[i]
4539 #if new_label and new_label != "<try>":
4540 if new_label == new_error_label and self.preserve_exception:
4541 self.put_error_catcher(code,
4542 new_error_label, i+1, catch_label, temps_to_clean_up)
4544 code.put('%s: ' % new_label)
4545 if exc_var_init_zero:
4546 code.putln(exc_var_init_zero)
4547 code.putln("__pyx_why = %s; goto %s;" % (
4550 code.put_label(catch_label)
4551 code.set_all_labels(old_labels)
4552 if error_label_used:
4553 code.new_error_label()
4554 finally_error_label = code.error_label
4555 self.finally_clause.generate_execution_code(code)
4556 if error_label_used:
4557 if finally_error_label in code.labels_used and self.preserve_exception:
4558 over_label = code.new_label()
4559 code.put_goto(over_label);
4560 code.put_label(finally_error_label)
4561 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4562 for var in Naming.exc_vars:
4563 code.putln("Py_XDECREF(%s);" % var)
4565 code.put_goto(old_error_label)
4566 code.put_label(over_label)
4567 code.error_label = old_error_label
4570 "switch (__pyx_why) {")
4571 for i in cases_used:
4572 old_label = old_labels[i]
4573 if old_label == old_error_label and self.preserve_exception:
4574 self.put_error_uncatcher(code, i+1, old_error_label)
4576 code.use_label(old_label)
4578 "case %s: goto %s;" % (
4586 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4587 code.globalstate.use_utility_code(restore_exception_utility_code)
4594 code.put_var_xdecrefs_clear(self.cleanup_list)
4595 for temp_name, type in temps_to_clean_up:
4596 code.put_xdecref_clear(temp_name, type)
4598 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4602 Naming.exc_lineno_name, Naming.lineno_cname))
4606 code.put_goto(catch_label)
4610 def put_error_uncatcher(self, code, i, error_label):
4611 code.globalstate.use_utility_code(restore_exception_utility_code)
4616 "__Pyx_ErrRestore(%s, %s, %s);" %
4620 Naming.lineno_cname, Naming.exc_lineno_name))
4621 for var in Naming.exc_vars:
4625 code.put_goto(error_label)
4629 def annotate(self, code):
4630 self.body.annotate(code)
4631 self.finally_clause.annotate(code)
4634 class GILStatNode(TryFinallyStatNode):
4635 # 'with gil' or 'with nogil' statement
4637 # state string 'gil' or 'nogil'
4641 preserve_exception = 0
4643 def __init__(self, pos, state, body):
4645 TryFinallyStatNode.__init__(self, pos,
4647 finally_clause = GILExitNode(pos, state = state))
4649 def analyse_expressions(self, env):
4650 env.use_utility_code(force_init_threads_utility_code)
4651 was_nogil = env.nogil
4653 TryFinallyStatNode.analyse_expressions(self, env)
4654 env.nogil = was_nogil
4656 def gil_check(self, env):
4659 def generate_execution_code(self, code):
4660 code.mark_pos(self.pos)
4661 if self.state == 'gil':
4662 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4664 code.putln("{ PyThreadState *_save;")
4665 code.putln("Py_UNBLOCK_THREADS")
4666 TryFinallyStatNode.generate_execution_code(self, code)
4670 class GILExitNode(StatNode):
4671 # Used as the 'finally' block in a GILStatNode
4673 # state string 'gil' or 'nogil'
4677 def analyse_expressions(self, env):
4680 def generate_execution_code(self, code):
4681 if self.state == 'gil':
4682 code.putln("PyGILState_Release();")
4684 code.putln("Py_BLOCK_THREADS")
4687 class CImportStatNode(StatNode):
4690 # module_name string Qualified name of module being imported
4691 # as_name string or None Name specified in "as" clause, if any
4695 def analyse_declarations(self, env):
4696 if not env.is_module_scope:
4697 error(self.pos, "cimport only allowed at module level")
4699 module_scope = env.find_module(self.module_name, self.pos)
4700 if "." in self.module_name:
4701 names = [EncodedString(name) for name in self.module_name.split(".")]
4703 top_module_scope = env.context.find_submodule(top_name)
4704 module_scope = top_module_scope
4705 for name in names[1:]:
4706 submodule_scope = module_scope.find_submodule(name)
4707 module_scope.declare_module(name, submodule_scope, self.pos)
4708 module_scope = submodule_scope
4710 env.declare_module(self.as_name, module_scope, self.pos)
4712 env.declare_module(top_name, top_module_scope, self.pos)
4714 name = self.as_name or self.module_name
4715 env.declare_module(name, module_scope, self.pos)
4717 def analyse_expressions(self, env):
4720 def generate_execution_code(self, code):
4724 class FromCImportStatNode(StatNode):
4725 # from ... cimport statement
4727 # module_name string Qualified name of module
4728 # imported_names [(pos, name, as_name, kind)] Names to be imported
4732 def analyse_declarations(self, env):
4733 if not env.is_module_scope:
4734 error(self.pos, "cimport only allowed at module level")
4736 module_scope = env.find_module(self.module_name, self.pos)
4737 env.add_imported_module(module_scope)
4738 for pos, name, as_name, kind in self.imported_names:
4740 for local_name, entry in module_scope.entries.items():
4741 env.add_imported_entry(local_name, entry, pos)
4743 entry = module_scope.lookup(name)
4745 if kind and not self.declaration_matches(entry, kind):
4746 entry.redeclared(pos)
4748 if kind == 'struct' or kind == 'union':
4749 entry = module_scope.declare_struct_or_union(name,
4750 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4751 elif kind == 'class':
4752 entry = module_scope.declare_c_class(name, pos = pos,
4753 module_name = self.module_name)
4755 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4756 if submodule_scope.parent_module is module_scope:
4757 env.declare_module(as_name or name, submodule_scope, self.pos)
4759 error(pos, "Name '%s' not declared in module '%s'"
4760 % (name, self.module_name))
4763 local_name = as_name or name
4764 env.add_imported_entry(local_name, entry, pos)
4766 def declaration_matches(self, entry, kind):
4767 if not entry.is_type:
4771 if not type.is_extension_type:
4774 if not type.is_struct_or_union:
4776 if kind != type.kind:
4780 def analyse_expressions(self, env):
4783 def generate_execution_code(self, code):
4787 class FromImportStatNode(StatNode):
4788 # from ... import statement
4791 # items [(string, NameNode)]
4792 # interned_items [(string, NameNode, ExprNode)]
4793 # item PyTempNode used internally
4794 # import_star boolean used internally
4796 child_attrs = ["module"]
4799 def analyse_declarations(self, env):
4800 for name, target in self.items:
4802 if not env.is_module_scope:
4803 error(self.pos, "import * only allowed at module level")
4805 env.has_import_star = 1
4806 self.import_star = 1
4808 target.analyse_target_declaration(env)
4810 def analyse_expressions(self, env):
4812 self.module.analyse_expressions(env)
4813 self.item = ExprNodes.PyTempNode(self.pos, env)
4814 self.item.allocate_temp(env)
4815 self.interned_items = []
4816 for name, target in self.items:
4818 for _, entry in env.entries.items():
4819 if not entry.is_type and entry.type.is_extension_type:
4820 env.use_utility_code(ExprNodes.type_test_utility_code)
4823 entry = env.lookup(target.name)
4824 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4825 continue # already cimported
4826 target.analyse_target_expression(env, None)
4827 if target.type is py_object_type:
4830 coerced_item = self.item.coerce_to(target.type, env)
4831 self.interned_items.append(
4832 (env.intern_identifier(name), target, coerced_item))
4833 #target.release_target_temp(env) # was release_temp ?!?
4834 self.module.release_temp(env)
4835 self.item.release_temp(env)
4837 def generate_execution_code(self, code):
4838 self.module.generate_evaluation_code(code)
4839 if self.import_star:
4841 'if (%s(%s) < 0) %s;' % (
4843 self.module.py_result(),
4844 code.error_goto(self.pos)))
4845 for cname, target, coerced_item in self.interned_items:
4847 '%s = PyObject_GetAttr(%s, %s); %s' % (
4849 self.module.py_result(),
4851 code.error_goto_if_null(self.item.result(), self.pos)))
4852 code.put_gotref(self.item.py_result())
4853 if coerced_item is None:
4854 target.generate_assignment_code(self.item, code)
4856 coerced_item.allocate_temp_result(code)
4857 coerced_item.generate_result_code(code)
4858 target.generate_assignment_code(coerced_item, code)
4859 if self.item.result() != coerced_item.result():
4860 code.put_decref_clear(self.item.result(), self.item.type)
4861 self.module.generate_disposal_code(code)
4862 self.module.free_temps(code)
4866 #------------------------------------------------------------------------------------
4868 # Runtime support code
4870 #------------------------------------------------------------------------------------
4872 utility_function_predeclarations = \
4875 #define INLINE __inline__
4877 #define INLINE __inline
4882 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4886 static int %(skip_dispatch_cname)s = 0;
4888 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4890 if Options.gcc_branch_hints:
4891 branch_prediction_macros = \
4894 /* Test for GCC > 2.95 */
4895 #if __GNUC__ > 2 || \
4896 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4897 #define likely(x) __builtin_expect(!!(x), 1)
4898 #define unlikely(x) __builtin_expect(!!(x), 0)
4899 #else /* __GNUC__ > 2 ... */
4900 #define likely(x) (x)
4901 #define unlikely(x) (x)
4902 #endif /* __GNUC__ > 2 ... */
4903 #else /* __GNUC__ */
4904 #define likely(x) (x)
4905 #define unlikely(x) (x)
4906 #endif /* __GNUC__ */
4909 branch_prediction_macros = \
4911 #define likely(x) (x)
4912 #define unlikely(x) (x)
4915 #get_name_predeclaration = \
4916 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4918 #get_name_interned_predeclaration = \
4919 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4921 #------------------------------------------------------------------------------------
4923 printing_utility_code = UtilityCode(
4925 static int __Pyx_Print(PyObject *, int); /*proto*/
4926 #if PY_MAJOR_VERSION >= 3
4927 static PyObject* %s = 0;
4928 static PyObject* %s = 0;
4930 """ % (Naming.print_function, Naming.print_function_kwargs),
4932 #if PY_MAJOR_VERSION < 3
4933 static PyObject *__Pyx_GetStdout(void) {
4934 PyObject *f = PySys_GetObject((char *)"stdout");
4936 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4941 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4946 if (!(f = __Pyx_GetStdout()))
4948 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4949 if (PyFile_SoftSpace(f, 1)) {
4950 if (PyFile_WriteString(" ", f) < 0)
4953 v = PyTuple_GET_ITEM(arg_tuple, i);
4954 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4956 if (PyString_Check(v)) {
4957 char *s = PyString_AsString(v);
4958 Py_ssize_t len = PyString_Size(v);
4960 isspace(Py_CHARMASK(s[len-1])) &&
4962 PyFile_SoftSpace(f, 0);
4966 if (PyFile_WriteString("\n", f) < 0)
4968 PyFile_SoftSpace(f, 0);
4973 #else /* Python 3 has a print function */
4975 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4976 PyObject* kwargs = 0;
4977 PyObject* result = 0;
4978 PyObject* end_string;
4979 if (!%(PRINT_FUNCTION)s) {
4980 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4981 if (!%(PRINT_FUNCTION)s)
4985 if (!%(PRINT_KWARGS)s) {
4986 %(PRINT_KWARGS)s = PyDict_New();
4987 if (!%(PRINT_KWARGS)s)
4989 end_string = PyUnicode_FromStringAndSize(" ", 1);
4992 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4993 Py_DECREF(end_string);
4996 Py_DECREF(end_string);
4998 kwargs = %(PRINT_KWARGS)s;
5000 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5008 """ % {'BUILTINS' : Naming.builtins_cname,
5009 'PRINT_FUNCTION' : Naming.print_function,
5010 'PRINT_KWARGS' : Naming.print_function_kwargs}
5014 printing_one_utility_code = UtilityCode(
5016 static int __Pyx_PrintOne(PyObject *o); /*proto*/
5019 #if PY_MAJOR_VERSION < 3
5021 static int __Pyx_PrintOne(PyObject *o) {
5023 if (!(f = __Pyx_GetStdout()))
5025 if (PyFile_SoftSpace(f, 0)) {
5026 if (PyFile_WriteString(" ", f) < 0)
5029 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5031 if (PyFile_WriteString("\n", f) < 0)
5034 /* the line below is just to avoid compiler
5035 * compiler warnings about unused functions */
5036 return __Pyx_Print(NULL, 0);
5039 #else /* Python 3 has a print function */
5041 static int __Pyx_PrintOne(PyObject *o) {
5043 PyObject* arg_tuple = PyTuple_New(1);
5044 if (unlikely(!arg_tuple))
5047 PyTuple_SET_ITEM(arg_tuple, 0, o);
5048 res = __Pyx_Print(arg_tuple, 1);
5049 Py_DECREF(arg_tuple);
5055 requires=[printing_utility_code])
5059 #------------------------------------------------------------------------------------
5061 # The following function is based on do_raise() from ceval.c.
5063 raise_utility_code = UtilityCode(
5065 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5068 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5072 /* First, check the traceback argument, replacing None with NULL. */
5073 if (tb == Py_None) {
5077 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5078 PyErr_SetString(PyExc_TypeError,
5079 "raise: arg 3 must be a traceback or None");
5082 /* Next, replace a missing value with None */
5083 if (value == NULL) {
5087 #if PY_VERSION_HEX < 0x02050000
5088 if (!PyClass_Check(type))
5090 if (!PyType_Check(type))
5093 /* Raising an instance. The value should be a dummy. */
5094 if (value != Py_None) {
5095 PyErr_SetString(PyExc_TypeError,
5096 "instance exception may not have a separate value");
5099 /* Normalize to raise <class>, <instance> */
5102 #if PY_VERSION_HEX < 0x02050000
5103 if (PyInstance_Check(type)) {
5104 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5109 PyErr_SetString(PyExc_TypeError,
5110 "raise: exception must be an old-style class or instance");
5114 type = (PyObject*) Py_TYPE(type);
5116 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5117 PyErr_SetString(PyExc_TypeError,
5118 "raise: exception class must be a subclass of BaseException");
5123 __Pyx_ErrRestore(type, value, tb);
5133 #------------------------------------------------------------------------------------
5135 reraise_utility_code = UtilityCode(
5137 static void __Pyx_ReRaise(void); /*proto*/
5140 static void __Pyx_ReRaise(void) {
5141 PyThreadState *tstate = PyThreadState_GET();
5142 PyObject* tmp_type = tstate->curexc_type;
5143 PyObject* tmp_value = tstate->curexc_value;
5144 PyObject* tmp_tb = tstate->curexc_traceback;
5145 tstate->curexc_type = tstate->exc_type;
5146 tstate->curexc_value = tstate->exc_value;
5147 tstate->curexc_traceback = tstate->exc_traceback;
5148 tstate->exc_type = 0;
5149 tstate->exc_value = 0;
5150 tstate->exc_traceback = 0;
5151 Py_XDECREF(tmp_type);
5152 Py_XDECREF(tmp_value);
5157 #------------------------------------------------------------------------------------
5159 arg_type_test_utility_code = UtilityCode(
5161 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5162 const char *name, int exact); /*proto*/
5165 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5166 const char *name, int exact)
5169 PyErr_Format(PyExc_SystemError, "Missing type object");
5172 if (none_allowed && obj == Py_None) return 1;
5174 if (Py_TYPE(obj) == type) return 1;
5177 if (PyObject_TypeCheck(obj, type)) return 1;
5179 PyErr_Format(PyExc_TypeError,
5180 "Argument '%s' has incorrect type (expected %s, got %s)",
5181 name, type->tp_name, Py_TYPE(obj)->tp_name);
5186 #------------------------------------------------------------------------------------
5188 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5189 # many or too few positional arguments were found. This handles
5190 # Py_ssize_t formatting correctly.
5192 raise_argtuple_invalid_utility_code = UtilityCode(
5194 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5195 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5198 static void __Pyx_RaiseArgtupleInvalid(
5199 const char* func_name,
5203 Py_ssize_t num_found)
5205 Py_ssize_t num_expected;
5206 const char *number, *more_or_less;
5208 if (num_found < num_min) {
5209 num_expected = num_min;
5210 more_or_less = "at least";
5212 num_expected = num_max;
5213 more_or_less = "at most";
5216 more_or_less = "exactly";
5218 number = (num_expected == 1) ? "" : "s";
5219 PyErr_Format(PyExc_TypeError,
5220 #if PY_VERSION_HEX < 0x02050000
5221 "%s() takes %s %d positional argument%s (%d given)",
5223 "%s() takes %s %zd positional argument%s (%zd given)",
5225 func_name, more_or_less, num_expected, number, num_found);
5229 raise_keyword_required_utility_code = UtilityCode(
5231 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5234 static INLINE void __Pyx_RaiseKeywordRequired(
5235 const char* func_name,
5238 PyErr_Format(PyExc_TypeError,
5239 #if PY_MAJOR_VERSION >= 3
5240 "%s() needs keyword-only argument %U", func_name, kw_name);
5242 "%s() needs keyword-only argument %s", func_name,
5243 PyString_AS_STRING(kw_name));
5248 raise_double_keywords_utility_code = UtilityCode(
5250 static void __Pyx_RaiseDoubleKeywordsError(
5251 const char* func_name, PyObject* kw_name); /*proto*/
5254 static void __Pyx_RaiseDoubleKeywordsError(
5255 const char* func_name,
5258 PyErr_Format(PyExc_TypeError,
5259 #if PY_MAJOR_VERSION >= 3
5260 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5262 "%s() got multiple values for keyword argument '%s'", func_name,
5263 PyString_AS_STRING(kw_name));
5268 #------------------------------------------------------------------------------------
5270 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5271 # were passed to a function, or if any keywords were passed to a
5272 # function that does not accept them.
5274 keyword_string_check_utility_code = UtilityCode(
5276 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5277 const char* function_name, int kw_allowed); /*proto*/
5280 static INLINE int __Pyx_CheckKeywordStrings(
5282 const char* function_name,
5287 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5288 #if PY_MAJOR_VERSION < 3
5289 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5291 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5293 goto invalid_keyword_type;
5295 if ((!kw_allowed) && unlikely(key))
5296 goto invalid_keyword;
5298 invalid_keyword_type:
5299 PyErr_Format(PyExc_TypeError,
5300 "%s() keywords must be strings", function_name);
5303 PyErr_Format(PyExc_TypeError,
5304 #if PY_MAJOR_VERSION < 3
5305 "%s() got an unexpected keyword argument '%s'",
5306 function_name, PyString_AsString(key));
5308 "%s() got an unexpected keyword argument '%U'",
5309 function_name, key);
5315 #------------------------------------------------------------------------------------
5317 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5318 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5319 # keywords will raise an invalid keyword error.
5321 # Three kinds of errors are checked: 1) non-string keywords, 2)
5322 # unexpected keywords and 3) overlap with positional arguments.
5324 # If num_posargs is greater 0, it denotes the number of positional
5325 # arguments that were passed and that must therefore not appear
5326 # amongst the keywords as well.
5328 # This method does not check for required keyword arguments.
5331 parse_keywords_utility_code = UtilityCode(
5333 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5334 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5335 const char* function_name); /*proto*/
5338 static int __Pyx_ParseOptionalKeywords(
5340 PyObject **argnames[],
5343 Py_ssize_t num_pos_args,
5344 const char* function_name)
5346 PyObject *key = 0, *value = 0;
5349 PyObject*** first_kw_arg = argnames + num_pos_args;
5351 while (PyDict_Next(kwds, &pos, &key, &value)) {
5352 name = first_kw_arg;
5353 while (*name && (**name != key)) name++;
5355 values[name-argnames] = value;
5357 #if PY_MAJOR_VERSION < 3
5358 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5360 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5362 goto invalid_keyword_type;
5364 for (name = first_kw_arg; *name; name++) {
5365 #if PY_MAJOR_VERSION >= 3
5366 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5367 PyUnicode_Compare(**name, key) == 0) break;
5369 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5370 _PyString_Eq(**name, key)) break;
5374 values[name-argnames] = value;
5376 /* unexpected keyword found */
5377 for (name=argnames; name != first_kw_arg; name++) {
5378 if (**name == key) goto arg_passed_twice;
5379 #if PY_MAJOR_VERSION >= 3
5380 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5381 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5383 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5384 _PyString_Eq(**name, key)) goto arg_passed_twice;
5388 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5390 goto invalid_keyword;
5398 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5400 invalid_keyword_type:
5401 PyErr_Format(PyExc_TypeError,
5402 "%s() keywords must be strings", function_name);
5405 PyErr_Format(PyExc_TypeError,
5406 #if PY_MAJOR_VERSION < 3
5407 "%s() got an unexpected keyword argument '%s'",
5408 function_name, PyString_AsString(key));
5410 "%s() got an unexpected keyword argument '%U'",
5411 function_name, key);
5418 #------------------------------------------------------------------------------------
5420 traceback_utility_code = UtilityCode(
5422 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5425 #include "compile.h"
5426 #include "frameobject.h"
5427 #include "traceback.h"
5429 static void __Pyx_AddTraceback(const char *funcname) {
5430 PyObject *py_srcfile = 0;
5431 PyObject *py_funcname = 0;
5432 PyObject *py_globals = 0;
5433 PyCodeObject *py_code = 0;
5434 PyFrameObject *py_frame = 0;
5436 #if PY_MAJOR_VERSION < 3
5437 py_srcfile = PyString_FromString(%(FILENAME)s);
5439 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5441 if (!py_srcfile) goto bad;
5443 #if PY_MAJOR_VERSION < 3
5444 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5446 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5450 #if PY_MAJOR_VERSION < 3
5451 py_funcname = PyString_FromString(funcname);
5453 py_funcname = PyUnicode_FromString(funcname);
5456 if (!py_funcname) goto bad;
5457 py_globals = PyModule_GetDict(%(GLOBALS)s);
5458 if (!py_globals) goto bad;
5459 py_code = PyCode_New(
5460 0, /*int argcount,*/
5461 #if PY_MAJOR_VERSION >= 3
5462 0, /*int kwonlyargcount,*/
5465 0, /*int stacksize,*/
5467 %(EMPTY_BYTES)s, /*PyObject *code,*/
5468 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5469 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5470 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5471 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5472 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5473 py_srcfile, /*PyObject *filename,*/
5474 py_funcname, /*PyObject *name,*/
5475 %(LINENO)s, /*int firstlineno,*/
5476 %(EMPTY_BYTES)s /*PyObject *lnotab*/
5478 if (!py_code) goto bad;
5479 py_frame = PyFrame_New(
5480 PyThreadState_GET(), /*PyThreadState *tstate,*/
5481 py_code, /*PyCodeObject *code,*/
5482 py_globals, /*PyObject *globals,*/
5483 0 /*PyObject *locals*/
5485 if (!py_frame) goto bad;
5486 py_frame->f_lineno = %(LINENO)s;
5487 PyTraceBack_Here(py_frame);
5489 Py_XDECREF(py_srcfile);
5490 Py_XDECREF(py_funcname);
5491 Py_XDECREF(py_code);
5492 Py_XDECREF(py_frame);
5495 'FILENAME': Naming.filename_cname,
5496 'LINENO': Naming.lineno_cname,
5497 'CFILENAME': Naming.cfilenm_cname,
5498 'CLINENO': Naming.clineno_cname,
5499 'GLOBALS': Naming.module_cname,
5500 'EMPTY_TUPLE' : Naming.empty_tuple,
5501 'EMPTY_BYTES' : Naming.empty_bytes,
5504 restore_exception_utility_code = UtilityCode(
5506 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5507 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5510 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5511 PyObject *tmp_type, *tmp_value, *tmp_tb;
5512 PyThreadState *tstate = PyThreadState_GET();
5514 #if PY_MAJOR_VERSION >= 3
5515 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5516 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5517 tmp_type = tstate->exc_type;
5518 tmp_value = tstate->exc_value;
5519 tmp_tb = tstate->exc_traceback;
5520 PyErr_NormalizeException(&type, &value, &tb);
5521 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5522 tstate->exc_type = 0;
5523 tstate->exc_value = 0;
5524 tstate->exc_traceback = 0;
5525 PyException_SetContext(value, tmp_value);
5526 Py_DECREF(tmp_type);
5531 tmp_type = tstate->curexc_type;
5532 tmp_value = tstate->curexc_value;
5533 tmp_tb = tstate->curexc_traceback;
5534 tstate->curexc_type = type;
5535 tstate->curexc_value = value;
5536 tstate->curexc_traceback = tb;
5537 Py_XDECREF(tmp_type);
5538 Py_XDECREF(tmp_value);
5542 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5543 PyThreadState *tstate = PyThreadState_GET();
5544 *type = tstate->curexc_type;
5545 *value = tstate->curexc_value;
5546 *tb = tstate->curexc_traceback;
5548 tstate->curexc_type = 0;
5549 tstate->curexc_value = 0;
5550 tstate->curexc_traceback = 0;
5555 #------------------------------------------------------------------------------------
5557 unraisable_exception_utility_code = UtilityCode(
5559 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5562 static void __Pyx_WriteUnraisable(const char *name) {
5563 PyObject *old_exc, *old_val, *old_tb;
5565 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5566 #if PY_MAJOR_VERSION < 3
5567 ctx = PyString_FromString(name);
5569 ctx = PyUnicode_FromString(name);
5571 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5573 PyErr_WriteUnraisable(Py_None);
5575 PyErr_WriteUnraisable(ctx);
5580 requires=[restore_exception_utility_code])
5582 #------------------------------------------------------------------------------------
5584 set_vtable_utility_code = UtilityCode(
5586 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5589 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5590 PyObject *pycobj = 0;
5593 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5596 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5609 #------------------------------------------------------------------------------------
5611 get_vtable_utility_code = UtilityCode(
5613 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5616 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5620 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5623 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5624 if (!*(void **)vtabptr)
5637 #------------------------------------------------------------------------------------
5639 init_string_tab_utility_code = UtilityCode(
5641 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5644 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5646 #if PY_MAJOR_VERSION < 3
5647 if (t->is_unicode && (!t->is_identifier)) {
5648 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5649 } else if (t->intern) {
5650 *t->p = PyString_InternFromString(t->s);
5652 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5654 #else /* Python 3+ has unicode identifiers */
5655 if (t->is_identifier || (t->is_unicode && t->intern)) {
5656 *t->p = PyUnicode_InternFromString(t->s);
5657 } else if (t->is_unicode) {
5658 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5660 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5671 #------------------------------------------------------------------------------------
5673 get_exception_utility_code = UtilityCode(
5675 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5678 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5679 PyObject *tmp_type, *tmp_value, *tmp_tb;
5680 PyThreadState *tstate = PyThreadState_GET();
5681 *type = tstate->curexc_type;
5682 *value = tstate->curexc_value;
5683 *tb = tstate->curexc_traceback;
5684 tstate->curexc_type = 0;
5685 tstate->curexc_value = 0;
5686 tstate->curexc_traceback = 0;
5687 PyErr_NormalizeException(type, value, tb);
5688 if (PyErr_Occurred())
5693 tmp_type = tstate->exc_type;
5694 tmp_value = tstate->exc_value;
5695 tmp_tb = tstate->exc_traceback;
5696 tstate->exc_type = *type;
5697 tstate->exc_value = *value;
5698 tstate->exc_traceback = *tb;
5699 /* Make sure tstate is in a consistent state when we XDECREF
5700 these objects (XDECREF may run arbitrary code). */
5701 Py_XDECREF(tmp_type);
5702 Py_XDECREF(tmp_value);
5714 #------------------------------------------------------------------------------------
5716 get_exception_tuple_utility_code = UtilityCode(proto="""
5717 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5720 static PyObject *__Pyx_GetExceptionTuple(void) {
5721 PyObject *type = NULL, *value = NULL, *tb = NULL;
5722 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5723 PyObject* exc_info = PyTuple_New(3);
5728 PyTuple_SET_ITEM(exc_info, 0, type);
5729 PyTuple_SET_ITEM(exc_info, 1, value);
5730 PyTuple_SET_ITEM(exc_info, 2, tb);
5737 requires=[get_exception_utility_code])
5739 #------------------------------------------------------------------------------------
5741 reset_exception_utility_code = UtilityCode(
5743 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5744 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5747 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5748 PyThreadState *tstate = PyThreadState_GET();
5749 *type = tstate->exc_type;
5750 *value = tstate->exc_value;
5751 *tb = tstate->exc_traceback;
5757 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5758 PyObject *tmp_type, *tmp_value, *tmp_tb;
5759 PyThreadState *tstate = PyThreadState_GET();
5760 tmp_type = tstate->exc_type;
5761 tmp_value = tstate->exc_value;
5762 tmp_tb = tstate->exc_traceback;
5763 tstate->exc_type = type;
5764 tstate->exc_value = value;
5765 tstate->exc_traceback = tb;
5766 Py_XDECREF(tmp_type);
5767 Py_XDECREF(tmp_value);
5772 #------------------------------------------------------------------------------------
5774 force_init_threads_utility_code = UtilityCode(
5776 #ifndef __PYX_FORCE_INIT_THREADS
5777 #if PY_VERSION_HEX < 0x02040200
5778 #define __PYX_FORCE_INIT_THREADS 1
5780 #define __PYX_FORCE_INIT_THREADS 0
5785 #------------------------------------------------------------------------------------
5787 # Note that cPython ignores PyTrace_EXCEPTION,
5788 # but maybe some other profilers don't.
5790 trace_utility_code = UtilityCode(proto="""
5791 #define CYTHON_TRACING 1
5792 #define CYTHON_TRACING_REUSE_FRAME 0
5796 #include "compile.h"
5797 #include "frameobject.h"
5798 #include "traceback.h"
5800 #if CYTHON_TRACING_REUSE_FRAME
5801 #define CYTHON_FRAME_MODIFIER static
5802 #define CYTHON_FRAME_DEL
5804 #define CYTHON_FRAME_MODIFIER
5805 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
5808 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
5809 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
5810 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
5811 int __Pyx_use_tracing = 0; \\
5812 if (PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5813 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
5816 #define __Pyx_TraceException() \\
5817 if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5818 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
5820 PyThreadState_GET()->c_profilefunc( \\
5821 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
5822 Py_DECREF(exc_info); \\
5826 #define __Pyx_TraceReturn(result) \\
5827 if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5828 PyThreadState_GET()->c_profilefunc( \\
5829 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
5830 CYTHON_FRAME_DEL; \\
5833 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
5834 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
5837 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
5838 #define __Pyx_TraceException()
5839 #define __Pyx_TraceReturn(result)
5840 #endif /* CYTHON_TRACING */
5843 "FRAME": Naming.frame_cname,
5844 "FRAME_CODE": Naming.frame_code_cname,
5850 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
5851 PyFrameObject** frame,
5852 const char *funcname,
5853 const char *srcfile,
5855 if (*frame == NULL || !CYTHON_TRACING_REUSE_FRAME) {
5856 if (*code == NULL) {
5857 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
5858 if (*code == NULL) return 0;
5860 *frame = PyFrame_New(
5861 PyThreadState_GET(), /*PyThreadState *tstate*/
5862 *code, /*PyCodeObject *code*/
5863 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
5864 0 /*PyObject *locals*/
5866 if (*frame == NULL) return 0;
5869 (*frame)->f_tstate = PyThreadState_GET();
5871 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
5874 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
5875 PyObject *py_srcfile = 0;
5876 PyObject *py_funcname = 0;
5877 PyCodeObject *py_code = 0;
5879 #if PY_MAJOR_VERSION < 3
5880 py_funcname = PyString_FromString(funcname);
5881 py_srcfile = PyString_FromString(srcfile);
5883 py_funcname = PyUnicode_FromString(funcname);
5884 py_srcfile = PyUnicode_FromString(srcfile);
5886 if (!py_funcname | !py_srcfile) goto bad;
5888 py_code = PyCode_New(
5889 0, /*int argcount,*/
5890 #if PY_MAJOR_VERSION >= 3
5891 0, /*int kwonlyargcount,*/
5894 0, /*int stacksize,*/
5896 %(EMPTY_BYTES)s, /*PyObject *code,*/
5897 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5898 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5899 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5900 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5901 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5902 py_srcfile, /*PyObject *filename,*/
5903 py_funcname, /*PyObject *name,*/
5904 firstlineno, /*int firstlineno,*/
5905 %(EMPTY_BYTES)s /*PyObject *lnotab*/
5909 Py_XDECREF(py_srcfile);
5910 Py_XDECREF(py_funcname);
5915 #endif /* CYTHON_TRACING */
5917 'EMPTY_TUPLE' : Naming.empty_tuple,
5918 'EMPTY_BYTES' : Naming.empty_bytes,
5919 "MODULE": Naming.module_cname,