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()
1010 for arg in self.args:
1014 if not hasattr(arg, 'default_entry'):
1015 arg.default.analyse_types(env)
1016 arg.default = arg.default.coerce_to(arg.type, genv)
1017 if arg.default.is_literal:
1018 arg.default_entry = arg.default
1019 arg.default_result_code = arg.default.calculate_result_code()
1020 if arg.default.type != arg.type and not arg.type.is_int:
1021 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
1023 arg.default.allocate_temps(genv)
1024 arg.default_entry = genv.add_default_value(arg.type)
1025 if arg.type.is_pyobject:
1026 arg.default_entry.init = 0
1027 arg.default_entry.used = 1
1028 arg.default_result_code = arg.default_entry.cname
1031 "This argument cannot have a default value")
1036 error(arg.pos, "Non-default argument following default argument")
1038 def need_gil_acquisition(self, lenv):
1041 def create_local_scope(self, env):
1043 while env.is_py_class_scope or env.is_c_class_scope:
1044 env = env.outer_scope
1045 if self.needs_closure:
1046 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1048 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1049 lenv.return_type = self.return_type
1050 type = self.entry.type
1051 if type.is_cfunction:
1052 lenv.nogil = type.nogil and not type.with_gil
1053 self.local_scope = lenv
1054 lenv.directives = env.directives
1057 def generate_function_definitions(self, env, code):
1060 lenv = self.local_scope
1062 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1063 self.entry.scope.is_c_class_scope)
1065 if code.globalstate.directives['profile'] is None:
1066 profile = 'inline' not in self.modifiers and not lenv.nogil
1068 profile = code.globalstate.directives['profile']
1069 if profile and lenv.nogil:
1070 error(self.pos, "Cannot profile nogil function.")
1072 code.globalstate.use_utility_code(trace_utility_code)
1074 # Generate C code for header and body of function
1075 code.enter_cfunc_scope()
1076 code.return_from_error_cleanup_label = code.new_label()
1078 # ----- Top-level constants used by this function
1079 code.mark_pos(self.pos)
1080 self.generate_interned_num_decls(lenv, code)
1081 self.generate_interned_string_decls(lenv, code)
1082 self.generate_py_string_decls(lenv, code)
1083 self.generate_cached_builtins_decls(lenv, code)
1085 #code.put_var_declarations(lenv.const_entries, static = 1)
1086 self.generate_const_definitions(lenv, code)
1087 # ----- Function header
1090 self.py_func.generate_function_header(code,
1091 with_pymethdef = env.is_py_class_scope,
1093 self.generate_function_header(code,
1094 with_pymethdef = env.is_py_class_scope)
1095 # ----- Local variable declarations
1096 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1097 self.generate_argument_declarations(lenv, code)
1098 if self.needs_closure:
1099 code.putln("/* TODO: declare and create scope object */")
1100 code.put_var_declarations(lenv.var_entries)
1102 if not self.return_type.is_void:
1103 if self.return_type.is_pyobject:
1107 (self.return_type.declaration_code(
1108 Naming.retval_cname),
1110 tempvardecl_code = code.insertion_point()
1111 self.generate_keyword_list(code)
1112 # ----- Extern library function declarations
1113 lenv.generate_library_function_declarations(code)
1114 # ----- GIL acquisition
1115 acquire_gil = self.acquire_gil
1117 env.use_utility_code(force_init_threads_utility_code)
1118 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1119 # ----- Automatic lead-ins for certain special functions
1121 code.put_trace_call(self.entry.name, self.pos)
1123 code.put_setup_refcount_context(self.entry.name)
1124 if is_getbuffer_slot:
1125 self.getbuffer_init(code)
1126 # ----- Fetch arguments
1127 self.generate_argument_parsing_code(env, code)
1128 # If an argument is assigned to in the body, we must
1129 # incref it to properly keep track of refcounts.
1130 for entry in lenv.arg_entries:
1131 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1132 code.put_var_incref(entry)
1133 # ----- Initialise local variables
1134 for entry in lenv.var_entries:
1135 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1136 code.put_init_var_to_py_none(entry)
1137 # ----- Initialise local buffer auxiliary variables
1138 for entry in lenv.var_entries + lenv.arg_entries:
1139 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1140 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1141 # ----- Check and convert arguments
1142 self.generate_argument_type_tests(code)
1143 # ----- Acquire buffer arguments
1144 for entry in lenv.arg_entries:
1145 if entry.type.is_buffer:
1146 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1147 # ----- Function body
1148 self.body.generate_execution_code(code)
1149 # ----- Default return value
1151 if self.return_type.is_pyobject:
1152 #if self.return_type.is_extension_type:
1153 # lhs = "(PyObject *)%s" % Naming.retval_cname
1155 lhs = Naming.retval_cname
1156 code.put_init_to_py_none(lhs, self.return_type)
1158 val = self.return_type.default_value
1160 code.putln("%s = %s;" % (Naming.retval_cname, val))
1161 # ----- Error cleanup
1162 if code.error_label in code.labels_used:
1163 code.put_goto(code.return_label)
1164 code.put_label(code.error_label)
1165 # cleanup temps the old way
1166 code.put_var_xdecrefs(lenv.temp_entries)
1167 # cleanup temps the new way
1168 for cname, type in code.funcstate.all_managed_temps():
1169 code.put_xdecref(cname, type)
1171 # Clean up buffers -- this calls a Python function
1172 # so need to save and restore error state
1173 buffers_present = len(lenv.buffer_entries) > 0
1175 code.globalstate.use_utility_code(restore_exception_utility_code)
1176 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1177 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1178 for entry in lenv.buffer_entries:
1179 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1180 #code.putln("%s = 0;" % entry.cname)
1181 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1183 err_val = self.error_value()
1184 exc_check = self.caller_will_check_exceptions()
1185 if err_val is not None or exc_check:
1186 # TODO: Fix exception tracing (though currently unused by cProfile).
1187 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1188 # code.put_trace_exception()
1189 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1191 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1192 % self.entry.qualified_name, 0)
1194 '__Pyx_WriteUnraisable("%s");' %
1195 self.entry.qualified_name)
1196 env.use_utility_code(unraisable_exception_utility_code)
1197 env.use_utility_code(restore_exception_utility_code)
1198 default_retval = self.return_type.default_value
1199 if err_val is None and default_retval:
1200 err_val = default_retval
1201 if err_val is not None:
1204 Naming.retval_cname,
1207 if is_getbuffer_slot:
1208 self.getbuffer_error_cleanup(code)
1210 # If we are using the non-error cleanup section we should
1211 # jump past it if we have an error. The if-test below determine
1212 # whether this section is used.
1213 if buffers_present or is_getbuffer_slot:
1214 code.put_goto(code.return_from_error_cleanup_label)
1217 # ----- Non-error return cleanup
1218 code.put_label(code.return_label)
1219 for entry in lenv.buffer_entries:
1221 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1222 if is_getbuffer_slot:
1223 self.getbuffer_normal_cleanup(code)
1224 # ----- Return cleanup for both error and no-error return
1225 code.put_label(code.return_from_error_cleanup_label)
1226 if not Options.init_local_none:
1227 for entry in lenv.var_entries:
1228 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1229 entry.xdecref_cleanup = 1
1230 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1231 # Decref any increfed args
1232 for entry in lenv.arg_entries:
1233 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1234 code.put_var_decref(entry)
1236 # code.putln("/* TODO: decref scope object */")
1238 # This code is duplicated in ModuleNode.generate_module_init_func
1240 default_retval = self.return_type.default_value
1241 err_val = self.error_value()
1242 if err_val is None and default_retval:
1243 err_val = default_retval
1244 if self.return_type.is_pyobject:
1245 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1247 code.put_finish_refcount_context()
1249 if self.entry.is_special and self.entry.name == "__hash__":
1250 # Returning -1 for __hash__ is supposed to signal an error
1251 # We do as Python instances and coerce -1 into -2.
1252 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
1255 if self.return_type.is_pyobject:
1256 code.put_trace_return(Naming.retval_cname)
1258 code.put_trace_return("Py_None")
1261 code.putln("PyGILState_Release(_save);")
1263 if not self.return_type.is_void:
1264 code.putln("return %s;" % Naming.retval_cname)
1267 # ----- Go back and insert temp variable declarations
1268 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1269 tempvardecl_code.put_temp_declarations(code.funcstate)
1270 # ----- Python version
1271 code.exit_cfunc_scope()
1273 self.py_func.generate_function_definitions(env, code)
1274 self.generate_wrapper_functions(code)
1276 def declare_argument(self, env, arg):
1277 if arg.type.is_void:
1278 error(arg.pos, "Invalid use of 'void'")
1279 elif not arg.type.is_complete() and not arg.type.is_array:
1281 "Argument type '%s' is incomplete" % arg.type)
1282 return env.declare_arg(arg.name, arg.type, arg.pos)
1284 def generate_wrapper_functions(self, code):
1287 def generate_execution_code(self, code):
1288 # Evaluate and store argument default values
1289 for arg in self.args:
1290 default = arg.default
1292 if not default.is_literal:
1293 default.generate_evaluation_code(code)
1294 default.make_owned_reference(code)
1297 arg.default_entry.cname,
1298 default.result_as(arg.default_entry.type)))
1299 if default.is_temp and default.type.is_pyobject:
1300 code.putln("%s = 0;" % default.result())
1301 default.free_temps(code)
1302 code.put_var_giveref(arg.default_entry)
1303 # For Python class methods, create and store function object
1305 self.assmt.generate_execution_code(code)
1308 # Special code for the __getbuffer__ function
1310 def getbuffer_init(self, code):
1311 info = self.local_scope.arg_entries[1].cname
1312 # Python 3.0 betas have a bug in memoryview which makes it call
1313 # getbuffer with a NULL parameter. For now we work around this;
1314 # the following line should be removed when this bug is fixed.
1315 code.putln("if (%s == NULL) return 0;" % info)
1316 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1317 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1319 def getbuffer_error_cleanup(self, code):
1320 info = self.local_scope.arg_entries[1].cname
1321 code.put_gotref("%s->obj" % info)
1322 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1325 def getbuffer_normal_cleanup(self, code):
1326 info = self.local_scope.arg_entries[1].cname
1327 code.putln("if (%s->obj == Py_None) {" % info)
1328 code.put_gotref("Py_None")
1329 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1332 class CFuncDefNode(FuncDefNode):
1333 # C function definition.
1335 # modifiers ['inline']
1336 # visibility 'private' or 'public' or 'extern'
1337 # base_type CBaseTypeNode
1338 # declarator CDeclaratorNode
1341 # decorators [DecoratorNode] list of decorators
1343 # with_gil boolean Acquire GIL around body
1345 # py_func wrapper for calling from Python
1346 # overridable whether or not this is a cpdef function
1347 # inline_in_pxd whether this is an inline function in a pxd file
1349 child_attrs = ["base_type", "declarator", "body", "py_func"]
1351 inline_in_pxd = False
1353 directive_locals = {}
1355 def unqualified_name(self):
1356 return self.entry.name
1358 def analyse_declarations(self, env):
1359 self.directive_locals.update(env.directives['locals'])
1360 base_type = self.base_type.analyse(env)
1361 # The 2 here is because we need both function and argument names.
1362 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1363 if not type.is_cfunction:
1365 "Suite attached to non-function declaration")
1366 # Remember the actual type according to the function header
1367 # written here, because the type in the symbol table entry
1368 # may be different if we're overriding a C method inherited
1369 # from the base type of an extension type.
1371 type.is_overridable = self.overridable
1372 declarator = self.declarator
1373 while not hasattr(declarator, 'args'):
1374 declarator = declarator.base
1375 self.args = declarator.args
1376 for formal_arg, type_arg in zip(self.args, type.args):
1377 formal_arg.type = type_arg.type
1378 formal_arg.name = type_arg.name
1379 formal_arg.cname = type_arg.cname
1380 name = name_declarator.name
1381 cname = name_declarator.cname
1382 self.entry = env.declare_cfunction(
1383 name, type, self.pos,
1384 cname = cname, visibility = self.visibility,
1385 defining = self.body is not None,
1386 api = self.api, modifiers = self.modifiers)
1387 self.entry.inline_func_in_pxd = self.inline_in_pxd
1388 self.return_type = type.return_type
1390 if self.overridable and not env.is_module_scope:
1391 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1392 # An error will be produced in the cdef function
1393 self.overridable = False
1395 if self.overridable:
1397 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1398 self.py_func = DefNode(pos = self.pos,
1399 name = self.entry.name,
1402 starstar_arg = None,
1404 body = py_func_body,
1406 self.py_func.is_module_scope = env.is_module_scope
1407 self.py_func.analyse_declarations(env)
1408 self.entry.as_variable = self.py_func.entry
1409 # Reset scope entry the above cfunction
1410 env.entries[name] = self.entry
1411 self.py_func.interned_attr_cname = env.intern_identifier(
1412 self.py_func.entry.name)
1413 if not env.is_module_scope or Options.lookup_module_cpdef:
1414 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1415 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1417 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1419 args = self.type.args
1420 if omit_optional_args:
1421 args = args[:len(args) - self.type.optional_arg_count]
1422 arg_names = [arg.name for arg in args]
1424 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1426 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1427 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1428 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1429 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)
1430 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1432 def declare_arguments(self, env):
1433 for arg in self.type.args:
1435 error(arg.pos, "Missing argument name")
1436 self.declare_argument(env, arg)
1438 def need_gil_acquisition(self, lenv):
1440 with_gil = self.type.with_gil
1441 if type.nogil and not with_gil:
1442 if type.return_type.is_pyobject:
1444 "Function with Python return type cannot be declared nogil")
1445 for entry in lenv.var_entries + lenv.temp_entries:
1446 if entry.type.is_pyobject:
1447 error(self.pos, "Function declared nogil has Python locals or temporaries")
1450 def analyse_expressions(self, env):
1451 self.local_scope.directives = env.directives
1452 self.analyse_default_values(env)
1453 if self.py_func is not None:
1454 self.py_func.analyse_expressions(env)
1455 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1457 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1460 visibility = self.entry.visibility
1461 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1462 arg_decls.append(arg.declaration_code())
1463 if with_dispatch and self.overridable:
1464 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1465 if type.optional_arg_count and with_opt_args:
1466 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1467 if type.has_varargs:
1468 arg_decls.append("...")
1470 arg_decls = ["void"]
1472 cname = self.entry.func_cname
1473 entity = type.function_header_code(cname, ', '.join(arg_decls))
1474 if visibility == 'public':
1475 dll_linkage = "DL_EXPORT"
1478 header = self.return_type.declaration_code(entity,
1479 dll_linkage = dll_linkage)
1480 if visibility == 'extern':
1481 storage_class = "%s " % Naming.extern_c_macro
1482 elif visibility == 'public':
1485 storage_class = "static "
1486 code.putln("%s%s %s {" % (
1488 ' '.join(self.modifiers).upper(), # macro forms
1491 def generate_argument_declarations(self, env, code):
1492 for arg in self.args:
1494 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1496 def generate_keyword_list(self, code):
1499 def generate_argument_parsing_code(self, env, code):
1501 if self.type.optional_arg_count:
1502 code.putln('if (%s) {' % Naming.optional_args_cname)
1503 for arg in self.args:
1505 # FIXME: simple name prefixing doesn't work when
1506 # argument name mangling is in place
1507 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1508 declarator = arg.declarator
1509 while not hasattr(declarator, 'name'):
1510 declarator = declarator.base
1511 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1513 for _ in range(self.type.optional_arg_count):
1517 def generate_argument_conversion_code(self, code):
1520 def generate_argument_type_tests(self, code):
1521 # Generate type tests for args whose type in a parent
1522 # class is a supertype of the declared type.
1523 for arg in self.type.args:
1524 if arg.needs_type_test:
1525 self.generate_arg_type_test(arg, code)
1527 def generate_arg_type_test(self, arg, code):
1528 # Generate type test for one argument.
1529 if arg.type.typeobj_is_available():
1530 typeptr_cname = arg.type.typeptr_cname
1531 arg_code = "((PyObject *)%s)" % arg.cname
1533 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1538 type.is_builtin_type,
1539 code.error_goto(arg.pos)))
1541 error(arg.pos, "Cannot test type of extern C class "
1542 "without type object name specification")
1544 def error_value(self):
1545 if self.return_type.is_pyobject:
1549 return self.entry.type.exception_value
1551 def caller_will_check_exceptions(self):
1552 return self.entry.type.exception_check
1554 def generate_wrapper_functions(self, code):
1555 # If the C signature of a function has changed, we need to generate
1556 # wrappers to put in the slots here.
1559 func_type = entry.type
1560 while entry.prev_entry is not None:
1562 entry = entry.prev_entry
1563 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1565 self.generate_function_header(code,
1567 with_dispatch = entry.type.is_overridable,
1568 with_opt_args = entry.type.optional_arg_count,
1569 cname = entry.func_cname)
1570 if not self.return_type.is_void:
1572 args = self.type.args
1573 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1574 if entry.type.is_overridable:
1575 arglist.append(Naming.skip_dispatch_cname)
1576 elif func_type.is_overridable:
1578 if entry.type.optional_arg_count:
1579 arglist.append(Naming.optional_args_cname)
1580 elif func_type.optional_arg_count:
1581 arglist.append('NULL')
1582 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1586 class PyArgDeclNode(Node):
1587 # Argument which must be a Python object (used
1588 # for * and ** arguments).
1591 # entry Symtab.Entry
1595 class DecoratorNode(Node):
1598 # decorator NameNode or CallNode
1599 child_attrs = ['decorator']
1602 class DefNode(FuncDefNode):
1603 # A Python function definition.
1605 # name string the Python name of the function
1606 # decorators [DecoratorNode] list of decorators
1607 # args [CArgDeclNode] formal arguments
1608 # star_arg PyArgDeclNode or None * argument
1609 # starstar_arg PyArgDeclNode or None ** argument
1610 # doc EncodedString or None
1613 # The following subnode is constructed internally
1614 # when the def statement is inside a Python class definition.
1616 # assmt AssignmentNode Function construction/assignment
1618 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1622 num_required_kw_args = 0
1623 reqd_kw_flags_cname = "0"
1630 def __init__(self, pos, **kwds):
1631 FuncDefNode.__init__(self, pos, **kwds)
1633 for arg in self.args:
1640 self.num_kwonly_args = k
1641 self.num_required_kw_args = rk
1642 self.num_required_args = r
1644 def as_cfunction(self, cfunc=None, scope=None):
1646 error(self.star_arg.pos, "cdef function cannot have star argument")
1647 if self.starstar_arg:
1648 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1651 for formal_arg in self.args:
1652 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1653 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1655 type = py_object_type,
1656 pos = formal_arg.pos))
1657 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1659 has_varargs = False,
1660 exception_value = None,
1661 exception_check = False,
1664 is_overridable = True)
1665 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1667 cfunc_type = cfunc.type
1668 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1669 error(self.pos, "wrong number of arguments")
1670 error(declarator.pos, "previous declaration here")
1671 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1672 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1673 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1674 formal_arg.type = type_arg.type
1675 formal_arg.name_declarator = name_declarator
1677 if cfunc_type.exception_value is None:
1678 exception_value = None
1680 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1681 declarator = CFuncDeclaratorNode(self.pos,
1682 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1684 has_varargs = False,
1685 exception_check = cfunc_type.exception_check,
1686 exception_value = exception_value,
1687 with_gil = cfunc_type.with_gil,
1688 nogil = cfunc_type.nogil)
1689 return CFuncDefNode(self.pos,
1691 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1692 declarator = declarator,
1695 overridable = cfunc_type.is_overridable,
1697 with_gil = cfunc_type.with_gil,
1698 nogil = cfunc_type.nogil,
1699 visibility = 'private',
1701 directive_locals = getattr(cfunc, 'directive_locals', {}))
1703 def analyse_declarations(self, env):
1704 directive_locals = self.directive_locals = env.directives['locals']
1705 for arg in self.args:
1706 if hasattr(arg, 'name'):
1708 name_declarator = None
1710 base_type = arg.base_type.analyse(env)
1711 name_declarator, type = \
1712 arg.declarator.analyse(base_type, env)
1713 arg.name = name_declarator.name
1714 if arg.name in directive_locals:
1715 type_node = directive_locals[arg.name]
1716 other_type = type_node.analyse_as_type(env)
1717 if other_type is None:
1718 error(type_node.pos, "Not a type")
1719 elif (type is not PyrexTypes.py_object_type
1720 and not type.same_as(other_type)):
1721 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1722 error(type_node.pos, "Previous declaration here")
1725 if name_declarator and name_declarator.cname:
1727 "Python function argument cannot have C name specification")
1728 arg.type = type.as_argument_type()
1730 arg.needs_conversion = 0
1731 arg.needs_type_test = 0
1733 if arg.not_none and not arg.type.is_extension_type:
1735 "Only extension type arguments can have 'not None'")
1736 self.declare_pyfunction(env)
1737 self.analyse_signature(env)
1738 self.return_type = self.entry.signature.return_type()
1740 def analyse_signature(self, env):
1741 any_type_tests_needed = 0
1742 if self.entry.is_special:
1743 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1744 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1745 # Use the simpler calling signature for zero- and one-argument functions.
1746 if self.entry.signature is TypeSlots.pyfunction_signature:
1747 if len(self.args) == 0:
1748 self.entry.signature = TypeSlots.pyfunction_noargs
1749 elif len(self.args) == 1:
1750 if self.args[0].default is None and not self.args[0].kw_only:
1751 self.entry.signature = TypeSlots.pyfunction_onearg
1752 elif self.entry.signature is TypeSlots.pymethod_signature:
1753 if len(self.args) == 1:
1754 self.entry.signature = TypeSlots.unaryfunc
1755 elif len(self.args) == 2:
1756 if self.args[1].default is None and not self.args[1].kw_only:
1757 self.entry.signature = TypeSlots.ibinaryfunc
1758 sig = self.entry.signature
1759 nfixed = sig.num_fixed_args()
1760 for i in range(nfixed):
1761 if i < len(self.args):
1764 if sig.is_self_arg(i):
1766 arg.hdr_type = arg.type = env.parent_type
1767 arg.needs_conversion = 0
1769 arg.hdr_type = sig.fixed_arg_type(i)
1770 if not arg.type.same_as(arg.hdr_type):
1771 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1772 arg.needs_type_test = 1
1773 any_type_tests_needed = 1
1775 arg.needs_conversion = 1
1776 if arg.needs_conversion:
1777 arg.hdr_cname = Naming.arg_prefix + arg.name
1779 arg.hdr_cname = Naming.var_prefix + arg.name
1781 self.bad_signature()
1783 if nfixed < len(self.args):
1784 if not sig.has_generic_args:
1785 self.bad_signature()
1786 for arg in self.args:
1787 if arg.is_generic and \
1788 (arg.type.is_extension_type or arg.type.is_builtin_type):
1789 arg.needs_type_test = 1
1790 any_type_tests_needed = 1
1791 if any_type_tests_needed:
1792 env.use_utility_code(arg_type_test_utility_code)
1794 def bad_signature(self):
1795 sig = self.entry.signature
1796 expected_str = "%d" % sig.num_fixed_args()
1797 if sig.has_generic_args:
1798 expected_str = expected_str + " or more"
1800 if name.startswith("__") and name.endswith("__"):
1801 desc = "Special method"
1805 "%s %s has wrong number of arguments "
1806 "(%d declared, %s expected)" % (
1807 desc, self.name, len(self.args), expected_str))
1809 def signature_has_nongeneric_args(self):
1810 argcount = len(self.args)
1811 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1815 def signature_has_generic_args(self):
1816 return self.entry.signature.has_generic_args
1818 def declare_pyfunction(self, env):
1819 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1821 entry = env.lookup_here(self.name)
1822 if entry and entry.type.is_cfunction and not self.is_wrapper:
1823 warning(self.pos, "Overriding cdef method with def method.", 5)
1824 entry = env.declare_pyfunction(self.name, self.pos)
1826 prefix = env.scope_prefix
1827 entry.func_cname = \
1828 Naming.pyfunc_prefix + prefix + name
1829 entry.pymethdef_cname = \
1830 Naming.pymethdef_prefix + prefix + name
1831 if Options.docstrings:
1832 entry.doc = embed_position(self.pos, self.doc)
1834 Naming.funcdoc_prefix + prefix + name
1838 def declare_arguments(self, env):
1839 for arg in self.args:
1841 error(arg.pos, "Missing argument name")
1842 if arg.needs_conversion:
1843 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1844 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1845 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1846 if arg.type.is_pyobject:
1847 arg.entry.init = "0"
1848 arg.entry.init_to_none = 0
1850 arg.entry = self.declare_argument(env, arg)
1852 arg.entry.is_self_arg = arg.is_self_arg
1853 if not arg.is_self_arg:
1854 arg.name_entry = env.get_string_const(
1855 arg.name, identifier = True)
1856 env.add_py_string(arg.name_entry, identifier = True)
1858 if arg.is_self_arg or \
1859 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1860 arg.entry.is_declared_generic = 1
1861 self.declare_python_arg(env, self.star_arg)
1862 self.declare_python_arg(env, self.starstar_arg)
1864 def declare_python_arg(self, env, arg):
1866 entry = env.declare_var(arg.name,
1867 PyrexTypes.py_object_type, arg.pos)
1870 entry.init_to_none = 0
1871 entry.xdecref_cleanup = 1
1873 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1875 def analyse_expressions(self, env):
1876 self.local_scope.directives = env.directives
1877 self.analyse_default_values(env)
1878 if env.is_py_class_scope:
1879 self.synthesize_assignment_node(env)
1881 def synthesize_assignment_node(self, env):
1883 self.assmt = SingleAssignmentNode(self.pos,
1884 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1885 rhs = ExprNodes.UnboundMethodNode(self.pos,
1886 class_cname = env.class_obj_cname,
1887 function = ExprNodes.PyCFunctionNode(self.pos,
1888 pymethdef_cname = self.entry.pymethdef_cname)))
1889 self.assmt.analyse_declarations(env)
1890 self.assmt.analyse_expressions(env)
1892 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1894 sig = self.entry.signature
1895 if sig.has_dummy_arg:
1896 arg_code_list.append(
1897 "PyObject *%s" % Naming.self_cname)
1898 for arg in self.args:
1899 if not arg.is_generic:
1901 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1903 arg_code_list.append(
1904 arg.hdr_type.declaration_code(arg.hdr_cname))
1905 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1906 arg_code_list.append("PyObject *unused")
1907 if sig.has_generic_args:
1908 arg_code_list.append(
1909 "PyObject *%s, PyObject *%s"
1910 % (Naming.args_cname, Naming.kwds_cname))
1911 arg_code = ", ".join(arg_code_list)
1912 dc = self.return_type.declaration_code(self.entry.func_cname)
1913 header = "static %s(%s)" % (dc, arg_code)
1914 code.putln("%s; /*proto*/" % header)
1917 if self.entry.doc and Options.docstrings:
1918 docstr = self.entry.doc
1919 if not isinstance(docstr, str):
1920 docstr = docstr.utf8encode()
1922 'static char %s[] = "%s";' % (
1923 self.entry.doc_cname,
1924 split_docstring(escape_byte_string(docstr))))
1927 "static PyMethodDef %s = " %
1928 self.entry.pymethdef_cname)
1929 code.put_pymethoddef(self.entry, ";")
1930 code.putln("%s {" % header)
1932 def generate_argument_declarations(self, env, code):
1933 for arg in self.args:
1934 if arg.is_generic: # or arg.needs_conversion:
1935 if arg.needs_conversion:
1936 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1938 code.put_var_declaration(arg.entry)
1940 def generate_keyword_list(self, code):
1941 if self.signature_has_generic_args() and \
1942 self.signature_has_nongeneric_args():
1944 "static PyObject **%s[] = {" %
1945 Naming.pykwdlist_cname)
1946 for arg in self.args:
1948 code.put('&%s,' % arg.name_entry.pystring_cname)
1951 def generate_argument_parsing_code(self, env, code):
1952 # Generate PyArg_ParseTuple call for generic
1953 # arguments, if any.
1954 if self.entry.signature.has_dummy_arg:
1955 # get rid of unused argument warning
1956 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1958 old_error_label = code.new_error_label()
1959 our_error_label = code.error_label
1960 end_label = code.new_label("argument_unpacking_done")
1962 has_kwonly_args = self.num_kwonly_args > 0
1963 has_star_or_kw_args = self.star_arg is not None \
1964 or self.starstar_arg is not None or has_kwonly_args
1966 for arg in self.args:
1967 if not arg.type.is_pyobject:
1968 done = arg.type.create_from_py_utility_code(env)
1969 if not done: pass # will fail later
1971 if not self.signature_has_generic_args():
1972 if has_star_or_kw_args:
1973 error(self.pos, "This method cannot have * or keyword arguments")
1974 self.generate_argument_conversion_code(code)
1976 elif not self.signature_has_nongeneric_args():
1977 # func(*args) or func(**kw) or func(*args, **kw)
1978 self.generate_stararg_copy_code(code)
1981 positional_args = []
1983 for arg in self.args:
1984 arg_entry = arg.entry
1987 if not arg.is_self_arg:
1989 kw_only_args.append(arg)
1991 positional_args.append(arg)
1993 kw_only_args.append(arg)
1994 elif not arg.is_self_arg:
1995 positional_args.append(arg)
1997 self.generate_tuple_and_keyword_parsing_code(
1998 positional_args, kw_only_args, end_label, code)
2000 code.error_label = old_error_label
2001 if code.label_used(our_error_label):
2002 if not code.label_used(end_label):
2003 code.put_goto(end_label)
2004 code.put_label(our_error_label)
2005 if has_star_or_kw_args:
2006 self.generate_arg_decref(self.star_arg, code)
2007 if self.starstar_arg:
2008 if self.starstar_arg.entry.xdecref_cleanup:
2009 code.put_var_xdecref(self.starstar_arg.entry)
2011 code.put_var_decref(self.starstar_arg.entry)
2012 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2013 code.putln("return %s;" % self.error_value())
2014 if code.label_used(end_label):
2015 code.put_label(end_label)
2017 def generate_arg_assignment(self, arg, item, code):
2018 if arg.type.is_pyobject:
2020 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2021 code.putln("%s = %s;" % (arg.entry.cname, item))
2023 func = arg.type.from_py_function
2025 code.putln("%s = %s(%s); %s" % (
2029 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2031 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2033 def generate_arg_xdecref(self, arg, code):
2035 code.put_var_xdecref(arg.entry)
2037 def generate_arg_decref(self, arg, code):
2039 code.put_var_decref(arg.entry)
2041 def generate_stararg_copy_code(self, code):
2042 if not self.star_arg:
2043 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2044 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2046 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2047 self.name.utf8encode(), Naming.args_cname, self.error_value()))
2050 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2052 if self.starstar_arg:
2054 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2056 kwarg_check = "%s" % Naming.kwds_cname
2058 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2059 Naming.kwds_cname, Naming.kwds_cname)
2061 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2062 kwarg_check, Naming.kwds_cname, self.name,
2063 bool(self.starstar_arg), self.error_value()))
2065 if self.starstar_arg:
2066 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2067 self.starstar_arg.entry.cname,
2070 code.putln("if (unlikely(!%s)) return %s;" % (
2071 self.starstar_arg.entry.cname, self.error_value()))
2072 self.starstar_arg.entry.xdecref_cleanup = 0
2073 code.put_gotref(self.starstar_arg.entry.cname)
2077 code.put_incref(Naming.args_cname, py_object_type)
2078 code.putln("%s = %s;" % (
2079 self.star_arg.entry.cname,
2081 self.star_arg.entry.xdecref_cleanup = 0
2083 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2084 kw_only_args, success_label, code):
2085 argtuple_error_label = code.new_label("argtuple_error")
2087 min_positional_args = self.num_required_args - self.num_required_kw_args
2088 if len(self.args) > 0 and self.args[0].is_self_arg:
2089 min_positional_args -= 1
2090 max_positional_args = len(positional_args)
2091 has_fixed_positional_count = not self.star_arg and \
2092 min_positional_args == max_positional_args
2094 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2095 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2096 if self.num_required_kw_args:
2097 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2099 if self.starstar_arg or self.star_arg:
2100 self.generate_stararg_init_code(max_positional_args, code)
2102 # --- optimised code when we receive keyword arguments
2103 if self.num_required_kw_args:
2104 likely_hint = "likely"
2106 likely_hint = "unlikely"
2107 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2108 self.generate_keyword_unpacking_code(
2109 min_positional_args, max_positional_args,
2110 has_fixed_positional_count,
2111 positional_args, kw_only_args, argtuple_error_label, code)
2113 # --- optimised code when we do not receive any keyword arguments
2114 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2115 # Python raises arg tuple related errors first, so we must
2116 # check the length here
2117 if min_positional_args == max_positional_args and not self.star_arg:
2121 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2122 Naming.args_cname, compare, min_positional_args))
2123 code.put_goto(argtuple_error_label)
2125 if self.num_required_kw_args:
2126 # pure error case: keywords required but not passed
2127 if max_positional_args > min_positional_args and not self.star_arg:
2128 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2129 Naming.args_cname, max_positional_args))
2130 code.put_goto(argtuple_error_label)
2131 code.putln('} else {')
2132 for i, arg in enumerate(kw_only_args):
2134 # required keyword-only argument missing
2135 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2136 self.name.utf8encode(),
2137 arg.name_entry.pystring_cname))
2138 code.putln(code.error_goto(self.pos))
2141 elif min_positional_args == max_positional_args:
2142 # parse the exact number of positional arguments from the
2144 code.putln('} else {')
2145 for i, arg in enumerate(positional_args):
2146 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2147 self.generate_arg_assignment(arg, item, code)
2148 self.generate_arg_default_assignments(code)
2151 # parse the positional arguments from the variable length
2153 code.putln('} else {')
2154 self.generate_arg_default_assignments(code)
2155 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2157 code.putln('default:')
2158 reversed_args = list(enumerate(positional_args))[::-1]
2159 for i, arg in reversed_args:
2160 if i >= min_positional_args-1:
2161 if min_positional_args > 1:
2162 code.putln('case %2d:' % (i+1)) # pure code beautification
2164 code.put('case %2d: ' % (i+1))
2165 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2166 self.generate_arg_assignment(arg, item, code)
2167 if min_positional_args == 0:
2168 code.put('case 0: ')
2169 code.putln('break;')
2171 if min_positional_args:
2172 for i in range(min_positional_args-1, -1, -1):
2173 code.putln('case %2d:' % i)
2174 code.put_goto(argtuple_error_label)
2176 code.put('default: ')
2177 code.put_goto(argtuple_error_label)
2182 if code.label_used(argtuple_error_label):
2183 code.put_goto(success_label)
2184 code.put_label(argtuple_error_label)
2185 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2186 self.name.utf8encode(), has_fixed_positional_count,
2187 min_positional_args, max_positional_args,
2189 code.putln(code.error_goto(self.pos))
2191 def generate_arg_default_assignments(self, code):
2192 for arg in self.args:
2193 if arg.is_generic and arg.default:
2197 arg.default_result_code))
2199 def generate_stararg_init_code(self, max_positional_args, code):
2200 if self.starstar_arg:
2201 self.starstar_arg.entry.xdecref_cleanup = 0
2202 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2203 self.starstar_arg.entry.cname,
2204 self.starstar_arg.entry.cname,
2205 self.error_value()))
2206 code.put_gotref(self.starstar_arg.entry.cname)
2208 self.star_arg.entry.xdecref_cleanup = 0
2209 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2211 max_positional_args))
2212 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2213 self.star_arg.entry.cname, Naming.args_cname,
2214 max_positional_args, Naming.args_cname))
2215 code.put_gotref(self.star_arg.entry.cname)
2216 if self.starstar_arg:
2218 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2219 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2220 code.putln('return %s;' % self.error_value())
2223 code.putln("if (unlikely(!%s)) return %s;" % (
2224 self.star_arg.entry.cname, self.error_value()))
2225 code.putln('} else {')
2226 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2227 code.put_incref(Naming.empty_tuple, py_object_type)
2230 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2231 has_fixed_positional_count, positional_args,
2232 kw_only_args, argtuple_error_label, code):
2233 all_args = tuple(positional_args) + tuple(kw_only_args)
2234 max_args = len(all_args)
2237 for i, arg in enumerate(all_args):
2238 if arg.default and arg.type.is_pyobject:
2239 default_value = arg.default_result_code
2240 if arg.type is not PyrexTypes.py_object_type:
2241 default_value = "(PyObject*)"+default_value
2242 default_args.append((i, default_value))
2244 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2246 # it looks funny to separate the init-to-0 from setting the
2247 # default value, but C89 needs this
2248 code.putln("PyObject* values[%d] = {%s};" % (
2249 max_args, ','.join(['0']*max_args)))
2250 for i, default_value in default_args:
2251 code.putln('values[%d] = %s;' % (i, default_value))
2253 # parse the tuple and check that it's not too long
2254 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2256 code.putln('default:')
2257 for i in range(max_positional_args-1, -1, -1):
2258 code.put('case %2d: ' % (i+1))
2259 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2260 i, Naming.args_cname, i))
2261 code.putln('case 0: break;')
2262 if not self.star_arg:
2263 code.put('default: ') # more arguments than allowed
2264 code.put_goto(argtuple_error_label)
2267 # now fill up the positional/required arguments with values
2269 if self.num_required_args or max_positional_args > 0:
2270 last_required_arg = -1
2271 for i, arg in enumerate(all_args):
2273 last_required_arg = i
2274 if last_required_arg < max_positional_args:
2275 last_required_arg = max_positional_args-1
2276 num_required_args = self.num_required_args
2277 if max_positional_args > 0:
2278 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2279 for i, arg in enumerate(all_args[:last_required_arg+1]):
2280 if max_positional_args > 0 and i <= max_positional_args:
2281 if self.star_arg and i == max_positional_args:
2282 code.putln('default:')
2284 code.putln('case %2d:' % i)
2287 # handled separately below
2289 code.putln('if (kw_args > %d) {' % num_required_args)
2290 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2291 Naming.kwds_cname, arg.name_entry.pystring_cname))
2292 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2295 num_required_args -= 1
2296 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2297 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2298 code.putln('if (likely(values[%d])) kw_args--;' % i);
2299 if i < min_positional_args:
2301 # special case: we know arg 0 is missing
2303 code.put_goto(argtuple_error_label)
2305 # print the correct number of values (args or
2306 # kwargs) that were passed into positional
2307 # arguments up to this point
2308 code.putln('else {')
2309 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2310 self.name.utf8encode(), has_fixed_positional_count,
2311 min_positional_args, max_positional_args, i))
2312 code.putln(code.error_goto(self.pos))
2315 code.putln('else {')
2316 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2317 self.name.utf8encode(), arg.name_entry.pystring_cname))
2318 code.putln(code.error_goto(self.pos))
2320 if max_positional_args > 0:
2323 if kw_only_args and not self.starstar_arg:
2324 # unpack optional keyword-only arguments
2325 # checking for interned strings in a dict is faster than iterating
2326 # but it's too likely that we must iterate if we expect **kwargs
2328 for i, arg in enumerate(all_args[max_positional_args:]):
2329 if not arg.kw_only or not arg.default:
2331 optional_args.append((i+max_positional_args, arg))
2333 # this mimics an unrolled loop so that we can "break" out of it
2334 code.putln('while (kw_args > 0) {')
2335 code.putln('PyObject* value;')
2336 for i, arg in optional_args:
2338 'value = PyDict_GetItem(%s, %s);' % (
2339 Naming.kwds_cname, arg.name_entry.pystring_cname))
2341 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2342 code.putln('break;')
2345 code.putln('if (unlikely(kw_args > 0)) {')
2346 # non-positional/-required kw args left in dict: default args,
2347 # kw-only args, **kwargs or error
2349 # This is sort of a catch-all: except for checking required
2350 # arguments, this will always do the right thing for unpacking
2351 # keyword arguments, so that we can concentrate on optimising
2352 # common cases above.
2353 if max_positional_args == 0:
2356 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2357 Naming.args_cname, max_positional_args,
2358 Naming.args_cname, max_positional_args))
2359 pos_arg_count = "used_pos_args"
2361 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2362 code.globalstate.use_utility_code(parse_keywords_utility_code)
2364 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2366 Naming.pykwdlist_cname,
2367 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2369 self.name.utf8encode()))
2370 code.putln(code.error_goto(self.pos))
2373 # convert arg values to their final type and assign them
2374 for i, arg in enumerate(all_args):
2375 if arg.default and not arg.type.is_pyobject:
2376 code.putln("if (values[%d]) {" % i)
2377 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2378 if arg.default and not arg.type.is_pyobject:
2379 code.putln('} else {')
2383 arg.default_result_code))
2386 def generate_argument_conversion_code(self, code):
2387 # Generate code to convert arguments from
2388 # signature type to declared type, if needed.
2389 for arg in self.args:
2390 if arg.needs_conversion:
2391 self.generate_arg_conversion(arg, code)
2393 def generate_arg_conversion(self, arg, code):
2394 # Generate conversion code for one argument.
2395 old_type = arg.hdr_type
2397 if old_type.is_pyobject:
2399 code.putln("if (%s) {" % arg.hdr_cname)
2401 code.putln("assert(%s); {" % arg.hdr_cname)
2402 self.generate_arg_conversion_from_pyobject(arg, code)
2404 elif new_type.is_pyobject:
2405 self.generate_arg_conversion_to_pyobject(arg, code)
2407 if new_type.assignable_from(old_type):
2409 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2412 "Cannot convert 1 argument from '%s' to '%s'" %
2413 (old_type, new_type))
2415 def generate_arg_conversion_from_pyobject(self, arg, code):
2417 func = new_type.from_py_function
2418 # copied from CoerceFromPyTypeNode
2420 code.putln("%s = %s(%s); %s" % (
2424 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2427 "Cannot convert Python object argument to type '%s'"
2430 def generate_arg_conversion_to_pyobject(self, arg, code):
2431 old_type = arg.hdr_type
2432 func = old_type.to_py_function
2434 code.putln("%s = %s(%s); %s" % (
2438 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2439 code.put_var_gotref(arg.entry)
2442 "Cannot convert argument of type '%s' to Python object"
2445 def generate_argument_type_tests(self, code):
2446 # Generate type tests for args whose signature
2447 # type is PyObject * and whose declared type is
2448 # a subtype thereof.
2449 for arg in self.args:
2450 if arg.needs_type_test:
2451 self.generate_arg_type_test(arg, code)
2453 def generate_arg_type_test(self, arg, code):
2454 # Generate type test for one argument.
2455 if arg.type.typeobj_is_available():
2456 typeptr_cname = arg.type.typeptr_cname
2457 arg_code = "((PyObject *)%s)" % arg.entry.cname
2459 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2464 arg.type.is_builtin_type,
2465 code.error_goto(arg.pos)))
2467 error(arg.pos, "Cannot test type of extern C class "
2468 "without type object name specification")
2470 def error_value(self):
2471 return self.entry.signature.error_value
2473 def caller_will_check_exceptions(self):
2476 class OverrideCheckNode(StatNode):
2477 # A Node for dispatching to the def method if it
2486 child_attrs = ['body']
2490 def analyse_expressions(self, env):
2491 self.args = env.arg_entries
2492 if self.py_func.is_module_scope:
2497 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2498 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2499 call_node = ExprNodes.SimpleCallNode(self.pos,
2500 function=self.func_node,
2501 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2502 self.body = ReturnStatNode(self.pos, value=call_node)
2503 self.body.analyse_expressions(env)
2505 def generate_execution_code(self, code):
2506 # Check to see if we are an extension type
2507 if self.py_func.is_module_scope:
2508 self_arg = "((PyObject *)%s)" % Naming.module_cname
2510 self_arg = "((PyObject *)%s)" % self.args[0].cname
2511 code.putln("/* Check if called by wrapper */")
2512 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2513 code.putln("/* Check if overriden in Python */")
2514 if self.py_func.is_module_scope:
2515 code.putln("else {")
2517 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2518 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2519 # need to get attribute manually--scope would return cdef method
2520 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2521 code.put_gotref(self.func_node.py_result())
2522 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2523 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2524 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2525 self.body.generate_execution_code(code)
2527 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2530 class ClassDefNode(StatNode, BlockNode):
2533 class PyClassDefNode(ClassDefNode):
2534 # A Python class definition.
2536 # name EncodedString Name of the class
2537 # doc string or None
2538 # body StatNode Attribute definition code
2539 # entry Symtab.Entry
2540 # scope PyClassScope
2542 # The following subnodes are constructed internally:
2544 # dict DictNode Class dictionary
2545 # classobj ClassNode Class object
2546 # target NameNode Variable to assign class object to
2548 child_attrs = ["body", "dict", "classobj", "target"]
2550 def __init__(self, pos, name, bases, doc, body):
2551 StatNode.__init__(self, pos)
2556 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2557 if self.doc and Options.docstrings:
2558 doc = embed_position(self.pos, self.doc)
2559 doc_node = ExprNodes.StringNode(pos, value = doc)
2562 self.classobj = ExprNodes.ClassNode(pos, name = name,
2563 bases = bases, dict = self.dict, doc = doc_node)
2564 self.target = ExprNodes.NameNode(pos, name = name)
2566 def as_cclass(self):
2568 Return this node as if it were declared as an extension class
2570 bases = self.classobj.bases.args
2572 base_class_name = None
2573 base_class_module = None
2574 elif len(bases) == 1:
2577 from ExprNodes import AttributeNode, NameNode
2578 while isinstance(base, AttributeNode):
2579 path.insert(0, base.attribute)
2581 if isinstance(base, NameNode):
2582 path.insert(0, base.name)
2583 base_class_name = path[-1]
2585 base_class_module = u'.'.join(path[:-1])
2587 base_class_module = None
2589 error(self.classobj.bases.args.pos, "Invalid base class")
2591 error(self.classobj.bases.args.pos, "C class may only have one base class")
2594 return CClassDefNode(self.pos,
2595 visibility = 'private',
2597 class_name = self.name,
2598 base_class_module = base_class_module,
2599 base_class_name = base_class_name,
2604 def create_scope(self, env):
2606 while env.is_py_class_scope or env.is_c_class_scope:
2607 env = env.outer_scope
2608 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2611 def analyse_declarations(self, env):
2612 self.target.analyse_target_declaration(env)
2613 cenv = self.create_scope(env)
2614 cenv.directives = env.directives
2615 cenv.class_obj_cname = self.target.entry.cname
2616 self.body.analyse_declarations(cenv)
2618 def analyse_expressions(self, env):
2619 self.dict.analyse_expressions(env)
2620 self.classobj.analyse_expressions(env)
2621 genv = env.global_scope()
2623 cenv.class_dict_cname = self.dict.result()
2624 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2625 self.body.analyse_expressions(cenv)
2626 self.target.analyse_target_expression(env, self.classobj)
2627 self.dict.release_temp(env)
2628 #self.classobj.release_temp(env)
2629 #self.target.release_target_temp(env)
2631 def generate_function_definitions(self, env, code):
2632 self.generate_py_string_decls(self.scope, code)
2633 self.body.generate_function_definitions(self.scope, code)
2635 def generate_execution_code(self, code):
2636 self.dict.generate_evaluation_code(code)
2637 self.classobj.generate_evaluation_code(code)
2638 self.body.generate_execution_code(code)
2639 self.target.generate_assignment_code(self.classobj, code)
2640 self.dict.generate_disposal_code(code)
2641 self.dict.free_temps(code)
2644 class CClassDefNode(ClassDefNode):
2645 # An extension type definition.
2647 # visibility 'private' or 'public' or 'extern'
2648 # typedef_flag boolean
2650 # module_name string or None For import of extern type objects
2651 # class_name string Unqualified name of class
2652 # as_name string or None Name to declare as in this scope
2653 # base_class_module string or None Module containing the base class
2654 # base_class_name string or None Name of the base class
2655 # objstruct_name string or None Specified C name of object struct
2656 # typeobj_name string or None Specified C name of type object
2657 # in_pxd boolean Is in a .pxd file
2658 # doc string or None
2659 # body StatNode or None
2660 # entry Symtab.Entry
2661 # base_type PyExtensionType or None
2662 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2663 # buffer_defaults_pos
2665 child_attrs = ["body"]
2666 buffer_defaults_node = None
2667 buffer_defaults_pos = None
2668 typedef_flag = False
2670 objstruct_name = None
2673 def analyse_declarations(self, env):
2674 #print "CClassDefNode.analyse_declarations:", self.class_name
2675 #print "...visibility =", self.visibility
2676 #print "...module_name =", self.module_name
2679 if self.buffer_defaults_node:
2680 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2681 env, [], self.buffer_defaults_node,
2682 need_complete=False)
2684 buffer_defaults = None
2686 if env.in_cinclude and not self.objstruct_name:
2687 error(self.pos, "Object struct name specification required for "
2688 "C class defined in 'extern from' block")
2689 self.base_type = None
2690 # Now that module imports are cached, we need to
2691 # import the modules for extern classes.
2692 if self.module_name:
2694 for module in env.cimported_modules:
2695 if module.name == self.module_name:
2696 self.module = module
2697 if self.module is None:
2698 self.module = ModuleScope(self.module_name, None, env.context)
2699 self.module.has_extern_class = 1
2700 env.add_imported_module(self.module)
2702 if self.base_class_name:
2703 if self.base_class_module:
2704 base_class_scope = env.find_module(self.base_class_module, self.pos)
2706 base_class_scope = env
2707 if self.base_class_name == 'object':
2708 # extension classes are special and don't need to inherit from object
2709 if base_class_scope is None or base_class_scope.lookup('object') is None:
2710 self.base_class_name = None
2711 self.base_class_module = None
2712 base_class_scope = None
2713 if base_class_scope:
2714 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2715 if base_class_entry:
2716 if not base_class_entry.is_type:
2717 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2718 elif not base_class_entry.type.is_extension_type:
2719 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2720 elif not base_class_entry.type.is_complete():
2721 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2723 self.base_type = base_class_entry.type
2724 has_body = self.body is not None
2725 if self.module_name and self.visibility != 'extern':
2726 module_path = self.module_name.split(".")
2727 home_scope = env.find_imported_module(module_path, self.pos)
2733 if self.visibility == 'extern':
2734 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2735 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2737 self.entry = home_scope.declare_c_class(
2738 name = self.class_name,
2740 defining = has_body and self.in_pxd,
2741 implementing = has_body and not self.in_pxd,
2742 module_name = self.module_name,
2743 base_type = self.base_type,
2744 objstruct_cname = self.objstruct_name,
2745 typeobj_cname = self.typeobj_name,
2746 visibility = self.visibility,
2747 typedef_flag = self.typedef_flag,
2749 buffer_defaults = buffer_defaults)
2750 if home_scope is not env and self.visibility == 'extern':
2751 env.add_imported_entry(self.class_name, self.entry, pos)
2752 scope = self.entry.type.scope
2753 if scope is not None:
2754 scope.directives = env.directives
2756 if self.doc and Options.docstrings:
2757 scope.doc = embed_position(self.pos, self.doc)
2760 self.body.analyse_declarations(scope)
2764 scope.implemented = 1
2765 env.allocate_vtable_names(self.entry)
2767 def analyse_expressions(self, env):
2769 scope = self.entry.type.scope
2770 self.body.analyse_expressions(scope)
2772 def generate_function_definitions(self, env, code):
2773 self.generate_py_string_decls(self.entry.type.scope, code)
2775 self.body.generate_function_definitions(
2776 self.entry.type.scope, code)
2778 def generate_execution_code(self, code):
2779 # This is needed to generate evaluation code for
2780 # default values of method arguments.
2782 self.body.generate_execution_code(code)
2784 def annotate(self, code):
2786 self.body.annotate(code)
2789 class PropertyNode(StatNode):
2790 # Definition of a property in an extension type.
2793 # doc EncodedString or None Doc string
2796 child_attrs = ["body"]
2798 def analyse_declarations(self, env):
2799 entry = env.declare_property(self.name, self.doc, self.pos)
2801 if self.doc and Options.docstrings:
2802 doc_entry = env.get_string_const(
2803 self.doc, identifier = False)
2804 entry.doc_cname = doc_entry.cname
2805 entry.scope.directives = env.directives
2806 self.body.analyse_declarations(entry.scope)
2808 def analyse_expressions(self, env):
2809 self.body.analyse_expressions(env)
2811 def generate_function_definitions(self, env, code):
2812 self.body.generate_function_definitions(env, code)
2814 def generate_execution_code(self, code):
2817 def annotate(self, code):
2818 self.body.annotate(code)
2821 class GlobalNode(StatNode):
2822 # Global variable declaration.
2828 def analyse_declarations(self, env):
2829 for name in self.names:
2830 env.declare_global(name, self.pos)
2832 def analyse_expressions(self, env):
2835 def generate_execution_code(self, code):
2839 class ExprStatNode(StatNode):
2840 # Expression used as a statement.
2844 child_attrs = ["expr"]
2846 def analyse_declarations(self, env):
2848 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2849 func = self.expr.function.as_cython_attribute()
2850 if func == u'declare':
2851 args, kwds = self.expr.explicit_args_kwds()
2853 error(self.expr.pos, "Variable names must be specified.")
2854 for var, type_node in kwds.key_value_pairs:
2855 type = type_node.analyse_as_type(env)
2857 error(type_node.pos, "Unknown type")
2859 env.declare_var(var.value, type, var.pos, is_cdef = True)
2860 self.__class__ = PassStatNode
2862 def analyse_expressions(self, env):
2863 self.expr.analyse_expressions(env)
2864 self.expr.release_temp(env)
2866 def generate_execution_code(self, code):
2867 self.expr.generate_evaluation_code(code)
2868 if not self.expr.is_temp and self.expr.result():
2869 code.putln("%s;" % self.expr.result())
2870 self.expr.generate_disposal_code(code)
2871 self.expr.free_temps(code)
2873 def annotate(self, code):
2874 self.expr.annotate(code)
2877 class AssignmentNode(StatNode):
2878 # Abstract base class for assignment nodes.
2880 # The analyse_expressions and generate_execution_code
2881 # phases of assignments are split into two sub-phases
2882 # each, to enable all the right hand sides of a
2883 # parallel assignment to be evaluated before assigning
2884 # to any of the left hand sides.
2886 def analyse_expressions(self, env):
2887 self.analyse_types(env)
2888 self.allocate_rhs_temps(env)
2889 self.allocate_lhs_temps(env)
2891 # def analyse_expressions(self, env):
2892 # self.analyse_expressions_1(env)
2893 # self.analyse_expressions_2(env)
2895 def generate_execution_code(self, code):
2896 self.generate_rhs_evaluation_code(code)
2897 self.generate_assignment_code(code)
2900 class SingleAssignmentNode(AssignmentNode):
2901 # The simplest case:
2905 # lhs ExprNode Left hand side
2906 # rhs ExprNode Right hand side
2907 # first bool Is this guaranteed the first assignment to lhs?
2909 child_attrs = ["lhs", "rhs"]
2911 declaration_only = False
2913 def analyse_declarations(self, env):
2916 # handle declarations of the form x = cython.foo()
2917 if isinstance(self.rhs, ExprNodes.CallNode):
2918 func_name = self.rhs.function.as_cython_attribute()
2920 args, kwds = self.rhs.explicit_args_kwds()
2922 if func_name in ['declare', 'typedef']:
2923 if len(args) > 2 or kwds is not None:
2924 error(rhs.pos, "Can only declare one type at a time.")
2926 type = args[0].analyse_as_type(env)
2928 error(args[0].pos, "Unknown type")
2931 if func_name == 'declare':
2932 if isinstance(lhs, ExprNodes.NameNode):
2933 vars = [(lhs.name, lhs.pos)]
2934 elif isinstance(lhs, ExprNodes.TupleNode):
2935 vars = [(var.name, var.pos) for var in lhs.args]
2937 error(lhs.pos, "Invalid declaration")
2939 for var, pos in vars:
2940 env.declare_var(var, type, pos, is_cdef = True)
2945 self.declaration_only = True
2947 self.declaration_only = True
2948 if not isinstance(lhs, ExprNodes.NameNode):
2949 error(lhs.pos, "Invalid declaration.")
2950 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2952 elif func_name in ['struct', 'union']:
2953 self.declaration_only = True
2954 if len(args) > 0 or kwds is None:
2955 error(rhs.pos, "Struct or union members must be given by name.")
2958 for member, type_node in kwds.key_value_pairs:
2959 type = type_node.analyse_as_type(env)
2961 error(type_node.pos, "Unknown type")
2963 members.append((member.value, type, member.pos))
2964 if len(members) < len(kwds.key_value_pairs):
2966 if not isinstance(self.lhs, ExprNodes.NameNode):
2967 error(self.lhs.pos, "Invalid declaration.")
2968 name = self.lhs.name
2969 scope = StructOrUnionScope(name)
2970 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2971 for member, type, pos in members:
2972 scope.declare_var(member, type, pos)
2974 if self.declaration_only:
2977 self.lhs.analyse_target_declaration(env)
2979 def analyse_types(self, env, use_temp = 0):
2980 self.rhs.analyse_types(env)
2981 self.lhs.analyse_target_types(env)
2982 self.lhs.gil_assignment_check(env)
2983 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2985 self.rhs = self.rhs.coerce_to_temp(env)
2987 def allocate_rhs_temps(self, env):
2988 self.rhs.allocate_temps(env)
2990 def allocate_lhs_temps(self, env):
2991 self.lhs.allocate_target_temps(env, self.rhs)
2992 #self.lhs.release_target_temp(env)
2993 #self.rhs.release_temp(env)
2995 def generate_rhs_evaluation_code(self, code):
2996 self.rhs.generate_evaluation_code(code)
2998 def generate_assignment_code(self, code):
2999 self.lhs.generate_assignment_code(self.rhs, code)
3001 def annotate(self, code):
3002 self.lhs.annotate(code)
3003 self.rhs.annotate(code)
3006 class CascadedAssignmentNode(AssignmentNode):
3007 # An assignment with multiple left hand sides:
3011 # lhs_list [ExprNode] Left hand sides
3012 # rhs ExprNode Right hand sides
3016 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3018 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3019 coerced_rhs_list = None
3021 def analyse_declarations(self, env):
3022 for lhs in self.lhs_list:
3023 lhs.analyse_target_declaration(env)
3025 def analyse_types(self, env, use_temp = 0):
3026 self.rhs.analyse_types(env)
3028 self.rhs = self.rhs.coerce_to_temp(env)
3030 self.rhs = self.rhs.coerce_to_simple(env)
3031 from ExprNodes import CloneNode
3032 self.coerced_rhs_list = []
3033 for lhs in self.lhs_list:
3034 lhs.analyse_target_types(env)
3035 lhs.gil_assignment_check(env)
3036 rhs = CloneNode(self.rhs)
3037 rhs = rhs.coerce_to(lhs.type, env)
3038 self.coerced_rhs_list.append(rhs)
3040 def allocate_rhs_temps(self, env):
3041 self.rhs.allocate_temps(env)
3043 def allocate_lhs_temps(self, env):
3044 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
3045 rhs.allocate_temps(env)
3046 lhs.allocate_target_temps(env, rhs)
3047 #lhs.release_target_temp(env)
3048 #rhs.release_temp(env)
3049 self.rhs.release_temp(env)
3051 def generate_rhs_evaluation_code(self, code):
3052 self.rhs.generate_evaluation_code(code)
3054 def generate_assignment_code(self, code):
3055 for i in range(len(self.lhs_list)):
3056 lhs = self.lhs_list[i]
3057 rhs = self.coerced_rhs_list[i]
3058 rhs.generate_evaluation_code(code)
3059 lhs.generate_assignment_code(rhs, code)
3060 # Assignment has disposed of the cloned RHS
3061 self.rhs.generate_disposal_code(code)
3062 self.rhs.free_temps(code)
3064 def annotate(self, code):
3065 for i in range(len(self.lhs_list)):
3066 lhs = self.lhs_list[i].annotate(code)
3067 rhs = self.coerced_rhs_list[i].annotate(code)
3068 self.rhs.annotate(code)
3071 class ParallelAssignmentNode(AssignmentNode):
3072 # A combined packing/unpacking assignment:
3076 # This has been rearranged by the parser into
3078 # a = d ; b = e ; c = f
3080 # but we must evaluate all the right hand sides
3081 # before assigning to any of the left hand sides.
3083 # stats [AssignmentNode] The constituent assignments
3085 child_attrs = ["stats"]
3087 def analyse_declarations(self, env):
3088 for stat in self.stats:
3089 stat.analyse_declarations(env)
3091 def analyse_expressions(self, env):
3092 for stat in self.stats:
3093 stat.analyse_types(env, use_temp = 1)
3094 stat.allocate_rhs_temps(env)
3095 for stat in self.stats:
3096 stat.allocate_lhs_temps(env)
3098 # def analyse_expressions(self, env):
3099 # for stat in self.stats:
3100 # stat.analyse_expressions_1(env, use_temp = 1)
3101 # for stat in self.stats:
3102 # stat.analyse_expressions_2(env)
3104 def generate_execution_code(self, code):
3105 for stat in self.stats:
3106 stat.generate_rhs_evaluation_code(code)
3107 for stat in self.stats:
3108 stat.generate_assignment_code(code)
3110 def annotate(self, code):
3111 for stat in self.stats:
3115 class InPlaceAssignmentNode(AssignmentNode):
3116 # An in place arithmatic operand:
3122 # lhs ExprNode Left hand side
3123 # rhs ExprNode Right hand side
3124 # op char one of "+-*/%^&|"
3125 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3127 # This code is a bit tricky because in order to obey Python
3128 # semantics the sub-expressions (e.g. indices) of the lhs must
3129 # not be evaluated twice. So we must re-use the values calculated
3130 # in evaluation phase for the assignment phase as well.
3131 # Fortunately, the type of the lhs node is fairly constrained
3132 # (it must be a NameNode, AttributeNode, or IndexNode).
3134 child_attrs = ["lhs", "rhs"]
3137 def analyse_declarations(self, env):
3138 self.lhs.analyse_target_declaration(env)
3140 def analyse_types(self, env):
3141 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3142 self.rhs.analyse_types(env)
3143 self.lhs.analyse_target_types(env)
3144 if Options.incref_local_binop and self.dup.type.is_pyobject:
3145 self.dup = self.dup.coerce_to_temp(env)
3147 def allocate_rhs_temps(self, env):
3149 if self.lhs.type.is_pyobject:
3150 self.rhs = self.rhs.coerce_to_pyobject(env)
3151 elif self.rhs.type.is_pyobject:
3152 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3153 if self.lhs.type.is_pyobject:
3154 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3155 self.result_value.allocate_temps(env)
3157 # self.rhs = self.rhs.coerce_to_temp(env)
3158 self.rhs.allocate_temps(env)
3159 self.dup.allocate_subexpr_temps(env)
3160 self.dup.allocate_temp(env)
3162 def allocate_lhs_temps(self, env):
3163 self.lhs.allocate_target_temps(env, self.rhs)
3164 # self.lhs.release_target_temp(env)
3165 self.dup.release_temp(env)
3166 if self.dup.is_temp:
3167 self.dup.release_subexpr_temps(env)
3168 # self.rhs.release_temp(env)
3169 if self.lhs.type.is_pyobject:
3170 self.result_value.release_temp(env)
3172 def generate_execution_code(self, code):
3174 self.rhs.generate_evaluation_code(code)
3175 self.dup.generate_subexpr_evaluation_code(code)
3176 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3177 # This is because we're manually messing with subexpr nodes
3178 if self.dup.is_temp:
3179 self.dup.allocate_temp_result(code)
3180 # self.dup.generate_result_code is run only if it is not buffer access
3181 if self.operator == "**":
3185 if self.lhs.type.is_pyobject:
3186 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3187 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3188 self.dup.generate_result_code(code)
3190 "%s = %s(%s, %s%s); %s" % (
3191 self.result_value.result(),
3192 self.py_operation_function(),
3193 self.dup.py_result(),
3194 self.rhs.py_result(),
3196 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3197 code.put_gotref(self.result_value.py_result())
3198 self.result_value.generate_evaluation_code(code) # May be a type check...
3199 self.rhs.generate_disposal_code(code)
3200 self.rhs.free_temps(code)
3201 self.dup.generate_disposal_code(code)
3202 self.dup.free_temps(code)
3203 self.lhs.generate_assignment_code(self.result_value, code)
3205 c_op = self.operator
3209 error(self.pos, "No C inplace power operator")
3210 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3211 error(self.pos, "Inplace operators not implemented for complex types.")
3213 # have to do assignment directly to avoid side-effects
3214 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3215 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3217 self.dup.generate_result_code(code)
3218 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3219 self.rhs.generate_disposal_code(code)
3220 self.rhs.free_temps(code)
3221 if self.dup.is_temp:
3222 self.dup.generate_subexpr_disposal_code(code)
3223 self.dup.free_subexpr_temps(code)
3225 def create_dup_node(self, env):
3228 self.dup.analyse_types(env)
3229 if isinstance(self.lhs, ExprNodes.NameNode):
3230 target_lhs = ExprNodes.NameNode(self.dup.pos,
3231 name = self.dup.name,
3232 is_temp = self.dup.is_temp,
3233 entry = self.dup.entry)
3234 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3235 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3236 obj = ExprNodes.CloneNode(self.lhs.obj),
3237 attribute = self.dup.attribute,
3238 is_temp = self.dup.is_temp)
3239 elif isinstance(self.lhs, ExprNodes.IndexNode):
3241 index = ExprNodes.CloneNode(self.lhs.index)
3244 if self.lhs.indices:
3245 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3248 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3249 base = ExprNodes.CloneNode(self.dup.base),
3252 is_temp = self.dup.is_temp)
3255 self.lhs = target_lhs
3258 def py_operation_function(self):
3259 return self.py_functions[self.operator]
3262 "|": "PyNumber_InPlaceOr",
3263 "^": "PyNumber_InPlaceXor",
3264 "&": "PyNumber_InPlaceAnd",
3265 "+": "PyNumber_InPlaceAdd",
3266 "-": "PyNumber_InPlaceSubtract",
3267 "*": "PyNumber_InPlaceMultiply",
3268 "/": "PyNumber_InPlaceDivide",
3269 "%": "PyNumber_InPlaceRemainder",
3270 "<<": "PyNumber_InPlaceLshift",
3271 ">>": "PyNumber_InPlaceRshift",
3272 "**": "PyNumber_InPlacePower",
3273 "//": "PyNumber_InPlaceFloorDivide",
3276 def annotate(self, code):
3277 self.lhs.annotate(code)
3278 self.rhs.annotate(code)
3279 self.dup.annotate(code)
3282 class PrintStatNode(StatNode):
3285 # arg_tuple TupleNode
3286 # append_newline boolean
3288 child_attrs = ["arg_tuple"]
3290 def analyse_expressions(self, env):
3291 self.arg_tuple.analyse_expressions(env)
3292 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3293 self.arg_tuple.release_temp(env)
3294 env.use_utility_code(printing_utility_code)
3295 if len(self.arg_tuple.args) == 1 and self.append_newline:
3296 env.use_utility_code(printing_one_utility_code)
3299 gil_message = "Python print statement"
3301 def generate_execution_code(self, code):
3302 if len(self.arg_tuple.args) == 1 and self.append_newline:
3303 arg = self.arg_tuple.args[0]
3304 arg.generate_evaluation_code(code)
3307 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3309 code.error_goto(self.pos)))
3310 arg.generate_disposal_code(code)
3311 arg.free_temps(code)
3313 self.arg_tuple.generate_evaluation_code(code)
3315 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3316 self.arg_tuple.py_result(),
3317 self.append_newline,
3318 code.error_goto(self.pos)))
3319 self.arg_tuple.generate_disposal_code(code)
3320 self.arg_tuple.free_temps(code)
3322 def annotate(self, code):
3323 self.arg_tuple.annotate(code)
3326 class ExecStatNode(StatNode):
3331 child_attrs = ["args"]
3333 def analyse_expressions(self, env):
3334 for i, arg in enumerate(self.args):
3335 arg.analyse_expressions(env)
3336 arg = arg.coerce_to_pyobject(env)
3337 arg.release_temp(env)
3339 self.temp_result = env.allocate_temp_pyobject()
3340 env.release_temp(self.temp_result)
3341 env.use_utility_code(Builtin.pyexec_utility_code)
3344 gil_message = "Python exec statement"
3346 def generate_execution_code(self, code):
3348 for arg in self.args:
3349 arg.generate_evaluation_code(code)
3350 args.append( arg.py_result() )
3351 args = tuple(args + ['0', '0'][:3-len(args)])
3352 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3353 (self.temp_result,) + args))
3354 for arg in self.args:
3355 arg.generate_disposal_code(code)
3356 arg.free_temps(code)
3358 code.error_goto_if_null(self.temp_result, self.pos))
3359 code.put_gotref(self.temp_result)
3360 code.put_decref_clear(self.temp_result, py_object_type)
3362 def annotate(self, code):
3363 for arg in self.args:
3367 class DelStatNode(StatNode):
3372 child_attrs = ["args"]
3374 def analyse_declarations(self, env):
3375 for arg in self.args:
3376 arg.analyse_target_declaration(env)
3378 def analyse_expressions(self, env):
3379 for arg in self.args:
3380 arg.analyse_target_expression(env, None)
3381 if arg.type.is_pyobject:
3384 error(arg.pos, "Deletion of non-Python object")
3385 #arg.release_target_temp(env)
3387 gil_message = "Deleting Python object"
3389 def generate_execution_code(self, code):
3390 for arg in self.args:
3391 if arg.type.is_pyobject:
3392 arg.generate_deletion_code(code)
3393 # else error reported earlier
3395 def annotate(self, code):
3396 for arg in self.args:
3400 class PassStatNode(StatNode):
3405 def analyse_expressions(self, env):
3408 def generate_execution_code(self, code):
3412 class BreakStatNode(StatNode):
3416 def analyse_expressions(self, env):
3419 def generate_execution_code(self, code):
3420 if not code.break_label:
3421 error(self.pos, "break statement not inside loop")
3423 code.put_goto(code.break_label)
3426 class ContinueStatNode(StatNode):
3430 def analyse_expressions(self, env):
3433 def generate_execution_code(self, code):
3434 if code.funcstate.in_try_finally:
3435 error(self.pos, "continue statement inside try of try...finally")
3436 elif not code.continue_label:
3437 error(self.pos, "continue statement not inside loop")
3439 code.put_goto(code.continue_label)
3442 class ReturnStatNode(StatNode):
3445 # value ExprNode or None
3446 # return_type PyrexType
3447 # temps_in_use [Entry] Temps in use at time of return
3449 child_attrs = ["value"]
3451 def analyse_expressions(self, env):
3452 return_type = env.return_type
3453 self.return_type = return_type
3454 self.temps_in_use = env.temps_in_use()
3456 error(self.pos, "Return not inside a function body")
3459 self.value.analyse_types(env)
3460 if return_type.is_void or return_type.is_returncode:
3461 error(self.value.pos,
3462 "Return with value in void function")
3464 self.value = self.value.coerce_to(env.return_type, env)
3465 self.value.allocate_temps(env)
3466 self.value.release_temp(env)
3468 if (not return_type.is_void
3469 and not return_type.is_pyobject
3470 and not return_type.is_returncode):
3471 error(self.pos, "Return value required")
3472 if return_type.is_pyobject:
3475 gil_message = "Returning Python object"
3477 def generate_execution_code(self, code):
3478 code.mark_pos(self.pos)
3479 if not self.return_type:
3480 # error reported earlier
3482 if self.return_type.is_pyobject:
3483 code.put_xdecref(Naming.retval_cname,
3486 self.value.generate_evaluation_code(code)
3487 self.value.make_owned_reference(code)
3490 Naming.retval_cname,
3491 self.value.result_as(self.return_type)))
3492 self.value.generate_post_assignment_code(code)
3493 self.value.free_temps(code)
3495 if self.return_type.is_pyobject:
3496 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3497 elif self.return_type.is_returncode:
3500 Naming.retval_cname,
3501 self.return_type.default_value))
3502 # free temps the old way
3503 for entry in self.temps_in_use:
3504 code.put_var_decref_clear(entry)
3505 # free temps the new way
3506 for cname, type in code.funcstate.temps_holding_reference():
3507 code.put_decref_clear(cname, type)
3510 # code.return_label)
3511 code.put_goto(code.return_label)
3513 def annotate(self, code):
3515 self.value.annotate(code)
3518 class RaiseStatNode(StatNode):
3521 # exc_type ExprNode or None
3522 # exc_value ExprNode or None
3523 # exc_tb ExprNode or None
3525 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3527 def analyse_expressions(self, env):
3529 self.exc_type.analyse_types(env)
3530 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3531 self.exc_type.allocate_temps(env)
3533 self.exc_value.analyse_types(env)
3534 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3535 self.exc_value.allocate_temps(env)
3537 self.exc_tb.analyse_types(env)
3538 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3539 self.exc_tb.allocate_temps(env)
3541 self.exc_type.release_temp(env)
3543 self.exc_value.release_temp(env)
3545 self.exc_tb.release_temp(env)
3546 env.use_utility_code(raise_utility_code)
3547 env.use_utility_code(restore_exception_utility_code)
3550 gil_message = "Raising exception"
3552 def generate_execution_code(self, code):
3554 self.exc_type.generate_evaluation_code(code)
3555 type_code = self.exc_type.py_result()
3559 self.exc_value.generate_evaluation_code(code)
3560 value_code = self.exc_value.py_result()
3564 self.exc_tb.generate_evaluation_code(code)
3565 tb_code = self.exc_tb.py_result()
3568 if self.exc_type or self.exc_value or self.exc_tb:
3570 "__Pyx_Raise(%s, %s, %s);" % (
3577 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3579 obj.generate_disposal_code(code)
3580 obj.free_temps(code)
3582 code.error_goto(self.pos))
3584 def annotate(self, code):
3586 self.exc_type.annotate(code)
3588 self.exc_value.annotate(code)
3590 self.exc_tb.annotate(code)
3593 class ReraiseStatNode(StatNode):
3597 def analyse_expressions(self, env):
3599 env.use_utility_code(raise_utility_code)
3600 env.use_utility_code(restore_exception_utility_code)
3602 gil_message = "Raising exception"
3604 def generate_execution_code(self, code):
3605 vars = code.funcstate.exc_vars
3607 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3608 code.putln(code.error_goto(self.pos))
3610 error(self.pos, "Reraise not inside except clause")
3613 class AssertStatNode(StatNode):
3617 # value ExprNode or None
3619 child_attrs = ["cond", "value"]
3621 def analyse_expressions(self, env):
3622 self.cond = self.cond.analyse_boolean_expression(env)
3624 self.value.analyse_types(env)
3625 self.value = self.value.coerce_to_pyobject(env)
3626 self.value.allocate_temps(env)
3627 self.cond.release_temp(env)
3629 self.value.release_temp(env)
3631 #env.recycle_pending_temps() # TEMPORARY
3633 gil_message = "Raising exception"
3635 def generate_execution_code(self, code):
3636 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3637 self.cond.generate_evaluation_code(code)
3639 "if (unlikely(!%s)) {" %
3642 self.value.generate_evaluation_code(code)
3644 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3645 self.value.py_result())
3646 self.value.generate_disposal_code(code)
3647 self.value.free_temps(code)
3650 "PyErr_SetNone(PyExc_AssertionError);")
3652 code.error_goto(self.pos))
3655 self.cond.generate_disposal_code(code)
3656 self.cond.free_temps(code)
3657 code.putln("#endif")
3659 def annotate(self, code):
3660 self.cond.annotate(code)
3662 self.value.annotate(code)
3665 class IfStatNode(StatNode):
3668 # if_clauses [IfClauseNode]
3669 # else_clause StatNode or None
3671 child_attrs = ["if_clauses", "else_clause"]
3673 def analyse_control_flow(self, env):
3674 env.start_branching(self.pos)
3675 for if_clause in self.if_clauses:
3676 if_clause.analyse_control_flow(env)
3677 env.next_branch(if_clause.end_pos())
3678 if self.else_clause:
3679 self.else_clause.analyse_control_flow(env)
3680 env.finish_branching(self.end_pos())
3682 def analyse_declarations(self, env):
3683 for if_clause in self.if_clauses:
3684 if_clause.analyse_declarations(env)
3685 if self.else_clause:
3686 self.else_clause.analyse_declarations(env)
3688 def analyse_expressions(self, env):
3689 for if_clause in self.if_clauses:
3690 if_clause.analyse_expressions(env)
3691 if self.else_clause:
3692 self.else_clause.analyse_expressions(env)
3694 def generate_execution_code(self, code):
3695 code.mark_pos(self.pos)
3696 end_label = code.new_label()
3697 for if_clause in self.if_clauses:
3698 if_clause.generate_execution_code(code, end_label)
3699 if self.else_clause:
3700 code.putln("/*else*/ {")
3701 self.else_clause.generate_execution_code(code)
3703 code.put_label(end_label)
3705 def annotate(self, code):
3706 for if_clause in self.if_clauses:
3707 if_clause.annotate(code)
3708 if self.else_clause:
3709 self.else_clause.annotate(code)
3712 class IfClauseNode(Node):
3713 # if or elif clause in an if statement
3715 # condition ExprNode
3718 child_attrs = ["condition", "body"]
3720 def analyse_control_flow(self, env):
3721 self.body.analyse_control_flow(env)
3723 def analyse_declarations(self, env):
3724 self.condition.analyse_declarations(env)
3725 self.body.analyse_declarations(env)
3727 def analyse_expressions(self, env):
3729 self.condition.analyse_temp_boolean_expression(env)
3730 self.condition.release_temp(env)
3731 self.body.analyse_expressions(env)
3733 def generate_execution_code(self, code, end_label):
3734 self.condition.generate_evaluation_code(code)
3737 self.condition.result())
3738 self.condition.generate_disposal_code(code)
3739 self.condition.free_temps(code)
3740 self.body.generate_execution_code(code)
3744 code.put_goto(end_label)
3747 def annotate(self, code):
3748 self.condition.annotate(code)
3749 self.body.annotate(code)
3752 class SwitchCaseNode(StatNode):
3753 # Generated in the optimization of an if-elif-else node
3755 # conditions [ExprNode]
3758 child_attrs = ['conditions', 'body']
3760 def generate_execution_code(self, code):
3761 for cond in self.conditions:
3762 code.mark_pos(cond.pos)
3763 code.putln("case %s:" % cond.calculate_result_code())
3764 self.body.generate_execution_code(code)
3765 code.putln("break;")
3767 def annotate(self, code):
3768 for cond in self.conditions:
3770 self.body.annotate(code)
3772 class SwitchStatNode(StatNode):
3773 # Generated in the optimization of an if-elif-else node
3776 # cases [SwitchCaseNode]
3777 # else_clause StatNode or None
3779 child_attrs = ['test', 'cases', 'else_clause']
3781 def generate_execution_code(self, code):
3782 code.putln("switch (%s) {" % self.test.calculate_result_code())
3783 for case in self.cases:
3784 case.generate_execution_code(code)
3785 if self.else_clause is not None:
3786 code.putln("default:")
3787 self.else_clause.generate_execution_code(code)
3788 code.putln("break;")
3791 def annotate(self, code):
3792 self.test.annotate(code)
3793 for case in self.cases:
3795 if self.else_clause is not None:
3796 self.else_clause.annotate(code)
3798 class LoopNode(object):
3800 def analyse_control_flow(self, env):
3801 env.start_branching(self.pos)
3802 self.body.analyse_control_flow(env)
3803 env.next_branch(self.body.end_pos())
3804 if self.else_clause:
3805 self.else_clause.analyse_control_flow(env)
3806 env.finish_branching(self.end_pos())
3809 class WhileStatNode(LoopNode, StatNode):
3812 # condition ExprNode
3814 # else_clause StatNode
3816 child_attrs = ["condition", "body", "else_clause"]
3818 def analyse_declarations(self, env):
3819 self.body.analyse_declarations(env)
3820 if self.else_clause:
3821 self.else_clause.analyse_declarations(env)
3823 def analyse_expressions(self, env):
3825 self.condition.analyse_temp_boolean_expression(env)
3826 self.condition.release_temp(env)
3827 #env.recycle_pending_temps() # TEMPORARY
3828 self.body.analyse_expressions(env)
3829 if self.else_clause:
3830 self.else_clause.analyse_expressions(env)
3832 def generate_execution_code(self, code):
3833 old_loop_labels = code.new_loop_labels()
3836 self.condition.generate_evaluation_code(code)
3837 self.condition.generate_disposal_code(code)
3840 self.condition.result())
3841 self.condition.free_temps(code)
3842 self.body.generate_execution_code(code)
3843 code.put_label(code.continue_label)
3845 break_label = code.break_label
3846 code.set_loop_labels(old_loop_labels)
3847 if self.else_clause:
3848 code.putln("/*else*/ {")
3849 self.else_clause.generate_execution_code(code)
3851 code.put_label(break_label)
3853 def annotate(self, code):
3854 self.condition.annotate(code)
3855 self.body.annotate(code)
3856 if self.else_clause:
3857 self.else_clause.annotate(code)
3860 def ForStatNode(pos, **kw):
3861 if 'iterator' in kw:
3862 return ForInStatNode(pos, **kw)
3864 return ForFromStatNode(pos, **kw)
3866 class ForInStatNode(LoopNode, StatNode):
3870 # iterator IteratorNode
3872 # else_clause StatNode
3873 # item NextNode used internally
3875 child_attrs = ["target", "iterator", "body", "else_clause"]
3878 def analyse_declarations(self, env):
3879 self.target.analyse_target_declaration(env)
3880 self.body.analyse_declarations(env)
3881 if self.else_clause:
3882 self.else_clause.analyse_declarations(env)
3884 def analyse_expressions(self, env):
3886 self.target.analyse_target_types(env)
3887 self.iterator.analyse_expressions(env)
3888 self.item = ExprNodes.NextNode(self.iterator, env)
3889 self.item = self.item.coerce_to(self.target.type, env)
3890 self.item.allocate_temps(env)
3891 self.target.allocate_target_temps(env, self.item)
3892 #self.item.release_temp(env)
3893 #self.target.release_target_temp(env)
3894 self.body.analyse_expressions(env)
3895 if self.else_clause:
3896 self.else_clause.analyse_expressions(env)
3897 self.iterator.release_temp(env)
3899 def generate_execution_code(self, code):
3900 old_loop_labels = code.new_loop_labels()
3901 self.iterator.allocate_counter_temp(code)
3902 self.iterator.generate_evaluation_code(code)
3905 self.item.generate_evaluation_code(code)
3906 self.target.generate_assignment_code(self.item, code)
3907 self.body.generate_execution_code(code)
3908 code.put_label(code.continue_label)
3911 break_label = code.break_label
3912 code.set_loop_labels(old_loop_labels)
3913 if self.else_clause:
3914 code.putln("/*else*/ {")
3915 self.else_clause.generate_execution_code(code)
3917 code.put_label(break_label)
3918 self.iterator.release_counter_temp(code)
3919 self.iterator.generate_disposal_code(code)
3920 self.iterator.free_temps(code)
3922 def annotate(self, code):
3923 self.target.annotate(code)
3924 self.iterator.annotate(code)
3925 self.body.annotate(code)
3926 if self.else_clause:
3927 self.else_clause.annotate(code)
3928 self.item.annotate(code)
3931 class ForFromStatNode(LoopNode, StatNode):
3932 # for name from expr rel name rel expr
3939 # step ExprNode or None
3941 # else_clause StatNode or None
3947 # loopvar_node ExprNode (usually a NameNode or temp node)
3948 # py_loopvar_node PyTempNode or None
3949 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3951 is_py_target = False
3953 py_loopvar_node = None
3956 def analyse_declarations(self, env):
3957 self.target.analyse_target_declaration(env)
3958 self.body.analyse_declarations(env)
3959 if self.else_clause:
3960 self.else_clause.analyse_declarations(env)
3962 def analyse_expressions(self, env):
3964 self.target.analyse_target_types(env)
3965 self.bound1.analyse_types(env)
3966 self.bound2.analyse_types(env)
3967 if self.step is not None:
3968 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3969 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3970 self.step.analyse_types(env)
3972 target_type = self.target.type
3973 if self.target.type.is_numeric:
3974 loop_type = self.target.type
3976 loop_type = PyrexTypes.c_int_type
3977 if not self.bound1.type.is_pyobject:
3978 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3979 if not self.bound2.type.is_pyobject:
3980 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3981 if self.step is not None and not self.step.type.is_pyobject:
3982 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3983 self.bound1 = self.bound1.coerce_to(loop_type, env)
3984 self.bound2 = self.bound2.coerce_to(loop_type, env)
3985 if not self.bound2.is_literal:
3986 self.bound2 = self.bound2.coerce_to_temp(env)
3987 if self.step is not None:
3988 self.step = self.step.coerce_to(loop_type, env)
3989 if not self.step.is_literal:
3990 self.step = self.step.coerce_to_temp(env)
3992 target_type = self.target.type
3993 if not (target_type.is_pyobject or target_type.is_numeric):
3994 error(self.target.pos,
3995 "for-from loop variable must be c numeric type or Python object")
3996 if target_type.is_numeric:
3997 self.is_py_target = False
3998 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3999 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4000 self.loopvar_node = self.target
4001 self.py_loopvar_node = None
4003 self.is_py_target = True
4004 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4005 c_loopvar_node.allocate_temps(env)
4006 self.loopvar_node = c_loopvar_node
4007 self.py_loopvar_node = \
4008 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4009 self.bound1.allocate_temps(env)
4010 self.bound2.allocate_temps(env)
4011 if self.step is not None:
4012 self.step.allocate_temps(env)
4013 if self.is_py_target:
4014 self.py_loopvar_node.allocate_temps(env)
4015 self.target.allocate_target_temps(env, self.py_loopvar_node)
4016 #self.target.release_target_temp(env)
4017 #self.py_loopvar_node.release_temp(env)
4018 self.body.analyse_expressions(env)
4019 if self.is_py_target:
4020 c_loopvar_node.release_temp(env)
4021 if self.else_clause:
4022 self.else_clause.analyse_expressions(env)
4023 self.bound1.release_temp(env)
4024 self.bound2.release_temp(env)
4025 if self.step is not None:
4026 self.step.release_temp(env)
4028 def generate_execution_code(self, code):
4029 old_loop_labels = code.new_loop_labels()
4030 from_range = self.from_range
4031 self.bound1.generate_evaluation_code(code)
4032 self.bound2.generate_evaluation_code(code)
4033 offset, incop = self.relation_table[self.relation1]
4034 if self.step is not None:
4035 self.step.generate_evaluation_code(code)
4036 step = self.step.result()
4037 incop = "%s=%s" % (incop[0], step)
4039 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4041 loopvar_name = self.loopvar_node.result()
4043 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4045 self.bound1.result(), offset,
4046 loopvar_name, self.relation2, self.bound2.result(),
4047 loopvar_name, incop))
4048 if self.py_loopvar_node:
4049 self.py_loopvar_node.generate_evaluation_code(code)
4050 self.target.generate_assignment_code(self.py_loopvar_node, code)
4052 code.putln("%s = %s;" % (
4053 self.target.result(), loopvar_name))
4054 self.body.generate_execution_code(code)
4055 code.put_label(code.continue_label)
4056 if self.py_loopvar_node:
4057 # This mess is to make for..from loops with python targets behave
4058 # exactly like those with C targets with regards to re-assignment
4059 # of the loop variable.
4061 if self.target.entry.is_pyglobal:
4062 # We know target is a NameNode, this is the only ugly case.
4063 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4064 target_node.result_code = code.funcstate.allocate_temp(py_object_type, False)
4065 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4066 target_node.result_code,
4067 Naming.module_cname,
4068 self.target.entry.interned_cname,
4069 code.error_goto_if_null(target_node.result_code, self.target.pos)))
4070 code.put_gotref(target_node.result_code)
4072 target_node = self.target
4073 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4074 from_py_node.temp_code = loopvar_name
4075 from_py_node.generate_result_code(code)
4076 if self.target.entry.is_pyglobal:
4077 code.put_decref_clear(target_node.result_code, py_object_type)
4078 code.funcstate.release_temp(target_node.result_code)
4080 if self.py_loopvar_node:
4081 # This is potentially wasteful, but we don't want the semantics to
4082 # depend on whether or not the loop is a python type.
4083 self.py_loopvar_node.generate_evaluation_code(code)
4084 self.target.generate_assignment_code(self.py_loopvar_node, code)
4085 break_label = code.break_label
4086 code.set_loop_labels(old_loop_labels)
4087 if self.else_clause:
4088 code.putln("/*else*/ {")
4089 self.else_clause.generate_execution_code(code)
4091 code.put_label(break_label)
4092 self.bound1.generate_disposal_code(code)
4093 self.bound1.free_temps(code)
4094 self.bound2.generate_disposal_code(code)
4095 self.bound2.free_temps(code)
4096 if self.step is not None:
4097 self.step.generate_disposal_code(code)
4098 self.step.free_temps(code)
4100 code.funcstate.release_temp(loopvar_name)
4103 # {relop : (initial offset, increment op)}
4110 def annotate(self, code):
4111 self.target.annotate(code)
4112 self.bound1.annotate(code)
4113 self.bound2.annotate(code)
4115 self.bound2.annotate(code)
4116 self.body.annotate(code)
4117 if self.else_clause:
4118 self.else_clause.annotate(code)
4121 class WithStatNode(StatNode):
4123 Represents a Python with statement.
4125 This is only used at parse tree level; and is not present in
4126 analysis or generation phases.
4128 # manager The with statement manager object
4129 # target Node (lhs expression)
4131 child_attrs = ["manager", "target", "body"]
4133 class TryExceptStatNode(StatNode):
4134 # try .. except statement
4137 # except_clauses [ExceptClauseNode]
4138 # else_clause StatNode or None
4139 # cleanup_list [Entry] old style temps to clean up on error
4141 child_attrs = ["body", "except_clauses", "else_clause"]
4143 def analyse_control_flow(self, env):
4144 env.start_branching(self.pos)
4145 self.body.analyse_control_flow(env)
4146 successful_try = env.control_flow # grab this for later
4147 env.next_branch(self.body.end_pos())
4148 env.finish_branching(self.body.end_pos())
4150 env.start_branching(self.except_clauses[0].pos)
4151 for except_clause in self.except_clauses:
4152 except_clause.analyse_control_flow(env)
4153 env.next_branch(except_clause.end_pos())
4155 # the else cause it executed only when the try clause finishes
4156 env.control_flow.incoming = successful_try
4157 if self.else_clause:
4158 self.else_clause.analyse_control_flow(env)
4159 env.finish_branching(self.end_pos())
4161 def analyse_declarations(self, env):
4162 self.body.analyse_declarations(env)
4163 for except_clause in self.except_clauses:
4164 except_clause.analyse_declarations(env)
4165 if self.else_clause:
4166 self.else_clause.analyse_declarations(env)
4168 env.use_utility_code(reset_exception_utility_code)
4170 def analyse_expressions(self, env):
4171 self.body.analyse_expressions(env)
4172 self.cleanup_list = env.free_temp_entries[:]
4173 default_clause_seen = 0
4174 for except_clause in self.except_clauses:
4175 except_clause.analyse_expressions(env)
4176 if default_clause_seen:
4177 error(except_clause.pos, "default 'except:' must be last")
4178 if not except_clause.pattern:
4179 default_clause_seen = 1
4180 self.has_default_clause = default_clause_seen
4181 if self.else_clause:
4182 self.else_clause.analyse_expressions(env)
4185 gil_message = "Try-except statement"
4187 def generate_execution_code(self, code):
4188 old_return_label = code.return_label
4189 old_break_label = code.break_label
4190 old_continue_label = code.continue_label
4191 old_error_label = code.new_error_label()
4192 our_error_label = code.error_label
4193 except_end_label = code.new_label('exception_handled')
4194 except_error_label = code.new_label('except_error')
4195 except_return_label = code.new_label('except_return')
4196 try_return_label = code.new_label('try_return')
4197 try_break_label = code.new_label('try_break')
4198 try_continue_label = code.new_label('try_continue')
4199 try_end_label = code.new_label('try_end')
4202 code.putln("PyObject %s;" %
4203 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4204 code.putln("__Pyx_ExceptionSave(%s);" %
4205 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4206 for var in Naming.exc_save_vars:
4207 code.put_xgotref(var)
4210 code.return_label = try_return_label
4211 code.break_label = try_break_label
4212 code.continue_label = try_continue_label
4213 self.body.generate_execution_code(code)
4216 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4217 code.error_label = except_error_label
4218 code.return_label = except_return_label
4219 if self.else_clause:
4222 self.else_clause.generate_execution_code(code)
4225 for var in Naming.exc_save_vars:
4226 code.put_xdecref_clear(var, py_object_type)
4227 code.put_goto(try_end_label)
4228 if code.label_used(try_return_label):
4229 code.put_label(try_return_label)
4230 for var in Naming.exc_save_vars:
4231 code.put_xdecref_clear(var, py_object_type)
4232 code.put_goto(old_return_label)
4233 code.put_label(our_error_label)
4234 code.put_var_xdecrefs_clear(self.cleanup_list)
4235 for temp_name, type in temps_to_clean_up:
4236 code.put_xdecref_clear(temp_name, type)
4237 for except_clause in self.except_clauses:
4238 except_clause.generate_handling_code(code, except_end_label)
4240 error_label_used = code.label_used(except_error_label)
4241 if error_label_used or not self.has_default_clause:
4242 if error_label_used:
4243 code.put_label(except_error_label)
4244 for var in Naming.exc_save_vars:
4245 code.put_xdecref(var, py_object_type)
4246 code.put_goto(old_error_label)
4248 if code.label_used(try_break_label):
4249 code.put_label(try_break_label)
4250 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4251 code.putln("__Pyx_ExceptionReset(%s);" %
4252 ', '.join(Naming.exc_save_vars))
4253 code.put_goto(old_break_label)
4255 if code.label_used(try_continue_label):
4256 code.put_label(try_continue_label)
4257 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4258 code.putln("__Pyx_ExceptionReset(%s);" %
4259 ', '.join(Naming.exc_save_vars))
4260 code.put_goto(old_continue_label)
4262 if code.label_used(except_return_label):
4263 code.put_label(except_return_label)
4264 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4265 code.putln("__Pyx_ExceptionReset(%s);" %
4266 ', '.join(Naming.exc_save_vars))
4267 code.put_goto(old_return_label)
4269 if code.label_used(except_end_label):
4270 code.put_label(except_end_label)
4271 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4272 code.putln("__Pyx_ExceptionReset(%s);" %
4273 ', '.join(Naming.exc_save_vars))
4274 code.put_label(try_end_label)
4277 code.return_label = old_return_label
4278 code.break_label = old_break_label
4279 code.continue_label = old_continue_label
4280 code.error_label = old_error_label
4282 def annotate(self, code):
4283 self.body.annotate(code)
4284 for except_node in self.except_clauses:
4285 except_node.annotate(code)
4286 if self.else_clause:
4287 self.else_clause.annotate(code)
4290 class ExceptClauseNode(Node):
4291 # Part of try ... except statement.
4294 # target ExprNode or None
4296 # excinfo_target NameNode or None optional target for exception info
4297 # match_flag string result of exception match
4298 # exc_value ExcValueNode used internally
4299 # function_name string qualified name of enclosing function
4300 # exc_vars (string * 3) local exception variables
4302 # excinfo_target is never set by the parser, but can be set by a transform
4303 # in order to extract more extensive information about the exception as a
4304 # sys.exc_info()-style tuple into a target variable
4306 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4309 excinfo_target = None
4311 def analyse_declarations(self, env):
4313 self.target.analyse_target_declaration(env)
4314 if self.excinfo_target is not None:
4315 self.excinfo_target.analyse_target_declaration(env)
4316 self.body.analyse_declarations(env)
4318 def analyse_expressions(self, env):
4320 genv = env.global_scope()
4321 self.function_name = env.qualified_name
4323 self.pattern.analyse_expressions(env)
4324 self.pattern = self.pattern.coerce_to_pyobject(env)
4325 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4326 self.pattern.release_temp(env)
4327 env.release_temp(self.match_flag)
4329 if self.target or self.excinfo_target:
4330 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4332 self.exc_vars = None
4335 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4336 self.exc_value.allocate_temps(env)
4337 self.target.analyse_target_expression(env, self.exc_value)
4338 if self.excinfo_target is not None:
4340 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4341 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4342 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4343 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4345 self.excinfo_tuple.analyse_expressions(env)
4346 self.excinfo_tuple.allocate_temps(env)
4347 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4349 self.body.analyse_expressions(env)
4352 for var in self.exc_vars:
4353 env.release_temp(var)
4355 def generate_handling_code(self, code, end_label):
4356 code.mark_pos(self.pos)
4358 self.pattern.generate_evaluation_code(code)
4360 "%s = PyErr_ExceptionMatches(%s);" % (
4362 self.pattern.py_result()))
4363 self.pattern.generate_disposal_code(code)
4364 self.pattern.free_temps(code)
4369 code.putln("/*except:*/ {")
4372 exc_vars = self.exc_vars
4373 elif not getattr(self.body, 'stats', True):
4374 # most simple case: no exception variable, empty body (pass)
4375 # => reset the exception state, done
4376 code.putln("PyErr_Restore(0,0,0);")
4377 code.put_goto(end_label)
4381 # during type analysis, we didn't know if we need the
4382 # exception value, but apparently, we do
4383 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4387 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4388 # We always have to fetch the exception value even if
4389 # there is no target, because this also normalises the
4390 # exception and stores it in the thread state.
4391 code.globalstate.use_utility_code(get_exception_utility_code)
4392 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4393 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4394 code.error_goto(self.pos)))
4398 self.exc_value.generate_evaluation_code(code)
4399 self.target.generate_assignment_code(self.exc_value, code)
4400 if self.excinfo_target is not None:
4401 self.excinfo_tuple.generate_evaluation_code(code)
4402 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4405 old_break_label, old_continue_label = code.break_label, code.continue_label
4406 code.break_label = code.new_label('except_break')
4407 code.continue_label = code.new_label('except_continue')
4409 old_exc_vars = code.funcstate.exc_vars
4410 code.funcstate.exc_vars = exc_vars
4411 self.body.generate_execution_code(code)
4412 code.funcstate.exc_vars = old_exc_vars
4413 for var in exc_vars:
4414 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4415 code.put_goto(end_label)
4417 if code.label_used(code.break_label):
4418 code.put_label(code.break_label)
4419 for var in exc_vars:
4420 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4421 code.put_goto(old_break_label)
4422 code.break_label = old_break_label
4424 if code.label_used(code.continue_label):
4425 code.put_label(code.continue_label)
4426 for var in exc_vars:
4427 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4428 code.put_goto(old_continue_label)
4429 code.continue_label = old_continue_label
4431 if not self.exc_vars:
4432 # clean up locally allocated temps
4433 for temp in exc_vars:
4434 code.funcstate.release_temp(temp)
4439 def annotate(self, code):
4441 self.pattern.annotate(code)
4443 self.target.annotate(code)
4444 self.body.annotate(code)
4447 class TryFinallyStatNode(StatNode):
4448 # try ... finally statement
4451 # finally_clause StatNode
4453 # cleanup_list [Entry] old_style temps to clean up on error
4455 # The plan is that we funnel all continue, break
4456 # return and error gotos into the beginning of the
4457 # finally block, setting a variable to remember which
4458 # one we're doing. At the end of the finally block, we
4459 # switch on the variable to figure out where to go.
4460 # In addition, if we're doing an error, we save the
4461 # exception on entry to the finally block and restore
4464 child_attrs = ["body", "finally_clause"]
4466 preserve_exception = 1
4468 disallow_continue_in_try_finally = 0
4469 # There doesn't seem to be any point in disallowing
4470 # continue in the try block, since we have no problem
4473 def create_analysed(pos, env, body, finally_clause):
4474 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4475 node.cleanup_list = []
4477 create_analysed = staticmethod(create_analysed)
4479 def analyse_control_flow(self, env):
4480 env.start_branching(self.pos)
4481 self.body.analyse_control_flow(env)
4482 env.next_branch(self.body.end_pos())
4483 env.finish_branching(self.body.end_pos())
4484 self.finally_clause.analyse_control_flow(env)
4486 def analyse_declarations(self, env):
4487 self.body.analyse_declarations(env)
4488 self.finally_clause.analyse_declarations(env)
4490 def analyse_expressions(self, env):
4491 self.body.analyse_expressions(env)
4492 self.cleanup_list = env.free_temp_entries[:]
4493 self.finally_clause.analyse_expressions(env)
4496 gil_message = "Try-finally statement"
4498 def generate_execution_code(self, code):
4499 old_error_label = code.error_label
4500 old_labels = code.all_new_labels()
4501 new_labels = code.get_all_labels()
4502 new_error_label = code.error_label
4503 catch_label = code.new_label()
4506 if self.disallow_continue_in_try_finally:
4507 was_in_try_finally = code.funcstate.in_try_finally
4508 code.funcstate.in_try_finally = 1
4509 self.body.generate_execution_code(code)
4510 if self.disallow_continue_in_try_finally:
4511 code.funcstate.in_try_finally = was_in_try_finally
4514 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4518 error_label_used = 0
4519 for i, new_label in enumerate(new_labels):
4520 if new_label in code.labels_used:
4521 cases_used.append(i)
4522 if new_label == new_error_label:
4523 error_label_used = 1
4524 error_label_case = i
4528 if error_label_used and self.preserve_exception:
4530 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4532 "int %s;" % Naming.exc_lineno_name)
4533 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4534 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4535 code.putln(exc_var_init_zero)
4537 exc_var_init_zero = None
4538 code.use_label(catch_label)
4540 "__pyx_why = 0; goto %s;" % catch_label)
4541 for i in cases_used:
4542 new_label = new_labels[i]
4543 #if new_label and new_label != "<try>":
4544 if new_label == new_error_label and self.preserve_exception:
4545 self.put_error_catcher(code,
4546 new_error_label, i+1, catch_label, temps_to_clean_up)
4548 code.put('%s: ' % new_label)
4549 if exc_var_init_zero:
4550 code.putln(exc_var_init_zero)
4551 code.putln("__pyx_why = %s; goto %s;" % (
4554 code.put_label(catch_label)
4555 code.set_all_labels(old_labels)
4556 if error_label_used:
4557 code.new_error_label()
4558 finally_error_label = code.error_label
4559 self.finally_clause.generate_execution_code(code)
4560 if error_label_used:
4561 if finally_error_label in code.labels_used and self.preserve_exception:
4562 over_label = code.new_label()
4563 code.put_goto(over_label);
4564 code.put_label(finally_error_label)
4565 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4566 for var in Naming.exc_vars:
4567 code.putln("Py_XDECREF(%s);" % var)
4569 code.put_goto(old_error_label)
4570 code.put_label(over_label)
4571 code.error_label = old_error_label
4574 "switch (__pyx_why) {")
4575 for i in cases_used:
4576 old_label = old_labels[i]
4577 if old_label == old_error_label and self.preserve_exception:
4578 self.put_error_uncatcher(code, i+1, old_error_label)
4580 code.use_label(old_label)
4582 "case %s: goto %s;" % (
4590 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4591 code.globalstate.use_utility_code(restore_exception_utility_code)
4598 code.put_var_xdecrefs_clear(self.cleanup_list)
4599 for temp_name, type in temps_to_clean_up:
4600 code.put_xdecref_clear(temp_name, type)
4602 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4606 Naming.exc_lineno_name, Naming.lineno_cname))
4610 code.put_goto(catch_label)
4614 def put_error_uncatcher(self, code, i, error_label):
4615 code.globalstate.use_utility_code(restore_exception_utility_code)
4620 "__Pyx_ErrRestore(%s, %s, %s);" %
4624 Naming.lineno_cname, Naming.exc_lineno_name))
4625 for var in Naming.exc_vars:
4629 code.put_goto(error_label)
4633 def annotate(self, code):
4634 self.body.annotate(code)
4635 self.finally_clause.annotate(code)
4638 class GILStatNode(TryFinallyStatNode):
4639 # 'with gil' or 'with nogil' statement
4641 # state string 'gil' or 'nogil'
4645 preserve_exception = 0
4647 def __init__(self, pos, state, body):
4649 TryFinallyStatNode.__init__(self, pos,
4651 finally_clause = GILExitNode(pos, state = state))
4653 def analyse_expressions(self, env):
4654 env.use_utility_code(force_init_threads_utility_code)
4655 was_nogil = env.nogil
4657 TryFinallyStatNode.analyse_expressions(self, env)
4658 env.nogil = was_nogil
4660 def gil_check(self, env):
4663 def generate_execution_code(self, code):
4664 code.mark_pos(self.pos)
4665 if self.state == 'gil':
4666 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4668 code.putln("{ PyThreadState *_save;")
4669 code.putln("Py_UNBLOCK_THREADS")
4670 TryFinallyStatNode.generate_execution_code(self, code)
4674 class GILExitNode(StatNode):
4675 # Used as the 'finally' block in a GILStatNode
4677 # state string 'gil' or 'nogil'
4681 def analyse_expressions(self, env):
4684 def generate_execution_code(self, code):
4685 if self.state == 'gil':
4686 code.putln("PyGILState_Release();")
4688 code.putln("Py_BLOCK_THREADS")
4691 class CImportStatNode(StatNode):
4694 # module_name string Qualified name of module being imported
4695 # as_name string or None Name specified in "as" clause, if any
4699 def analyse_declarations(self, env):
4700 if not env.is_module_scope:
4701 error(self.pos, "cimport only allowed at module level")
4703 module_scope = env.find_module(self.module_name, self.pos)
4704 if "." in self.module_name:
4705 names = [EncodedString(name) for name in self.module_name.split(".")]
4707 top_module_scope = env.context.find_submodule(top_name)
4708 module_scope = top_module_scope
4709 for name in names[1:]:
4710 submodule_scope = module_scope.find_submodule(name)
4711 module_scope.declare_module(name, submodule_scope, self.pos)
4712 module_scope = submodule_scope
4714 env.declare_module(self.as_name, module_scope, self.pos)
4716 env.declare_module(top_name, top_module_scope, self.pos)
4718 name = self.as_name or self.module_name
4719 env.declare_module(name, module_scope, self.pos)
4721 def analyse_expressions(self, env):
4724 def generate_execution_code(self, code):
4728 class FromCImportStatNode(StatNode):
4729 # from ... cimport statement
4731 # module_name string Qualified name of module
4732 # imported_names [(pos, name, as_name, kind)] Names to be imported
4736 def analyse_declarations(self, env):
4737 if not env.is_module_scope:
4738 error(self.pos, "cimport only allowed at module level")
4740 module_scope = env.find_module(self.module_name, self.pos)
4741 env.add_imported_module(module_scope)
4742 for pos, name, as_name, kind in self.imported_names:
4744 for local_name, entry in module_scope.entries.items():
4745 env.add_imported_entry(local_name, entry, pos)
4747 entry = module_scope.lookup(name)
4749 if kind and not self.declaration_matches(entry, kind):
4750 entry.redeclared(pos)
4752 if kind == 'struct' or kind == 'union':
4753 entry = module_scope.declare_struct_or_union(name,
4754 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4755 elif kind == 'class':
4756 entry = module_scope.declare_c_class(name, pos = pos,
4757 module_name = self.module_name)
4759 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4760 if submodule_scope.parent_module is module_scope:
4761 env.declare_module(as_name or name, submodule_scope, self.pos)
4763 error(pos, "Name '%s' not declared in module '%s'"
4764 % (name, self.module_name))
4767 local_name = as_name or name
4768 env.add_imported_entry(local_name, entry, pos)
4770 def declaration_matches(self, entry, kind):
4771 if not entry.is_type:
4775 if not type.is_extension_type:
4778 if not type.is_struct_or_union:
4780 if kind != type.kind:
4784 def analyse_expressions(self, env):
4787 def generate_execution_code(self, code):
4791 class FromImportStatNode(StatNode):
4792 # from ... import statement
4795 # items [(string, NameNode)]
4796 # interned_items [(string, NameNode, ExprNode)]
4797 # item PyTempNode used internally
4798 # import_star boolean used internally
4800 child_attrs = ["module"]
4803 def analyse_declarations(self, env):
4804 for name, target in self.items:
4806 if not env.is_module_scope:
4807 error(self.pos, "import * only allowed at module level")
4809 env.has_import_star = 1
4810 self.import_star = 1
4812 target.analyse_target_declaration(env)
4814 def analyse_expressions(self, env):
4816 self.module.analyse_expressions(env)
4817 self.item = ExprNodes.PyTempNode(self.pos, env)
4818 self.item.allocate_temp(env)
4819 self.interned_items = []
4820 for name, target in self.items:
4822 for _, entry in env.entries.items():
4823 if not entry.is_type and entry.type.is_extension_type:
4824 env.use_utility_code(ExprNodes.type_test_utility_code)
4827 entry = env.lookup(target.name)
4828 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4829 continue # already cimported
4830 target.analyse_target_expression(env, None)
4831 if target.type is py_object_type:
4834 coerced_item = self.item.coerce_to(target.type, env)
4835 self.interned_items.append(
4836 (env.intern_identifier(name), target, coerced_item))
4837 #target.release_target_temp(env) # was release_temp ?!?
4838 self.module.release_temp(env)
4839 self.item.release_temp(env)
4841 def generate_execution_code(self, code):
4842 self.module.generate_evaluation_code(code)
4843 if self.import_star:
4845 'if (%s(%s) < 0) %s;' % (
4847 self.module.py_result(),
4848 code.error_goto(self.pos)))
4849 for cname, target, coerced_item in self.interned_items:
4851 '%s = PyObject_GetAttr(%s, %s); %s' % (
4853 self.module.py_result(),
4855 code.error_goto_if_null(self.item.result(), self.pos)))
4856 code.put_gotref(self.item.py_result())
4857 if coerced_item is None:
4858 target.generate_assignment_code(self.item, code)
4860 coerced_item.allocate_temp_result(code)
4861 coerced_item.generate_result_code(code)
4862 target.generate_assignment_code(coerced_item, code)
4863 if self.item.result() != coerced_item.result():
4864 code.put_decref_clear(self.item.result(), self.item.type)
4865 self.module.generate_disposal_code(code)
4866 self.module.free_temps(code)
4870 #------------------------------------------------------------------------------------
4872 # Runtime support code
4874 #------------------------------------------------------------------------------------
4876 utility_function_predeclarations = \
4879 #define INLINE __inline__
4881 #define INLINE __inline
4886 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4890 static int %(skip_dispatch_cname)s = 0;
4892 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4894 if Options.gcc_branch_hints:
4895 branch_prediction_macros = \
4898 /* Test for GCC > 2.95 */
4899 #if __GNUC__ > 2 || \
4900 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4901 #define likely(x) __builtin_expect(!!(x), 1)
4902 #define unlikely(x) __builtin_expect(!!(x), 0)
4903 #else /* __GNUC__ > 2 ... */
4904 #define likely(x) (x)
4905 #define unlikely(x) (x)
4906 #endif /* __GNUC__ > 2 ... */
4907 #else /* __GNUC__ */
4908 #define likely(x) (x)
4909 #define unlikely(x) (x)
4910 #endif /* __GNUC__ */
4913 branch_prediction_macros = \
4915 #define likely(x) (x)
4916 #define unlikely(x) (x)
4919 #get_name_predeclaration = \
4920 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4922 #get_name_interned_predeclaration = \
4923 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4925 #------------------------------------------------------------------------------------
4927 printing_utility_code = UtilityCode(
4929 static int __Pyx_Print(PyObject *, int); /*proto*/
4930 #if PY_MAJOR_VERSION >= 3
4931 static PyObject* %s = 0;
4932 static PyObject* %s = 0;
4934 """ % (Naming.print_function, Naming.print_function_kwargs),
4936 #if PY_MAJOR_VERSION < 3
4937 static PyObject *__Pyx_GetStdout(void) {
4938 PyObject *f = PySys_GetObject((char *)"stdout");
4940 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4945 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4950 if (!(f = __Pyx_GetStdout()))
4952 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4953 if (PyFile_SoftSpace(f, 1)) {
4954 if (PyFile_WriteString(" ", f) < 0)
4957 v = PyTuple_GET_ITEM(arg_tuple, i);
4958 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4960 if (PyString_Check(v)) {
4961 char *s = PyString_AsString(v);
4962 Py_ssize_t len = PyString_Size(v);
4964 isspace(Py_CHARMASK(s[len-1])) &&
4966 PyFile_SoftSpace(f, 0);
4970 if (PyFile_WriteString("\n", f) < 0)
4972 PyFile_SoftSpace(f, 0);
4977 #else /* Python 3 has a print function */
4979 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4980 PyObject* kwargs = 0;
4981 PyObject* result = 0;
4982 PyObject* end_string;
4983 if (!%(PRINT_FUNCTION)s) {
4984 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4985 if (!%(PRINT_FUNCTION)s)
4989 if (!%(PRINT_KWARGS)s) {
4990 %(PRINT_KWARGS)s = PyDict_New();
4991 if (!%(PRINT_KWARGS)s)
4993 end_string = PyUnicode_FromStringAndSize(" ", 1);
4996 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4997 Py_DECREF(end_string);
5000 Py_DECREF(end_string);
5002 kwargs = %(PRINT_KWARGS)s;
5004 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5012 """ % {'BUILTINS' : Naming.builtins_cname,
5013 'PRINT_FUNCTION' : Naming.print_function,
5014 'PRINT_KWARGS' : Naming.print_function_kwargs}
5018 printing_one_utility_code = UtilityCode(
5020 static int __Pyx_PrintOne(PyObject *o); /*proto*/
5023 #if PY_MAJOR_VERSION < 3
5025 static int __Pyx_PrintOne(PyObject *o) {
5027 if (!(f = __Pyx_GetStdout()))
5029 if (PyFile_SoftSpace(f, 0)) {
5030 if (PyFile_WriteString(" ", f) < 0)
5033 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5035 if (PyFile_WriteString("\n", f) < 0)
5038 /* the line below is just to avoid compiler
5039 * compiler warnings about unused functions */
5040 return __Pyx_Print(NULL, 0);
5043 #else /* Python 3 has a print function */
5045 static int __Pyx_PrintOne(PyObject *o) {
5047 PyObject* arg_tuple = PyTuple_New(1);
5048 if (unlikely(!arg_tuple))
5051 PyTuple_SET_ITEM(arg_tuple, 0, o);
5052 res = __Pyx_Print(arg_tuple, 1);
5053 Py_DECREF(arg_tuple);
5059 requires=[printing_utility_code])
5063 #------------------------------------------------------------------------------------
5065 # The following function is based on do_raise() from ceval.c.
5067 raise_utility_code = UtilityCode(
5069 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5072 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5076 /* First, check the traceback argument, replacing None with NULL. */
5077 if (tb == Py_None) {
5081 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5082 PyErr_SetString(PyExc_TypeError,
5083 "raise: arg 3 must be a traceback or None");
5086 /* Next, replace a missing value with None */
5087 if (value == NULL) {
5091 #if PY_VERSION_HEX < 0x02050000
5092 if (!PyClass_Check(type))
5094 if (!PyType_Check(type))
5097 /* Raising an instance. The value should be a dummy. */
5098 if (value != Py_None) {
5099 PyErr_SetString(PyExc_TypeError,
5100 "instance exception may not have a separate value");
5103 /* Normalize to raise <class>, <instance> */
5106 #if PY_VERSION_HEX < 0x02050000
5107 if (PyInstance_Check(type)) {
5108 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5113 PyErr_SetString(PyExc_TypeError,
5114 "raise: exception must be an old-style class or instance");
5118 type = (PyObject*) Py_TYPE(type);
5120 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5121 PyErr_SetString(PyExc_TypeError,
5122 "raise: exception class must be a subclass of BaseException");
5127 __Pyx_ErrRestore(type, value, tb);
5137 #------------------------------------------------------------------------------------
5139 reraise_utility_code = UtilityCode(
5141 static void __Pyx_ReRaise(void); /*proto*/
5144 static void __Pyx_ReRaise(void) {
5145 PyThreadState *tstate = PyThreadState_GET();
5146 PyObject* tmp_type = tstate->curexc_type;
5147 PyObject* tmp_value = tstate->curexc_value;
5148 PyObject* tmp_tb = tstate->curexc_traceback;
5149 tstate->curexc_type = tstate->exc_type;
5150 tstate->curexc_value = tstate->exc_value;
5151 tstate->curexc_traceback = tstate->exc_traceback;
5152 tstate->exc_type = 0;
5153 tstate->exc_value = 0;
5154 tstate->exc_traceback = 0;
5155 Py_XDECREF(tmp_type);
5156 Py_XDECREF(tmp_value);
5161 #------------------------------------------------------------------------------------
5163 arg_type_test_utility_code = UtilityCode(
5165 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5166 const char *name, int exact); /*proto*/
5169 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5170 const char *name, int exact)
5173 PyErr_Format(PyExc_SystemError, "Missing type object");
5176 if (none_allowed && obj == Py_None) return 1;
5178 if (Py_TYPE(obj) == type) return 1;
5181 if (PyObject_TypeCheck(obj, type)) return 1;
5183 PyErr_Format(PyExc_TypeError,
5184 "Argument '%s' has incorrect type (expected %s, got %s)",
5185 name, type->tp_name, Py_TYPE(obj)->tp_name);
5190 #------------------------------------------------------------------------------------
5192 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5193 # many or too few positional arguments were found. This handles
5194 # Py_ssize_t formatting correctly.
5196 raise_argtuple_invalid_utility_code = UtilityCode(
5198 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5199 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5202 static void __Pyx_RaiseArgtupleInvalid(
5203 const char* func_name,
5207 Py_ssize_t num_found)
5209 Py_ssize_t num_expected;
5210 const char *number, *more_or_less;
5212 if (num_found < num_min) {
5213 num_expected = num_min;
5214 more_or_less = "at least";
5216 num_expected = num_max;
5217 more_or_less = "at most";
5220 more_or_less = "exactly";
5222 number = (num_expected == 1) ? "" : "s";
5223 PyErr_Format(PyExc_TypeError,
5224 #if PY_VERSION_HEX < 0x02050000
5225 "%s() takes %s %d positional argument%s (%d given)",
5227 "%s() takes %s %zd positional argument%s (%zd given)",
5229 func_name, more_or_less, num_expected, number, num_found);
5233 raise_keyword_required_utility_code = UtilityCode(
5235 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5238 static INLINE void __Pyx_RaiseKeywordRequired(
5239 const char* func_name,
5242 PyErr_Format(PyExc_TypeError,
5243 #if PY_MAJOR_VERSION >= 3
5244 "%s() needs keyword-only argument %U", func_name, kw_name);
5246 "%s() needs keyword-only argument %s", func_name,
5247 PyString_AS_STRING(kw_name));
5252 raise_double_keywords_utility_code = UtilityCode(
5254 static void __Pyx_RaiseDoubleKeywordsError(
5255 const char* func_name, PyObject* kw_name); /*proto*/
5258 static void __Pyx_RaiseDoubleKeywordsError(
5259 const char* func_name,
5262 PyErr_Format(PyExc_TypeError,
5263 #if PY_MAJOR_VERSION >= 3
5264 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5266 "%s() got multiple values for keyword argument '%s'", func_name,
5267 PyString_AS_STRING(kw_name));
5272 #------------------------------------------------------------------------------------
5274 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5275 # were passed to a function, or if any keywords were passed to a
5276 # function that does not accept them.
5278 keyword_string_check_utility_code = UtilityCode(
5280 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5281 const char* function_name, int kw_allowed); /*proto*/
5284 static INLINE int __Pyx_CheckKeywordStrings(
5286 const char* function_name,
5291 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5292 #if PY_MAJOR_VERSION < 3
5293 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5295 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5297 goto invalid_keyword_type;
5299 if ((!kw_allowed) && unlikely(key))
5300 goto invalid_keyword;
5302 invalid_keyword_type:
5303 PyErr_Format(PyExc_TypeError,
5304 "%s() keywords must be strings", function_name);
5307 PyErr_Format(PyExc_TypeError,
5308 #if PY_MAJOR_VERSION < 3
5309 "%s() got an unexpected keyword argument '%s'",
5310 function_name, PyString_AsString(key));
5312 "%s() got an unexpected keyword argument '%U'",
5313 function_name, key);
5319 #------------------------------------------------------------------------------------
5321 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5322 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5323 # keywords will raise an invalid keyword error.
5325 # Three kinds of errors are checked: 1) non-string keywords, 2)
5326 # unexpected keywords and 3) overlap with positional arguments.
5328 # If num_posargs is greater 0, it denotes the number of positional
5329 # arguments that were passed and that must therefore not appear
5330 # amongst the keywords as well.
5332 # This method does not check for required keyword arguments.
5335 parse_keywords_utility_code = UtilityCode(
5337 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5338 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5339 const char* function_name); /*proto*/
5342 static int __Pyx_ParseOptionalKeywords(
5344 PyObject **argnames[],
5347 Py_ssize_t num_pos_args,
5348 const char* function_name)
5350 PyObject *key = 0, *value = 0;
5353 PyObject*** first_kw_arg = argnames + num_pos_args;
5355 while (PyDict_Next(kwds, &pos, &key, &value)) {
5356 name = first_kw_arg;
5357 while (*name && (**name != key)) name++;
5359 values[name-argnames] = value;
5361 #if PY_MAJOR_VERSION < 3
5362 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5364 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5366 goto invalid_keyword_type;
5368 for (name = first_kw_arg; *name; name++) {
5369 #if PY_MAJOR_VERSION >= 3
5370 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5371 PyUnicode_Compare(**name, key) == 0) break;
5373 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5374 _PyString_Eq(**name, key)) break;
5378 values[name-argnames] = value;
5380 /* unexpected keyword found */
5381 for (name=argnames; name != first_kw_arg; name++) {
5382 if (**name == key) goto arg_passed_twice;
5383 #if PY_MAJOR_VERSION >= 3
5384 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5385 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5387 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5388 _PyString_Eq(**name, key)) goto arg_passed_twice;
5392 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5394 goto invalid_keyword;
5402 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5404 invalid_keyword_type:
5405 PyErr_Format(PyExc_TypeError,
5406 "%s() keywords must be strings", function_name);
5409 PyErr_Format(PyExc_TypeError,
5410 #if PY_MAJOR_VERSION < 3
5411 "%s() got an unexpected keyword argument '%s'",
5412 function_name, PyString_AsString(key));
5414 "%s() got an unexpected keyword argument '%U'",
5415 function_name, key);
5422 #------------------------------------------------------------------------------------
5424 traceback_utility_code = UtilityCode(
5426 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5429 #include "compile.h"
5430 #include "frameobject.h"
5431 #include "traceback.h"
5433 static void __Pyx_AddTraceback(const char *funcname) {
5434 PyObject *py_srcfile = 0;
5435 PyObject *py_funcname = 0;
5436 PyObject *py_globals = 0;
5437 PyCodeObject *py_code = 0;
5438 PyFrameObject *py_frame = 0;
5440 #if PY_MAJOR_VERSION < 3
5441 py_srcfile = PyString_FromString(%(FILENAME)s);
5443 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5445 if (!py_srcfile) goto bad;
5447 #if PY_MAJOR_VERSION < 3
5448 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5450 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5454 #if PY_MAJOR_VERSION < 3
5455 py_funcname = PyString_FromString(funcname);
5457 py_funcname = PyUnicode_FromString(funcname);
5460 if (!py_funcname) goto bad;
5461 py_globals = PyModule_GetDict(%(GLOBALS)s);
5462 if (!py_globals) goto bad;
5463 py_code = PyCode_New(
5464 0, /*int argcount,*/
5465 #if PY_MAJOR_VERSION >= 3
5466 0, /*int kwonlyargcount,*/
5469 0, /*int stacksize,*/
5471 %(EMPTY_BYTES)s, /*PyObject *code,*/
5472 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5473 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5474 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5475 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5476 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5477 py_srcfile, /*PyObject *filename,*/
5478 py_funcname, /*PyObject *name,*/
5479 %(LINENO)s, /*int firstlineno,*/
5480 %(EMPTY_BYTES)s /*PyObject *lnotab*/
5482 if (!py_code) goto bad;
5483 py_frame = PyFrame_New(
5484 PyThreadState_GET(), /*PyThreadState *tstate,*/
5485 py_code, /*PyCodeObject *code,*/
5486 py_globals, /*PyObject *globals,*/
5487 0 /*PyObject *locals*/
5489 if (!py_frame) goto bad;
5490 py_frame->f_lineno = %(LINENO)s;
5491 PyTraceBack_Here(py_frame);
5493 Py_XDECREF(py_srcfile);
5494 Py_XDECREF(py_funcname);
5495 Py_XDECREF(py_code);
5496 Py_XDECREF(py_frame);
5499 'FILENAME': Naming.filename_cname,
5500 'LINENO': Naming.lineno_cname,
5501 'CFILENAME': Naming.cfilenm_cname,
5502 'CLINENO': Naming.clineno_cname,
5503 'GLOBALS': Naming.module_cname,
5504 'EMPTY_TUPLE' : Naming.empty_tuple,
5505 'EMPTY_BYTES' : Naming.empty_bytes,
5508 restore_exception_utility_code = UtilityCode(
5510 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5511 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5514 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5515 PyObject *tmp_type, *tmp_value, *tmp_tb;
5516 PyThreadState *tstate = PyThreadState_GET();
5518 #if PY_MAJOR_VERSION >= 3
5519 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5520 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5521 tmp_type = tstate->exc_type;
5522 tmp_value = tstate->exc_value;
5523 tmp_tb = tstate->exc_traceback;
5524 PyErr_NormalizeException(&type, &value, &tb);
5525 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5526 tstate->exc_type = 0;
5527 tstate->exc_value = 0;
5528 tstate->exc_traceback = 0;
5529 PyException_SetContext(value, tmp_value);
5530 Py_DECREF(tmp_type);
5535 tmp_type = tstate->curexc_type;
5536 tmp_value = tstate->curexc_value;
5537 tmp_tb = tstate->curexc_traceback;
5538 tstate->curexc_type = type;
5539 tstate->curexc_value = value;
5540 tstate->curexc_traceback = tb;
5541 Py_XDECREF(tmp_type);
5542 Py_XDECREF(tmp_value);
5546 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5547 PyThreadState *tstate = PyThreadState_GET();
5548 *type = tstate->curexc_type;
5549 *value = tstate->curexc_value;
5550 *tb = tstate->curexc_traceback;
5552 tstate->curexc_type = 0;
5553 tstate->curexc_value = 0;
5554 tstate->curexc_traceback = 0;
5559 #------------------------------------------------------------------------------------
5561 unraisable_exception_utility_code = UtilityCode(
5563 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5566 static void __Pyx_WriteUnraisable(const char *name) {
5567 PyObject *old_exc, *old_val, *old_tb;
5569 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5570 #if PY_MAJOR_VERSION < 3
5571 ctx = PyString_FromString(name);
5573 ctx = PyUnicode_FromString(name);
5575 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5577 PyErr_WriteUnraisable(Py_None);
5579 PyErr_WriteUnraisable(ctx);
5584 requires=[restore_exception_utility_code])
5586 #------------------------------------------------------------------------------------
5588 set_vtable_utility_code = UtilityCode(
5590 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5593 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5594 PyObject *pycobj = 0;
5597 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5600 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5613 #------------------------------------------------------------------------------------
5615 get_vtable_utility_code = UtilityCode(
5617 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5620 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5624 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5627 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5628 if (!*(void **)vtabptr)
5641 #------------------------------------------------------------------------------------
5643 init_string_tab_utility_code = UtilityCode(
5645 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5648 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5650 #if PY_MAJOR_VERSION < 3
5651 if (t->is_unicode && (!t->is_identifier)) {
5652 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5653 } else if (t->intern) {
5654 *t->p = PyString_InternFromString(t->s);
5656 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5658 #else /* Python 3+ has unicode identifiers */
5659 if (t->is_identifier || (t->is_unicode && t->intern)) {
5660 *t->p = PyUnicode_InternFromString(t->s);
5661 } else if (t->is_unicode) {
5662 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5664 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5675 #------------------------------------------------------------------------------------
5677 get_exception_utility_code = UtilityCode(
5679 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5682 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5683 PyObject *tmp_type, *tmp_value, *tmp_tb;
5684 PyThreadState *tstate = PyThreadState_GET();
5685 *type = tstate->curexc_type;
5686 *value = tstate->curexc_value;
5687 *tb = tstate->curexc_traceback;
5688 tstate->curexc_type = 0;
5689 tstate->curexc_value = 0;
5690 tstate->curexc_traceback = 0;
5691 PyErr_NormalizeException(type, value, tb);
5692 if (PyErr_Occurred())
5697 tmp_type = tstate->exc_type;
5698 tmp_value = tstate->exc_value;
5699 tmp_tb = tstate->exc_traceback;
5700 tstate->exc_type = *type;
5701 tstate->exc_value = *value;
5702 tstate->exc_traceback = *tb;
5703 /* Make sure tstate is in a consistent state when we XDECREF
5704 these objects (XDECREF may run arbitrary code). */
5705 Py_XDECREF(tmp_type);
5706 Py_XDECREF(tmp_value);
5718 #------------------------------------------------------------------------------------
5720 get_exception_tuple_utility_code = UtilityCode(proto="""
5721 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5724 static PyObject *__Pyx_GetExceptionTuple(void) {
5725 PyObject *type = NULL, *value = NULL, *tb = NULL;
5726 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5727 PyObject* exc_info = PyTuple_New(3);
5732 PyTuple_SET_ITEM(exc_info, 0, type);
5733 PyTuple_SET_ITEM(exc_info, 1, value);
5734 PyTuple_SET_ITEM(exc_info, 2, tb);
5741 requires=[get_exception_utility_code])
5743 #------------------------------------------------------------------------------------
5745 reset_exception_utility_code = UtilityCode(
5747 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5748 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5751 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5752 PyThreadState *tstate = PyThreadState_GET();
5753 *type = tstate->exc_type;
5754 *value = tstate->exc_value;
5755 *tb = tstate->exc_traceback;
5761 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5762 PyObject *tmp_type, *tmp_value, *tmp_tb;
5763 PyThreadState *tstate = PyThreadState_GET();
5764 tmp_type = tstate->exc_type;
5765 tmp_value = tstate->exc_value;
5766 tmp_tb = tstate->exc_traceback;
5767 tstate->exc_type = type;
5768 tstate->exc_value = value;
5769 tstate->exc_traceback = tb;
5770 Py_XDECREF(tmp_type);
5771 Py_XDECREF(tmp_value);
5776 #------------------------------------------------------------------------------------
5778 force_init_threads_utility_code = UtilityCode(
5780 #ifndef __PYX_FORCE_INIT_THREADS
5781 #if PY_VERSION_HEX < 0x02040200
5782 #define __PYX_FORCE_INIT_THREADS 1
5784 #define __PYX_FORCE_INIT_THREADS 0
5789 #------------------------------------------------------------------------------------
5791 # Note that cPython ignores PyTrace_EXCEPTION,
5792 # but maybe some other profilers don't.
5794 trace_utility_code = UtilityCode(proto="""
5795 #ifndef CYTHON_TRACING
5796 #define CYTHON_TRACING 1
5799 #ifndef CYTHON_TRACING_REUSE_FRAME
5800 #define CYTHON_TRACING_REUSE_FRAME 0
5805 #include "compile.h"
5806 #include "frameobject.h"
5807 #include "traceback.h"
5809 #if CYTHON_TRACING_REUSE_FRAME
5810 #define CYTHON_FRAME_MODIFIER static
5811 #define CYTHON_FRAME_DEL
5813 #define CYTHON_FRAME_MODIFIER
5814 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
5817 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
5818 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
5819 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
5820 int __Pyx_use_tracing = 0; \\
5821 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
5822 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
5825 #define __Pyx_TraceException() \\
5826 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5827 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
5829 PyThreadState_GET()->c_profilefunc( \\
5830 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
5831 Py_DECREF(exc_info); \\
5835 #define __Pyx_TraceReturn(result) \\
5836 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5837 PyThreadState_GET()->c_profilefunc( \\
5838 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
5839 CYTHON_FRAME_DEL; \\
5842 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
5843 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
5846 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
5847 #define __Pyx_TraceException()
5848 #define __Pyx_TraceReturn(result)
5849 #endif /* CYTHON_TRACING */
5852 "FRAME": Naming.frame_cname,
5853 "FRAME_CODE": Naming.frame_code_cname,
5859 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
5860 PyFrameObject** frame,
5861 const char *funcname,
5862 const char *srcfile,
5864 if (*frame == NULL || !CYTHON_TRACING_REUSE_FRAME) {
5865 if (*code == NULL) {
5866 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
5867 if (*code == NULL) return 0;
5869 *frame = PyFrame_New(
5870 PyThreadState_GET(), /*PyThreadState *tstate*/
5871 *code, /*PyCodeObject *code*/
5872 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
5873 0 /*PyObject *locals*/
5875 if (*frame == NULL) return 0;
5878 (*frame)->f_tstate = PyThreadState_GET();
5880 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
5883 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
5884 PyObject *py_srcfile = 0;
5885 PyObject *py_funcname = 0;
5886 PyCodeObject *py_code = 0;
5888 #if PY_MAJOR_VERSION < 3
5889 py_funcname = PyString_FromString(funcname);
5890 py_srcfile = PyString_FromString(srcfile);
5892 py_funcname = PyUnicode_FromString(funcname);
5893 py_srcfile = PyUnicode_FromString(srcfile);
5895 if (!py_funcname | !py_srcfile) goto bad;
5897 py_code = PyCode_New(
5898 0, /*int argcount,*/
5899 #if PY_MAJOR_VERSION >= 3
5900 0, /*int kwonlyargcount,*/
5903 0, /*int stacksize,*/
5905 %(EMPTY_BYTES)s, /*PyObject *code,*/
5906 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5907 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5908 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5909 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5910 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5911 py_srcfile, /*PyObject *filename,*/
5912 py_funcname, /*PyObject *name,*/
5913 firstlineno, /*int firstlineno,*/
5914 %(EMPTY_BYTES)s /*PyObject *lnotab*/
5918 Py_XDECREF(py_srcfile);
5919 Py_XDECREF(py_funcname);
5924 #endif /* CYTHON_TRACING */
5926 'EMPTY_TUPLE' : Naming.empty_tuple,
5927 'EMPTY_BYTES' : Naming.empty_bytes,
5928 "MODULE": Naming.module_cname,