2 # Pyrex - Parse tree nodes
5 import string, 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
21 from DebugFlags import debug_disposal_code
23 absolute_path_length = 0
25 def relative_position(pos):
27 We embed the relative filename in the generated C file, since we
28 don't want to have to regnerate and compile all the source code
29 whenever the Python install directory moves (which could happen,
30 e.g,. when distributing binaries.)
33 a position tuple -- (absolute filename, line number column position)
41 global absolute_path_length
42 if absolute_path_length==0:
43 absolute_path_length = len(os.path.abspath(os.getcwd()))
44 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
46 def embed_position(pos, docstring):
47 if not Options.embed_pos_in_docstring:
49 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
52 return EncodedString(pos_line)
54 # make sure we can encode the filename in the docstring encoding
55 # otherwise make the docstring a unicode string
56 encoding = docstring.encoding
57 if encoding is not None:
59 encoded_bytes = pos_line.encode(encoding)
60 except UnicodeEncodeError:
64 # reuse the string encoding of the original docstring
65 doc = EncodedString(pos_line)
67 doc = EncodedString(pos_line + u'\n' + docstring)
68 doc.encoding = encoding
72 # pos (string, int, int) Source file position
73 # is_name boolean Is a NameNode
74 # is_literal boolean Is a ConstNode
80 # All descandants should set child_attrs to a list of the attributes
81 # containing nodes considered "children" in the tree. Each such attribute
82 # can either contain a single node or a list of nodes. See Visitor.py.
85 def __init__(self, pos, **kw):
87 self.__dict__.update(kw)
89 gil_message = "Operation"
91 def gil_check(self, env):
96 error(self.pos, "%s not allowed without gil" % self.gil_message)
99 """Clone the node. This is defined as a shallow copy, except for member lists
100 amongst the child attributes (from get_child_accessors) which are also
101 copied. Lists containing child nodes are thus seen as a way for the node
102 to hold multiple children directly; the list is not treated as a seperate
103 level in the tree."""
104 result = copy.copy(self)
105 for attrname in result.child_attrs:
106 value = getattr(result, attrname)
107 if isinstance(value, list):
108 setattr(result, attrname, [x for x in value])
113 # There are 4 phases of parse tree processing, applied in order to
114 # all the statements in a given scope-block:
116 # (0) analyse_control_flow
117 # Create the control flow tree into which state can be asserted and
120 # (1) analyse_declarations
121 # Make symbol table entries for all declarations at the current
122 # level, both explicit (def, cdef, etc.) and implicit (assignment
123 # to an otherwise undeclared name).
125 # (2) analyse_expressions
126 # Determine the result types of expressions and fill in the
127 # 'type' attribute of each ExprNode. Insert coercion nodes into the
128 # tree where needed to convert to and from Python objects.
129 # Allocate temporary locals for intermediate results. Fill
130 # in the 'result_code' attribute of each ExprNode with a C code
134 # Emit C code for all declarations, statements and expressions.
135 # Recursively applies the 3 processing phases to the bodies of
139 def analyse_control_flow(self, env):
142 def analyse_declarations(self, env):
145 def analyse_expressions(self, env):
146 raise InternalError("analyse_expressions not implemented for %s" % \
147 self.__class__.__name__)
149 def generate_code(self, code):
150 raise InternalError("generate_code not implemented for %s" % \
151 self.__class__.__name__)
153 def annotate(self, code):
154 # mro does the wrong thing
155 if isinstance(self, BlockNode):
156 self.body.annotate(code)
161 except AttributeError:
163 if not self.child_attrs:
166 for attr in self.child_attrs:
167 child = getattr(self, attr)
168 # Sometimes lists, sometimes nodes
171 elif isinstance(child, list):
173 pos = max(pos, c.end_pos())
175 pos = max(pos, child.end_pos())
179 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
181 return "<...nesting level cutoff...>"
182 if encountered is None:
184 if id(self) in encountered:
185 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
186 encountered.add(id(self))
188 def dump_child(x, level):
189 if isinstance(x, Node):
190 return x.dump(level, filter_out, cutoff-1, encountered)
191 elif isinstance(x, list):
192 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
197 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
199 return "<%s (%d)>" % (self.__class__.__name__, id(self))
202 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
203 for key, value in attrs:
204 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
205 res += "%s>" % indent
208 class CompilerDirectivesNode(Node):
210 Sets compiler directives for the children nodes
212 # directives {string:value} A dictionary holding the right value for
213 # *all* possible directives.
215 child_attrs = ["body"]
217 def analyse_control_flow(self, env):
219 env.directives = self.directives
220 self.body.analyse_control_flow(env)
223 def analyse_declarations(self, env):
225 env.directives = self.directives
226 self.body.analyse_declarations(env)
229 def analyse_expressions(self, env):
231 env.directives = self.directives
232 self.body.analyse_expressions(env)
235 def generate_function_definitions(self, env, code):
236 env_old = env.directives
237 code_old = code.globalstate.directives
238 code.globalstate.directives = self.directives
239 self.body.generate_function_definitions(env, code)
240 env.directives = env_old
241 code.globalstate.directives = code_old
243 def generate_execution_code(self, code):
244 old = code.globalstate.directives
245 code.globalstate.directives = self.directives
246 self.body.generate_execution_code(code)
247 code.globalstate.directives = old
249 def annotate(self, code):
250 old = code.globalstate.directives
251 code.globalstate.directives = self.directives
252 self.body.annotate(code)
253 code.globalstate.directives = old
255 class BlockNode(object):
256 # Mixin class for nodes representing a declaration block.
258 def generate_const_definitions(self, env, code):
259 if env.const_entries:
260 for entry in env.const_entries:
261 if not entry.is_interned:
262 code.globalstate.add_const_definition(entry)
264 def generate_interned_string_decls(self, env, code):
265 entries = env.global_scope().new_interned_string_entries
267 for entry in entries:
268 code.globalstate.add_interned_string_decl(entry)
271 def generate_py_string_decls(self, env, code):
273 return # earlier error
274 entries = env.pystring_entries
276 for entry in entries:
277 if not entry.is_interned:
278 code.globalstate.add_py_string_decl(entry)
280 def generate_interned_num_decls(self, env, code):
281 # Flush accumulated interned nums from the global scope
282 # and generate declarations for them.
283 genv = env.global_scope()
284 entries = genv.interned_nums
286 for entry in entries:
287 code.globalstate.add_interned_num_decl(entry)
290 def generate_cached_builtins_decls(self, env, code):
291 entries = env.global_scope().undeclared_cached_builtins
292 for entry in entries:
293 code.globalstate.add_cached_builtin_decl(entry)
297 class StatListNode(Node):
298 # stats a list of StatNode
300 child_attrs = ["stats"]
302 def create_analysed(pos, env, *args, **kw):
303 node = StatListNode(pos, *args, **kw)
304 return node # No node-specific analysis necesarry
305 create_analysed = staticmethod(create_analysed)
307 def analyse_control_flow(self, env):
308 for stat in self.stats:
309 stat.analyse_control_flow(env)
311 def analyse_declarations(self, env):
312 #print "StatListNode.analyse_declarations" ###
313 for stat in self.stats:
314 stat.analyse_declarations(env)
316 def analyse_expressions(self, env):
317 #print "StatListNode.analyse_expressions" ###
318 for stat in self.stats:
319 stat.analyse_expressions(env)
321 def generate_function_definitions(self, env, code):
322 #print "StatListNode.generate_function_definitions" ###
323 for stat in self.stats:
324 stat.generate_function_definitions(env, code)
326 def generate_execution_code(self, code):
327 #print "StatListNode.generate_execution_code" ###
328 for stat in self.stats:
329 code.mark_pos(stat.pos)
330 stat.generate_execution_code(code)
332 def annotate(self, code):
333 for stat in self.stats:
337 class StatNode(Node):
339 # Code generation for statements is split into the following subphases:
341 # (1) generate_function_definitions
342 # Emit C code for the definitions of any structs,
343 # unions, enums and functions defined in the current
346 # (2) generate_execution_code
347 # Emit C code for executable statements.
350 def generate_function_definitions(self, env, code):
353 def generate_execution_code(self, code):
354 raise InternalError("generate_execution_code not implemented for %s" % \
355 self.__class__.__name__)
358 class CDefExternNode(StatNode):
359 # include_file string or None
362 child_attrs = ["body"]
364 def analyse_declarations(self, env):
365 if self.include_file:
366 env.add_include_file(self.include_file)
367 old_cinclude_flag = env.in_cinclude
369 self.body.analyse_declarations(env)
370 env.in_cinclude = old_cinclude_flag
372 def analyse_expressions(self, env):
375 def generate_execution_code(self, code):
378 def annotate(self, code):
379 self.body.annotate(code)
382 class CDeclaratorNode(Node):
383 # Part of a C declaration.
385 # Processing during analyse_declarations phase:
388 # Returns (name, type) pair where name is the
389 # CNameDeclaratorNode of the name being declared
390 # and type is the type it is being declared as.
392 # calling_convention string Calling convention of CFuncDeclaratorNode
393 # for which this is a base
397 calling_convention = ""
400 class CNameDeclaratorNode(CDeclaratorNode):
401 # name string The Pyrex name being declared
402 # cname string or None C name, if specified
403 # default ExprNode or None the value assigned on declaration
405 child_attrs = ['default']
409 def analyse(self, base_type, env, nonempty = 0):
410 if nonempty and self.name == '':
411 # May have mistaken the name for the type.
412 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
413 error(self.pos, "Missing argument name")
414 elif base_type.is_void:
415 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
417 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
418 base_type = py_object_type
419 self.type = base_type
420 return self, base_type
422 class CPtrDeclaratorNode(CDeclaratorNode):
423 # base CDeclaratorNode
425 child_attrs = ["base"]
427 def analyse(self, base_type, env, nonempty = 0):
428 if base_type.is_pyobject:
430 "Pointer base type cannot be a Python object")
431 ptr_type = PyrexTypes.c_ptr_type(base_type)
432 return self.base.analyse(ptr_type, env, nonempty = nonempty)
434 class CArrayDeclaratorNode(CDeclaratorNode):
435 # base CDeclaratorNode
438 child_attrs = ["base", "dimension"]
440 def analyse(self, base_type, env, nonempty = 0):
442 self.dimension.analyse_const_expression(env)
443 if not self.dimension.type.is_int:
444 error(self.dimension.pos, "Array dimension not integer")
445 size = self.dimension.result()
453 if not base_type.is_complete():
455 "Array element type '%s' is incomplete" % base_type)
456 if base_type.is_pyobject:
458 "Array element cannot be a Python object")
459 if base_type.is_cfunction:
461 "Array element cannot be a function")
462 array_type = PyrexTypes.c_array_type(base_type, size)
463 return self.base.analyse(array_type, env, nonempty = nonempty)
466 class CFuncDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
468 # args [CArgDeclNode]
469 # has_varargs boolean
470 # exception_value ConstNode
471 # exception_check boolean True if PyErr_Occurred check needed
472 # nogil boolean Can be called without gil
473 # with_gil boolean Acquire gil around function body
475 child_attrs = ["base", "args", "exception_value"]
478 optional_arg_count = 0
480 def analyse(self, return_type, env, nonempty = 0):
484 for arg_node in self.args:
485 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
486 name = name_declarator.name
487 if name_declarator.cname:
489 "Function argument cannot have C name specification")
490 # Turn *[] argument into **
492 type = PyrexTypes.c_ptr_type(type.base_type)
493 # Catch attempted C-style func(void) decl
495 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
496 # if type.is_pyobject and self.nogil:
498 # "Function with Python argument cannot be declared nogil")
499 func_type_args.append(
500 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
502 self.optional_arg_count += 1
503 elif self.optional_arg_count:
504 error(self.pos, "Non-default argument follows default argument")
506 if self.optional_arg_count:
507 scope = StructOrUnionScope()
508 scope.declare_var('%sn' % Naming.pyrex_prefix, PyrexTypes.c_int_type, self.pos)
509 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
510 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
511 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
512 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
517 cname = struct_cname)
518 self.op_args_struct.defined_in_pxd = 1
519 self.op_args_struct.used = 1
523 if return_type.is_pyobject \
524 and (self.exception_value or self.exception_check) \
525 and self.exception_check != '+':
527 "Exception clause not allowed for function returning Python object")
529 if self.exception_value:
530 self.exception_value.analyse_const_expression(env)
531 if self.exception_check == '+':
532 exc_val_type = self.exception_value.type
533 if not exc_val_type.is_error and \
534 not exc_val_type.is_pyobject and \
535 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
536 error(self.exception_value.pos,
537 "Exception value must be a Python exception or cdef function with no arguments.")
538 exc_val = self.exception_value
540 exc_val = self.exception_value.result()
541 if not return_type.assignable_from(self.exception_value.type):
542 error(self.exception_value.pos,
543 "Exception value incompatible with function return type")
544 exc_check = self.exception_check
545 if return_type.is_array:
547 "Function cannot return an array")
548 if return_type.is_cfunction:
550 "Function cannot return a function")
551 func_type = PyrexTypes.CFuncType(
552 return_type, func_type_args, self.has_varargs,
553 optional_arg_count = self.optional_arg_count,
554 exception_value = exc_val, exception_check = exc_check,
555 calling_convention = self.base.calling_convention,
556 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
557 if self.optional_arg_count:
558 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
559 return self.base.analyse(func_type, env)
562 class CArgDeclNode(Node):
563 # Item in a function declaration argument list.
565 # base_type CBaseTypeNode
566 # declarator CDeclaratorNode
567 # not_none boolean Tagged with 'not None'
568 # default ExprNode or None
569 # default_entry Symtab.Entry Entry for the variable holding the default value
570 # default_result_code string cname or code fragment for default value
571 # is_self_arg boolean Is the "self" arg of an extension type method
572 # is_kw_only boolean Is a keyword-only argument
574 child_attrs = ["base_type", "declarator", "default"]
579 name_declarator = None
581 def analyse(self, env, nonempty = 0):
582 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
583 if self.type is None:
584 # The parser may missinterpret names as types...
586 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
588 self.declarator.name = self.base_type.name
589 self.base_type.name = None
590 self.base_type.is_basic_c_type = False
593 could_be_name = False
594 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
595 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
596 self.declarator.name = self.base_type.arg_name
597 return self.declarator.analyse(base_type, env, nonempty = nonempty)
599 return self.name_declarator, self.type
601 def annotate(self, code):
603 self.default.annotate(code)
606 class CBaseTypeNode(Node):
607 # Abstract base class for C base type nodes.
609 # Processing during analyse_declarations phase:
616 class CAnalysedBaseTypeNode(Node):
621 def analyse(self, env, could_be_name = False):
624 class CSimpleBaseTypeNode(CBaseTypeNode):
626 # module_path [string] Qualifying name components
627 # is_basic_c_type boolean
630 # is_self_arg boolean Is self argument of C method
633 arg_name = None # in case the argument name was interpreted as a type
635 def analyse(self, env, could_be_name = False):
636 # Return type descriptor.
637 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
639 if self.is_basic_c_type:
640 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
642 error(self.pos, "Unrecognised type modifier combination")
643 elif self.name == "object" and not self.module_path:
644 type = py_object_type
645 elif self.name is None:
646 if self.is_self_arg and env.is_c_class_scope:
647 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
648 type = env.parent_type
650 type = py_object_type
653 scope = env.find_imported_module(self.module_path, self.pos)
657 if scope.is_c_class_scope:
658 scope = scope.global_scope()
659 entry = scope.lookup(self.name)
660 if entry and entry.is_type:
663 if self.is_self_arg and env.is_c_class_scope:
664 type = env.parent_type
666 type = py_object_type
667 self.arg_name = self.name
669 error(self.pos, "'%s' is not a type identifier" % self.name)
673 return PyrexTypes.error_type
675 class CBufferAccessTypeNode(CBaseTypeNode):
677 # positional_args [ExprNode] List of positional arguments
678 # keyword_args DictNode Keyword arguments
679 # base_type_node CBaseTypeNode
682 # type PyrexType.BufferType ...containing the right options
685 child_attrs = ["base_type_node", "positional_args",
686 "keyword_args", "dtype_node"]
690 def analyse(self, env, could_be_name = False):
691 base_type = self.base_type_node.analyse(env)
692 if base_type.is_error: return base_type
695 options = Buffer.analyse_buffer_options(
698 self.positional_args,
700 base_type.buffer_defaults)
702 self.type = PyrexTypes.BufferType(base_type, **options)
705 class CComplexBaseTypeNode(CBaseTypeNode):
706 # base_type CBaseTypeNode
707 # declarator CDeclaratorNode
709 child_attrs = ["base_type", "declarator"]
711 def analyse(self, env, could_be_name = False):
712 base = self.base_type.analyse(env, could_be_name)
713 _, type = self.declarator.analyse(base, env)
717 class CVarDefNode(StatNode):
718 # C variable definition or forward/extern function declaration.
720 # visibility 'private' or 'public' or 'extern'
721 # base_type CBaseTypeNode
722 # declarators [CDeclaratorNode]
725 # need_properties [entry]
726 # pxd_locals [CVarDefNode] (used for functions declared in pxd)
728 child_attrs = ["base_type", "declarators"]
732 def analyse_declarations(self, env, dest_scope = None):
735 self.dest_scope = dest_scope
736 base_type = self.base_type.analyse(env)
737 if (dest_scope.is_c_class_scope
738 and self.visibility == 'public'
739 and base_type.is_pyobject
740 and (base_type.is_builtin_type or base_type.is_extension_type)):
741 self.need_properties = []
743 visibility = 'private'
745 need_property = False
746 visibility = self.visibility
748 for declarator in self.declarators:
749 name_declarator, type = declarator.analyse(base_type, env)
750 if not type.is_complete():
751 if not (self.visibility == 'extern' and type.is_array):
752 error(declarator.pos,
753 "Variable type '%s' is incomplete" % type)
754 if self.visibility == 'extern' and type.is_pyobject:
755 error(declarator.pos,
756 "Python object cannot be declared extern")
757 name = name_declarator.name
758 cname = name_declarator.cname
760 error(declarator.pos, "Missing name in declaration.")
762 if type.is_cfunction:
763 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
764 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
766 if entry is not None:
767 entry.pxd_locals = self.pxd_locals
769 if self.in_pxd and self.visibility != 'extern':
771 "Only 'extern' C variable declaration allowed in .pxd file")
772 entry = dest_scope.declare_var(name, type, declarator.pos,
773 cname = cname, visibility = visibility, is_cdef = 1)
775 self.need_properties.append(entry)
776 entry.needs_property = 1
779 class CStructOrUnionDefNode(StatNode):
781 # cname string or None
782 # kind "struct" or "union"
783 # typedef_flag boolean
784 # visibility "public" or "private"
786 # attributes [CVarDefNode] or None
789 child_attrs = ["attributes"]
791 def analyse_declarations(self, env):
793 if self.attributes is not None:
794 scope = StructOrUnionScope(self.name)
795 self.entry = env.declare_struct_or_union(
796 self.name, self.kind, scope, self.typedef_flag, self.pos,
797 self.cname, visibility = self.visibility)
798 if self.attributes is not None:
799 if self.in_pxd and not env.in_cinclude:
800 self.entry.defined_in_pxd = 1
801 for attr in self.attributes:
802 attr.analyse_declarations(env, scope)
803 if self.visibility != 'extern':
804 need_typedef_indirection = False
805 for attr in scope.var_entries:
808 type = type.base_type
809 if type == self.entry.type:
810 error(attr.pos, "Struct cannot contain itself as a member.")
811 if self.typedef_flag:
813 type = type.base_type
814 if type == self.entry.type:
815 need_typedef_indirection = True
816 if need_typedef_indirection:
817 # C can't handle typedef structs that refer to themselves.
818 struct_entry = self.entry
819 cname = env.new_const_cname()
820 self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore')
821 struct_entry.type.typedef_flag = False
822 struct_entry.cname = struct_entry.type.cname = env.new_const_cname()
824 def analyse_expressions(self, env):
827 def generate_execution_code(self, code):
831 class CEnumDefNode(StatNode):
832 # name string or None
833 # cname string or None
834 # items [CEnumDefItemNode]
835 # typedef_flag boolean
836 # visibility "public" or "private"
840 child_attrs = ["items"]
842 def analyse_declarations(self, env):
843 self.entry = env.declare_enum(self.name, self.pos,
844 cname = self.cname, typedef_flag = self.typedef_flag,
845 visibility = self.visibility)
846 if self.items is not None:
847 if self.in_pxd and not env.in_cinclude:
848 self.entry.defined_in_pxd = 1
849 for item in self.items:
850 item.analyse_declarations(env, self.entry)
852 def analyse_expressions(self, env):
853 if self.visibility == 'public':
854 self.temp = env.allocate_temp_pyobject()
855 env.release_temp(self.temp)
857 def generate_execution_code(self, code):
858 if self.visibility == 'public':
859 for item in self.entry.enum_values:
860 code.putln("%s = PyInt_FromLong(%s); %s" % (
863 code.error_goto_if_null(self.temp, item.pos)))
864 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
868 code.error_goto(item.pos)))
869 code.putln("%s = 0;" % self.temp)
872 class CEnumDefItemNode(StatNode):
874 # cname string or None
875 # value ExprNode or None
877 child_attrs = ["value"]
879 def analyse_declarations(self, env, enum_entry):
881 self.value.analyse_const_expression(env)
882 if not self.value.type.is_int:
883 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
884 self.value.analyse_const_expression(env)
885 value = self.value.result()
888 entry = env.declare_const(self.name, enum_entry.type,
889 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
890 enum_entry.enum_values.append(entry)
893 class CTypeDefNode(StatNode):
894 # base_type CBaseTypeNode
895 # declarator CDeclaratorNode
896 # visibility "public" or "private"
899 child_attrs = ["base_type", "declarator"]
901 def analyse_declarations(self, env):
902 base = self.base_type.analyse(env)
903 name_declarator, type = self.declarator.analyse(base, env)
904 name = name_declarator.name
905 cname = name_declarator.cname
906 entry = env.declare_typedef(name, type, self.pos,
907 cname = cname, visibility = self.visibility)
908 if self.in_pxd and not env.in_cinclude:
909 entry.defined_in_pxd = 1
911 def analyse_expressions(self, env):
913 def generate_execution_code(self, code):
917 class FuncDefNode(StatNode, BlockNode):
918 # Base class for function definition nodes.
920 # return_type PyrexType
921 # #filename string C name of filename string const
923 # needs_closure boolean Whether or not this function has inner functions/classes/yield
924 # pxd_locals [CVarDefNode] locals defined in the pxd
928 needs_closure = False
931 def analyse_default_values(self, env):
932 genv = env.global_scope()
933 for arg in self.args:
936 if not hasattr(arg, 'default_entry'):
937 arg.default.analyse_types(env)
938 arg.default = arg.default.coerce_to(arg.type, genv)
939 if arg.default.is_literal:
940 arg.default_entry = arg.default
941 arg.default_result_code = arg.default.calculate_result_code()
942 if arg.default.type != arg.type and not arg.type.is_int:
943 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
945 arg.default.allocate_temps(genv)
946 arg.default_entry = genv.add_default_value(arg.type)
947 arg.default_entry.used = 1
948 arg.default_result_code = arg.default_entry.cname
951 "This argument cannot have a default value")
954 def need_gil_acquisition(self, lenv):
957 def create_local_scope(self, env):
959 while env.is_py_class_scope or env.is_c_class_scope:
960 env = env.outer_scope
961 if self.needs_closure:
962 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
964 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
965 lenv.return_type = self.return_type
966 type = self.entry.type
967 if type.is_cfunction:
968 lenv.nogil = type.nogil and not type.with_gil
969 self.local_scope = lenv
972 def generate_function_definitions(self, env, code):
975 lenv = self.local_scope
977 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
978 self.entry.scope.is_c_class_scope)
980 # Generate C code for header and body of function
981 code.enter_cfunc_scope()
982 code.return_from_error_cleanup_label = code.new_label()
984 # ----- Top-level constants used by this function
985 code.mark_pos(self.pos)
986 self.generate_interned_num_decls(lenv, code)
987 self.generate_interned_string_decls(lenv, code)
988 self.generate_py_string_decls(lenv, code)
989 self.generate_cached_builtins_decls(lenv, code)
991 #code.put_var_declarations(lenv.const_entries, static = 1)
992 self.generate_const_definitions(lenv, code)
993 # ----- Function header
996 self.py_func.generate_function_header(code,
997 with_pymethdef = env.is_py_class_scope,
999 self.generate_function_header(code,
1000 with_pymethdef = env.is_py_class_scope)
1001 # ----- Local variable declarations
1002 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1003 self.generate_argument_declarations(lenv, code)
1004 if self.needs_closure:
1005 code.putln("/* TODO: declare and create scope object */")
1006 code.put_var_declarations(lenv.var_entries)
1008 if not self.return_type.is_void:
1011 (self.return_type.declaration_code(
1012 Naming.retval_cname),
1014 tempvardecl_code = code.insertion_point()
1015 self.generate_keyword_list(code)
1016 # ----- Extern library function declarations
1017 lenv.generate_library_function_declarations(code)
1018 # ----- GIL acquisition
1019 acquire_gil = self.need_gil_acquisition(lenv)
1021 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1022 # ----- Automatic lead-ins for certain special functions
1023 if is_getbuffer_slot:
1024 self.getbuffer_init(code)
1025 # ----- Fetch arguments
1026 self.generate_argument_parsing_code(env, code)
1027 # If an argument is assigned to in the body, we must
1028 # incref it to properly keep track of refcounts.
1029 for entry in lenv.arg_entries:
1030 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1031 code.put_var_incref(entry)
1032 # ----- Initialise local variables
1033 for entry in lenv.var_entries:
1034 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1035 code.put_init_var_to_py_none(entry)
1036 # ----- Initialise local buffer auxiliary variables
1037 for entry in lenv.var_entries + lenv.arg_entries:
1038 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1039 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1040 # ----- Check and convert arguments
1041 self.generate_argument_type_tests(code)
1042 # ----- Acquire buffer arguments
1043 for entry in lenv.arg_entries:
1044 if entry.type.is_buffer:
1045 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1046 # ----- Function body
1047 self.body.generate_execution_code(code)
1048 # ----- Default return value
1050 if self.return_type.is_pyobject:
1051 #if self.return_type.is_extension_type:
1052 # lhs = "(PyObject *)%s" % Naming.retval_cname
1054 lhs = Naming.retval_cname
1055 code.put_init_to_py_none(lhs, self.return_type)
1057 val = self.return_type.default_value
1059 code.putln("%s = %s;" % (Naming.retval_cname, val))
1060 # ----- Error cleanup
1061 if code.error_label in code.labels_used:
1062 code.put_goto(code.return_label)
1063 code.put_label(code.error_label)
1064 # cleanup temps the old way
1065 code.put_var_xdecrefs(lenv.temp_entries)
1066 # cleanup temps the new way
1067 for cname, type in code.funcstate.all_managed_temps():
1068 code.put_xdecref(cname, type)
1070 # Clean up buffers -- this calls a Python function
1071 # so need to save and restore error state
1072 buffers_present = len(lenv.buffer_entries) > 0
1074 code.globalstate.use_utility_code(restore_exception_utility_code)
1075 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1076 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1077 for entry in lenv.buffer_entries:
1078 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1079 #code.putln("%s = 0;" % entry.cname)
1080 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1082 err_val = self.error_value()
1083 exc_check = self.caller_will_check_exceptions()
1084 if err_val is not None or exc_check:
1085 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1087 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1088 % self.entry.qualified_name, 0)
1090 '__Pyx_WriteUnraisable("%s");' %
1091 self.entry.qualified_name)
1092 env.use_utility_code(unraisable_exception_utility_code)
1093 env.use_utility_code(restore_exception_utility_code)
1094 default_retval = self.return_type.default_value
1095 if err_val is None and default_retval:
1096 err_val = default_retval
1097 if err_val is not None:
1100 Naming.retval_cname,
1103 if is_getbuffer_slot:
1104 self.getbuffer_error_cleanup(code)
1106 # If we are using the non-error cleanup section we should
1107 # jump past it if we have an error. The if-test below determine
1108 # whether this section is used.
1109 if buffers_present or is_getbuffer_slot:
1110 code.put_goto(code.return_from_error_cleanup_label)
1113 # ----- Non-error return cleanup
1114 # If you add anything here, remember to add a condition to the
1115 # if-test above in the error block (so that it can jump past this
1117 code.put_label(code.return_label)
1118 for entry in lenv.buffer_entries:
1120 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1121 if is_getbuffer_slot:
1122 self.getbuffer_normal_cleanup(code)
1123 # ----- Return cleanup for both error and no-error return
1124 code.put_label(code.return_from_error_cleanup_label)
1125 if not Options.init_local_none:
1126 for entry in lenv.var_entries:
1127 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1128 entry.xdecref_cleanup = 1
1129 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1130 # Decref any increfed args
1131 for entry in lenv.arg_entries:
1132 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1133 code.put_var_decref(entry)
1135 code.putln("PyGILState_Release(_save);")
1136 # code.putln("/* TODO: decref scope object */")
1138 if not self.return_type.is_void:
1139 code.putln("return %s;" % Naming.retval_cname)
1141 # ----- Go back and insert temp variable declarations
1142 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1143 tempvardecl_code.put_temp_declarations(code.funcstate)
1144 # ----- Python version
1145 code.exit_cfunc_scope()
1147 self.py_func.generate_function_definitions(env, code)
1148 self.generate_wrapper_functions(code)
1150 def declare_argument(self, env, arg):
1151 if arg.type.is_void:
1152 error(arg.pos, "Invalid use of 'void'")
1153 elif not arg.type.is_complete() and not arg.type.is_array:
1155 "Argument type '%s' is incomplete" % arg.type)
1156 return env.declare_arg(arg.name, arg.type, arg.pos)
1158 def generate_wrapper_functions(self, code):
1161 def generate_execution_code(self, code):
1162 # Evaluate and store argument default values
1163 for arg in self.args:
1164 default = arg.default
1166 if not default.is_literal:
1167 default.generate_evaluation_code(code)
1168 default.make_owned_reference(code)
1171 arg.default_entry.cname,
1172 default.result_as(arg.default_entry.type)))
1173 if default.is_temp and default.type.is_pyobject:
1177 # For Python class methods, create and store function object
1179 self.assmt.generate_execution_code(code)
1182 # Special code for the __getbuffer__ function
1184 def getbuffer_init(self, code):
1185 info = self.local_scope.arg_entries[1].cname
1186 # Python 3.0 betas have a bug in memoryview which makes it call
1187 # getbuffer with a NULL parameter. For now we work around this;
1188 # the following line should be removed when this bug is fixed.
1189 code.putln("if (%s == NULL) return 0;" % info)
1190 code.putln("%s->obj = Py_None; Py_INCREF(Py_None);" % info)
1192 def getbuffer_error_cleanup(self, code):
1193 info = self.local_scope.arg_entries[1].cname
1194 code.putln("Py_DECREF(%s->obj); %s->obj = NULL;" %
1197 def getbuffer_normal_cleanup(self, code):
1198 info = self.local_scope.arg_entries[1].cname
1199 code.putln("if (%s->obj == Py_None) { Py_DECREF(Py_None); %s->obj = NULL; }" %
1202 class CFuncDefNode(FuncDefNode):
1203 # C function definition.
1205 # modifiers ['inline']
1206 # visibility 'private' or 'public' or 'extern'
1207 # base_type CBaseTypeNode
1208 # declarator CDeclaratorNode
1212 # with_gil boolean Acquire GIL around body
1214 # py_func wrapper for calling from Python
1215 # overridable whether or not this is a cpdef function
1216 # inline_in_pxd whether this is an inline function in a pxd file
1218 child_attrs = ["base_type", "declarator", "body", "py_func"]
1220 inline_in_pxd = False
1222 def unqualified_name(self):
1223 return self.entry.name
1225 def analyse_declarations(self, env):
1226 if 'locals' in env.directives:
1227 directive_locals = env.directives['locals']
1229 directive_locals = {}
1230 self.directive_locals = directive_locals
1231 base_type = self.base_type.analyse(env)
1232 # The 2 here is because we need both function and argument names.
1233 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1234 if not type.is_cfunction:
1236 "Suite attached to non-function declaration")
1237 # Remember the actual type according to the function header
1238 # written here, because the type in the symbol table entry
1239 # may be different if we're overriding a C method inherited
1240 # from the base type of an extension type.
1242 type.is_overridable = self.overridable
1243 declarator = self.declarator
1244 while not hasattr(declarator, 'args'):
1245 declarator = declarator.base
1246 self.args = declarator.args
1247 for formal_arg, type_arg in zip(self.args, type.args):
1248 formal_arg.type = type_arg.type
1249 formal_arg.name = type_arg.name
1250 formal_arg.cname = type_arg.cname
1251 name = name_declarator.name
1252 cname = name_declarator.cname
1253 self.entry = env.declare_cfunction(
1254 name, type, self.pos,
1255 cname = cname, visibility = self.visibility,
1256 defining = self.body is not None,
1257 api = self.api, modifiers = self.modifiers)
1258 self.entry.inline_func_in_pxd = self.inline_in_pxd
1259 self.return_type = type.return_type
1261 if self.overridable:
1263 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1264 self.py_func = DefNode(pos = self.pos,
1265 name = self.entry.name,
1268 starstar_arg = None,
1270 body = py_func_body,
1272 self.py_func.is_module_scope = env.is_module_scope
1273 self.py_func.analyse_declarations(env)
1274 self.entry.as_variable = self.py_func.entry
1275 # Reset scope entry the above cfunction
1276 env.entries[name] = self.entry
1277 self.py_func.interned_attr_cname = env.intern_identifier(
1278 self.py_func.entry.name)
1279 if not env.is_module_scope or Options.lookup_module_cpdef:
1280 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1281 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1283 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1285 args = self.type.args
1286 if omit_optional_args:
1287 args = args[:len(args) - self.type.optional_arg_count]
1288 arg_names = [arg.name for arg in args]
1290 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1292 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1293 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1294 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1295 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)
1296 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1298 def declare_arguments(self, env):
1299 for arg in self.type.args:
1301 error(arg.pos, "Missing argument name")
1302 self.declare_argument(env, arg)
1304 def need_gil_acquisition(self, lenv):
1306 with_gil = self.type.with_gil
1307 if type.nogil and not with_gil:
1308 if type.return_type.is_pyobject:
1310 "Function with Python return type cannot be declared nogil")
1311 for entry in lenv.var_entries + lenv.temp_entries:
1312 if entry.type.is_pyobject:
1313 error(self.pos, "Function declared nogil has Python locals or temporaries")
1316 def analyse_expressions(self, env):
1317 self.analyse_default_values(env)
1318 if self.overridable:
1319 self.py_func.analyse_expressions(env)
1321 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1324 visibility = self.entry.visibility
1325 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1326 arg_decls.append(arg.declaration_code())
1327 if with_dispatch and self.overridable:
1328 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1329 if type.optional_arg_count and with_opt_args:
1330 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1331 if type.has_varargs:
1332 arg_decls.append("...")
1334 arg_decls = ["void"]
1336 cname = self.entry.func_cname
1337 entity = type.function_header_code(cname, string.join(arg_decls, ", "))
1338 if visibility == 'public':
1339 dll_linkage = "DL_EXPORT"
1342 header = self.return_type.declaration_code(entity,
1343 dll_linkage = dll_linkage)
1344 if visibility == 'extern':
1345 storage_class = "%s " % Naming.extern_c_macro
1346 elif visibility == 'public':
1349 storage_class = "static "
1350 code.putln("%s%s %s {" % (
1352 ' '.join(self.modifiers).upper(), # macro forms
1355 def generate_argument_declarations(self, env, code):
1356 for arg in self.args:
1358 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1360 def generate_keyword_list(self, code):
1363 def generate_argument_parsing_code(self, env, code):
1365 if self.type.optional_arg_count:
1366 code.putln('if (%s) {' % Naming.optional_args_cname)
1367 for arg in self.args:
1369 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1370 declarator = arg.declarator
1371 while not hasattr(declarator, 'name'):
1372 declarator = declarator.base
1373 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1375 for _ in range(self.type.optional_arg_count):
1379 def generate_argument_conversion_code(self, code):
1382 def generate_argument_type_tests(self, code):
1383 # Generate type tests for args whose type in a parent
1384 # class is a supertype of the declared type.
1385 for arg in self.type.args:
1386 if arg.needs_type_test:
1387 self.generate_arg_type_test(arg, code)
1389 def generate_arg_type_test(self, arg, code):
1390 # Generate type test for one argument.
1391 if arg.type.typeobj_is_available():
1392 typeptr_cname = arg.type.typeptr_cname
1393 arg_code = "((PyObject *)%s)" % arg.cname
1395 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1400 type.is_builtin_type,
1401 code.error_goto(arg.pos)))
1403 error(arg.pos, "Cannot test type of extern C class "
1404 "without type object name specification")
1406 def error_value(self):
1407 if self.return_type.is_pyobject:
1411 return self.entry.type.exception_value
1413 def caller_will_check_exceptions(self):
1414 return self.entry.type.exception_check
1416 def generate_wrapper_functions(self, code):
1417 # If the C signature of a function has changed, we need to generate
1418 # wrappers to put in the slots here.
1421 func_type = entry.type
1422 while entry.prev_entry is not None:
1424 entry = entry.prev_entry
1425 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1427 self.generate_function_header(code,
1429 with_dispatch = entry.type.is_overridable,
1430 with_opt_args = entry.type.optional_arg_count,
1431 cname = entry.func_cname)
1432 if not self.return_type.is_void:
1434 args = self.type.args
1435 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1436 if entry.type.is_overridable:
1437 arglist.append(Naming.skip_dispatch_cname)
1438 elif func_type.is_overridable:
1440 if entry.type.optional_arg_count:
1441 arglist.append(Naming.optional_args_cname)
1442 elif func_type.optional_arg_count:
1443 arglist.append('NULL')
1444 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1448 class PyArgDeclNode(Node):
1449 # Argument which must be a Python object (used
1450 # for * and ** arguments).
1453 # entry Symtab.Entry
1457 class DecoratorNode(Node):
1460 # decorator NameNode or CallNode
1461 child_attrs = ['decorator']
1464 class DefNode(FuncDefNode):
1465 # A Python function definition.
1467 # name string the Python name of the function
1468 # decorators [DecoratorNode] list of decorators
1469 # args [CArgDeclNode] formal arguments
1470 # star_arg PyArgDeclNode or None * argument
1471 # starstar_arg PyArgDeclNode or None ** argument
1472 # doc EncodedString or None
1475 # The following subnode is constructed internally
1476 # when the def statement is inside a Python class definition.
1478 # assmt AssignmentNode Function construction/assignment
1480 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1484 num_required_kw_args = 0
1485 reqd_kw_flags_cname = "0"
1491 def __init__(self, pos, **kwds):
1492 FuncDefNode.__init__(self, pos, **kwds)
1494 for arg in self.args:
1501 self.num_kwonly_args = k
1502 self.num_required_kw_args = rk
1503 self.num_required_args = r
1505 def as_cfunction(self, cfunc=None, scope=None):
1507 error(self.star_arg.pos, "cdef function cannot have star argument")
1508 if self.starstar_arg:
1509 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1512 for formal_arg in self.args:
1513 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1514 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1516 type = py_object_type,
1517 pos = formal_arg.pos))
1518 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1520 has_varargs = False,
1521 exception_value = None,
1522 exception_check = False,
1525 is_overridable = True)
1526 cfunc = CVarDefNode(self.pos, type=cfunc_type, pxd_locals=[])
1528 cfunc_type = cfunc.type
1529 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1530 error(self.pos, "wrong number of arguments")
1531 error(declarator.pos, "previous declaration here")
1532 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1533 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1534 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1535 formal_arg.type = type_arg.type
1536 formal_arg.name_declarator = name_declarator
1538 if cfunc_type.exception_value is None:
1539 exception_value = None
1541 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1542 declarator = CFuncDeclaratorNode(self.pos,
1543 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1545 has_varargs = False,
1546 exception_check = cfunc_type.exception_check,
1547 exception_value = exception_value,
1548 with_gil = cfunc_type.with_gil,
1549 nogil = cfunc_type.nogil)
1550 return CFuncDefNode(self.pos,
1552 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1553 declarator = declarator,
1556 overridable = cfunc_type.is_overridable,
1558 with_gil = cfunc_type.with_gil,
1559 nogil = cfunc_type.nogil,
1560 visibility = 'private',
1562 pxd_locals = cfunc.pxd_locals)
1564 def analyse_declarations(self, env):
1565 if 'locals' in env.directives:
1566 directive_locals = env.directives['locals']
1568 directive_locals = {}
1569 self.directive_locals = directive_locals
1570 for arg in self.args:
1571 if hasattr(arg, 'name'):
1573 name_declarator = None
1575 base_type = arg.base_type.analyse(env)
1576 name_declarator, type = \
1577 arg.declarator.analyse(base_type, env)
1578 arg.name = name_declarator.name
1579 if arg.name in directive_locals:
1580 type_node = directive_locals[arg.name]
1581 other_type = type_node.analyse_as_type(env)
1582 if other_type is None:
1583 error(type_node.pos, "Not a type")
1584 elif (type is not PyrexTypes.py_object_type
1585 and not type.same_as(other_type)):
1586 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1587 error(type_node.pos, "Previous declaration here")
1590 if name_declarator and name_declarator.cname:
1592 "Python function argument cannot have C name specification")
1593 arg.type = type.as_argument_type()
1595 arg.needs_conversion = 0
1596 arg.needs_type_test = 0
1598 if arg.not_none and not arg.type.is_extension_type:
1600 "Only extension type arguments can have 'not None'")
1601 self.declare_pyfunction(env)
1602 self.analyse_signature(env)
1603 self.return_type = self.entry.signature.return_type()
1605 def analyse_signature(self, env):
1606 any_type_tests_needed = 0
1607 # Use the simpler calling signature for zero- and one-argument functions.
1608 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1609 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1610 if len(self.args) == 0:
1611 self.entry.signature = TypeSlots.pyfunction_noargs
1612 elif len(self.args) == 1:
1613 if self.args[0].default is None and not self.args[0].kw_only:
1614 self.entry.signature = TypeSlots.pyfunction_onearg
1615 elif self.entry.signature is TypeSlots.pymethod_signature:
1616 if len(self.args) == 1:
1617 self.entry.signature = TypeSlots.unaryfunc
1618 elif len(self.args) == 2:
1619 if self.args[1].default is None and not self.args[1].kw_only:
1620 self.entry.signature = TypeSlots.ibinaryfunc
1621 elif self.entry.is_special:
1622 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1623 sig = self.entry.signature
1624 nfixed = sig.num_fixed_args()
1625 for i in range(nfixed):
1626 if i < len(self.args):
1629 if sig.is_self_arg(i):
1631 arg.hdr_type = arg.type = env.parent_type
1632 arg.needs_conversion = 0
1634 arg.hdr_type = sig.fixed_arg_type(i)
1635 if not arg.type.same_as(arg.hdr_type):
1636 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1637 arg.needs_type_test = 1
1638 any_type_tests_needed = 1
1640 arg.needs_conversion = 1
1641 if arg.needs_conversion:
1642 arg.hdr_cname = Naming.arg_prefix + arg.name
1644 arg.hdr_cname = Naming.var_prefix + arg.name
1646 self.bad_signature()
1648 if nfixed < len(self.args):
1649 if not sig.has_generic_args:
1650 self.bad_signature()
1651 for arg in self.args:
1652 if arg.is_generic and \
1653 (arg.type.is_extension_type or arg.type.is_builtin_type):
1654 arg.needs_type_test = 1
1655 any_type_tests_needed = 1
1656 elif arg.type is PyrexTypes.c_py_ssize_t_type:
1657 # Want to use __index__ rather than __int__ method
1658 # that PyArg_ParseTupleAndKeywords calls
1659 arg.needs_conversion = 1
1660 arg.hdr_type = PyrexTypes.py_object_type
1661 arg.hdr_cname = Naming.arg_prefix + arg.name
1662 if any_type_tests_needed:
1663 env.use_utility_code(arg_type_test_utility_code)
1665 def bad_signature(self):
1666 sig = self.entry.signature
1667 expected_str = "%d" % sig.num_fixed_args()
1668 if sig.has_generic_args:
1669 expected_str = expected_str + " or more"
1671 if name.startswith("__") and name.endswith("__"):
1672 desc = "Special method"
1676 "%s %s has wrong number of arguments "
1677 "(%d declared, %s expected)" % (
1678 desc, self.name, len(self.args), expected_str))
1680 def signature_has_nongeneric_args(self):
1681 argcount = len(self.args)
1682 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1686 def signature_has_generic_args(self):
1687 return self.entry.signature.has_generic_args
1689 def declare_pyfunction(self, env):
1690 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1692 entry = env.lookup_here(self.name)
1693 if entry and entry.type.is_cfunction and not self.is_wrapper:
1694 warning(self.pos, "Overriding cdef method with def method.", 5)
1695 entry = env.declare_pyfunction(self.name, self.pos)
1697 prefix = env.scope_prefix
1698 entry.func_cname = \
1699 Naming.pyfunc_prefix + prefix + name
1700 entry.pymethdef_cname = \
1701 Naming.pymethdef_prefix + prefix + name
1702 if Options.docstrings:
1703 entry.doc = embed_position(self.pos, self.doc)
1705 Naming.funcdoc_prefix + prefix + name
1709 def declare_arguments(self, env):
1710 for arg in self.args:
1712 error(arg.pos, "Missing argument name")
1713 if arg.needs_conversion:
1714 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1715 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1716 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1717 if arg.type.is_pyobject:
1718 arg.entry.init = "0"
1719 arg.entry.init_to_none = 0
1721 arg.entry = self.declare_argument(env, arg)
1723 arg.entry.is_self_arg = arg.is_self_arg
1724 if not arg.is_self_arg:
1725 arg.name_entry = env.get_string_const(
1726 arg.name, identifier = True)
1727 env.add_py_string(arg.name_entry, identifier = True)
1729 if arg.is_self_arg or \
1730 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1731 arg.entry.is_declared_generic = 1
1732 self.declare_python_arg(env, self.star_arg)
1733 self.declare_python_arg(env, self.starstar_arg)
1735 def declare_python_arg(self, env, arg):
1737 entry = env.declare_var(arg.name,
1738 PyrexTypes.py_object_type, arg.pos)
1741 entry.init_to_none = 0
1742 entry.xdecref_cleanup = 1
1744 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1746 def analyse_expressions(self, env):
1747 self.analyse_default_values(env)
1748 if env.is_py_class_scope:
1749 self.synthesize_assignment_node(env)
1751 def synthesize_assignment_node(self, env):
1753 self.assmt = SingleAssignmentNode(self.pos,
1754 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1755 rhs = ExprNodes.UnboundMethodNode(self.pos,
1756 class_cname = env.class_obj_cname,
1757 function = ExprNodes.PyCFunctionNode(self.pos,
1758 pymethdef_cname = self.entry.pymethdef_cname)))
1759 self.assmt.analyse_declarations(env)
1760 self.assmt.analyse_expressions(env)
1762 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1764 sig = self.entry.signature
1765 if sig.has_dummy_arg:
1766 arg_code_list.append(
1767 "PyObject *%s" % Naming.self_cname)
1768 for arg in self.args:
1769 if not arg.is_generic:
1771 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1773 arg_code_list.append(
1774 arg.hdr_type.declaration_code(arg.hdr_cname))
1775 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1776 arg_code_list.append("PyObject *unused")
1777 if sig.has_generic_args:
1778 arg_code_list.append(
1779 "PyObject *%s, PyObject *%s"
1780 % (Naming.args_cname, Naming.kwds_cname))
1781 arg_code = ", ".join(arg_code_list)
1782 dc = self.return_type.declaration_code(self.entry.func_cname)
1783 header = "static %s(%s)" % (dc, arg_code)
1784 code.putln("%s; /*proto*/" % header)
1787 if self.entry.doc and Options.docstrings:
1788 docstr = self.entry.doc
1789 if not isinstance(docstr, str):
1790 docstr = docstr.utf8encode()
1792 'static char %s[] = "%s";' % (
1793 self.entry.doc_cname,
1794 split_docstring(escape_byte_string(docstr))))
1797 "static PyMethodDef %s = " %
1798 self.entry.pymethdef_cname)
1799 code.put_pymethoddef(self.entry, ";")
1800 code.putln("%s {" % header)
1802 def generate_argument_declarations(self, env, code):
1803 for arg in self.args:
1804 if arg.is_generic: # or arg.needs_conversion:
1805 if arg.needs_conversion:
1806 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1808 code.put_var_declaration(arg.entry)
1810 def generate_keyword_list(self, code):
1811 if self.signature_has_generic_args() and \
1812 self.signature_has_nongeneric_args():
1814 "static PyObject **%s[] = {" %
1815 Naming.pykwdlist_cname)
1816 for arg in self.args:
1818 code.put('&%s,' % arg.name_entry.pystring_cname)
1821 def generate_argument_parsing_code(self, env, code):
1822 # Generate PyArg_ParseTuple call for generic
1823 # arguments, if any.
1824 if self.entry.signature.has_dummy_arg:
1825 # get rid of unused argument warning
1826 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1828 old_error_label = code.new_error_label()
1829 our_error_label = code.error_label
1830 end_label = code.new_label("argument_unpacking_done")
1832 has_kwonly_args = self.num_kwonly_args > 0
1833 has_star_or_kw_args = self.star_arg is not None \
1834 or self.starstar_arg is not None or has_kwonly_args
1836 if not self.signature_has_generic_args():
1837 if has_star_or_kw_args:
1838 error(self.pos, "This method cannot have * or keyword arguments")
1839 self.generate_argument_conversion_code(code)
1841 elif not self.signature_has_nongeneric_args():
1842 # func(*args) or func(**kw) or func(*args, **kw)
1843 self.generate_stararg_copy_code(code)
1846 positional_args = []
1849 for arg in self.args:
1850 arg_entry = arg.entry
1856 arg.default_result_code))
1858 if not arg.is_self_arg:
1860 kw_only_args.append(arg)
1862 positional_args.append(arg)
1864 kw_only_args.append(arg)
1867 error(arg.pos, "Non-default argument following default argument")
1868 elif not arg.is_self_arg:
1869 positional_args.append(arg)
1870 if arg.needs_conversion:
1871 format = arg.hdr_type.parsetuple_format
1873 format = arg_entry.type.parsetuple_format
1876 "Cannot convert Python object argument to type '%s' (when parsing input arguments)"
1879 self.generate_tuple_and_keyword_parsing_code(
1880 positional_args, kw_only_args, end_label, code)
1882 code.error_label = old_error_label
1883 if code.label_used(our_error_label):
1884 if not code.label_used(end_label):
1885 code.put_goto(end_label)
1886 code.put_label(our_error_label)
1887 if has_star_or_kw_args:
1888 self.generate_arg_decref(self.star_arg, code)
1889 if self.starstar_arg:
1890 if self.starstar_arg.entry.xdecref_cleanup:
1891 code.put_var_xdecref(self.starstar_arg.entry)
1893 code.put_var_decref(self.starstar_arg.entry)
1894 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1895 code.putln("return %s;" % self.error_value())
1896 if code.label_used(end_label):
1897 code.put_label(end_label)
1899 def generate_arg_assignment(self, arg, item, code):
1900 if arg.type.is_pyobject:
1902 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1903 code.putln("%s = %s;" % (arg.entry.cname, item))
1905 func = arg.type.from_py_function
1907 code.putln("%s = %s(%s); %s" % (
1911 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1913 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1915 def generate_arg_xdecref(self, arg, code):
1917 code.put_var_xdecref(arg.entry)
1919 def generate_arg_decref(self, arg, code):
1921 code.put_var_decref(arg.entry)
1923 def generate_stararg_copy_code(self, code):
1924 if not self.star_arg:
1925 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1926 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1928 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1929 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1932 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1934 if self.starstar_arg:
1936 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1938 kwarg_check = "%s" % Naming.kwds_cname
1940 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1941 Naming.kwds_cname, Naming.kwds_cname)
1943 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1944 kwarg_check, Naming.kwds_cname, self.name,
1945 bool(self.starstar_arg), self.error_value()))
1947 if self.starstar_arg:
1948 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1949 self.starstar_arg.entry.cname,
1952 code.putln("if (unlikely(!%s)) return %s;" % (
1953 self.starstar_arg.entry.cname, self.error_value()))
1954 self.starstar_arg.entry.xdecref_cleanup = 0
1957 code.put_incref(Naming.args_cname, py_object_type)
1958 code.putln("%s = %s;" % (
1959 self.star_arg.entry.cname,
1961 self.star_arg.entry.xdecref_cleanup = 0
1963 def generate_tuple_and_keyword_parsing_code(self, positional_args,
1964 kw_only_args, success_label, code):
1965 argtuple_error_label = code.new_label("argtuple_error")
1967 min_positional_args = self.num_required_args - self.num_required_kw_args
1968 if len(self.args) > 0 and self.args[0].is_self_arg:
1969 min_positional_args -= 1
1970 max_positional_args = len(positional_args)
1971 has_fixed_positional_count = not self.star_arg and \
1972 min_positional_args == max_positional_args
1974 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
1975 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1976 if self.num_required_kw_args:
1977 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
1979 if self.starstar_arg or self.star_arg:
1980 self.generate_stararg_init_code(max_positional_args, code)
1982 # --- optimised code when we receive keyword arguments
1983 if self.num_required_kw_args:
1984 likely_hint = "likely"
1986 likely_hint = "unlikely"
1987 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
1988 self.generate_keyword_unpacking_code(
1989 min_positional_args, max_positional_args,
1990 has_fixed_positional_count,
1991 positional_args, kw_only_args, argtuple_error_label, code)
1993 # --- optimised code when we do not receive any keyword arguments
1994 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
1995 # Python raises arg tuple related errors first, so we must
1996 # check the length here
1997 if min_positional_args == max_positional_args and not self.star_arg:
2001 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2002 Naming.args_cname, compare, min_positional_args))
2003 code.put_goto(argtuple_error_label)
2005 if self.num_required_kw_args:
2006 # pure error case: keywords required but not passed
2007 if max_positional_args > min_positional_args and not self.star_arg:
2008 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2009 Naming.args_cname, max_positional_args))
2010 code.put_goto(argtuple_error_label)
2011 code.putln('} else {')
2012 for i, arg in enumerate(kw_only_args):
2014 # required keyword-only argument missing
2015 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2016 self.name.utf8encode(),
2017 arg.name_entry.pystring_cname))
2018 code.putln(code.error_goto(self.pos))
2021 elif min_positional_args == max_positional_args:
2022 # parse the exact number of positional arguments from the
2024 if max_positional_args > 0:
2025 code.putln('} else {')
2026 for i, arg in enumerate(positional_args):
2027 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2028 self.generate_arg_assignment(arg, item, code)
2031 # parse the positional arguments from the variable length
2033 code.putln('} else {')
2034 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2036 code.putln('default:')
2037 reversed_args = list(enumerate(positional_args))[::-1]
2038 for i, arg in reversed_args:
2039 if i >= min_positional_args-1:
2040 if min_positional_args > 1:
2041 code.putln('case %2d:' % (i+1)) # pure code beautification
2043 code.put('case %2d: ' % (i+1))
2044 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2045 self.generate_arg_assignment(arg, item, code)
2046 if min_positional_args == 0:
2047 code.put('case 0: ')
2048 code.putln('break;')
2050 if min_positional_args:
2051 for i in range(min_positional_args-1, -1, -1):
2052 code.putln('case %2d:' % i)
2053 code.put_goto(argtuple_error_label)
2055 code.put('default: ')
2056 code.put_goto(argtuple_error_label)
2061 if code.label_used(argtuple_error_label):
2062 code.put_goto(success_label)
2063 code.put_label(argtuple_error_label)
2064 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2065 self.name.utf8encode(), has_fixed_positional_count,
2066 min_positional_args, max_positional_args,
2068 code.putln(code.error_goto(self.pos))
2070 def generate_stararg_init_code(self, max_positional_args, code):
2071 if self.starstar_arg:
2072 self.starstar_arg.entry.xdecref_cleanup = 0
2073 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2074 self.starstar_arg.entry.cname,
2075 self.starstar_arg.entry.cname,
2076 self.error_value()))
2078 self.star_arg.entry.xdecref_cleanup = 0
2079 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2081 max_positional_args))
2082 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2083 self.star_arg.entry.cname, Naming.args_cname,
2084 max_positional_args, Naming.args_cname))
2085 if self.starstar_arg:
2087 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2088 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2089 code.putln('return %s;' % self.error_value())
2092 code.putln("if (unlikely(!%s)) return %s;" % (
2093 self.star_arg.entry.cname, self.error_value()))
2094 code.putln('} else {')
2095 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2096 code.put_incref(Naming.empty_tuple, py_object_type)
2099 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2100 has_fixed_positional_count, positional_args,
2101 kw_only_args, argtuple_error_label, code):
2102 all_args = tuple(positional_args) + tuple(kw_only_args)
2103 max_args = len(all_args)
2106 for arg in all_args:
2107 if arg.default and arg.type.is_pyobject:
2108 default_value = arg.default_result_code
2109 if arg.type is not PyrexTypes.py_object_type:
2110 default_value = "(PyObject*)"+default_value
2111 default_args.append(default_value)
2113 default_args.append('0')
2114 code.putln("PyObject* values[%d] = {%s};" % (
2115 max_args, ', '.join(default_args)))
2116 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2119 # parse the tuple and check that it's not too long
2120 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2122 code.putln('default:')
2123 for i in range(max_positional_args-1, -1, -1):
2124 code.put('case %2d: ' % (i+1))
2125 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2126 i, Naming.args_cname, i))
2127 code.putln('case 0: break;')
2128 if not self.star_arg:
2129 code.put('default: ') # more arguments than allowed
2130 code.put_goto(argtuple_error_label)
2133 # now fill up the required arguments with values from the kw dict
2134 if self.num_required_args:
2135 last_required_arg = -1
2136 for i, arg in enumerate(all_args):
2138 last_required_arg = i
2139 if max_positional_args > 0:
2140 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2141 for i, arg in enumerate(all_args[:last_required_arg+1]):
2142 if max_positional_args > 0 and i <= max_positional_args:
2143 if self.star_arg and i == max_positional_args:
2144 code.putln('default:')
2146 code.putln('case %2d:' % i)
2148 # handled in ParseOptionalKeywords() below
2150 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2151 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2152 code.putln('if (likely(values[%d])) kw_args--;' % i);
2153 if i < min_positional_args:
2155 # special case: we know arg 0 is missing
2157 code.put_goto(argtuple_error_label)
2159 # print the correct number of values (args or
2160 # kwargs) that were passed into positional
2161 # arguments up to this point
2162 code.putln('else {')
2163 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2164 self.name.utf8encode(), has_fixed_positional_count,
2165 min_positional_args, max_positional_args, i))
2166 code.putln(code.error_goto(self.pos))
2169 code.putln('else {')
2170 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2171 self.name.utf8encode(), arg.name_entry.pystring_cname))
2172 code.putln(code.error_goto(self.pos))
2174 if max_positional_args > 0:
2177 code.putln('if (unlikely(kw_args > 0)) {')
2178 # non-positional/-required kw args left in dict: default args, **kwargs or error
2179 if max_positional_args == 0:
2182 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2183 Naming.args_cname, max_positional_args,
2184 Naming.args_cname, max_positional_args))
2185 pos_arg_count = "used_pos_args"
2187 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2188 code.globalstate.use_utility_code(parse_keywords_utility_code)
2190 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2192 Naming.pykwdlist_cname,
2193 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2195 self.name.utf8encode()))
2196 code.putln(code.error_goto(self.pos))
2199 # convert arg values to their final type and assign them
2200 for i, arg in enumerate(all_args):
2201 if arg.default and not arg.type.is_pyobject:
2202 code.putln("if (values[%d]) {" % i)
2203 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2204 if arg.default and not arg.type.is_pyobject:
2207 def generate_argument_conversion_code(self, code):
2208 # Generate code to convert arguments from
2209 # signature type to declared type, if needed.
2210 for arg in self.args:
2211 if arg.needs_conversion:
2212 self.generate_arg_conversion(arg, code)
2214 def generate_arg_conversion(self, arg, code):
2215 # Generate conversion code for one argument.
2216 old_type = arg.hdr_type
2218 if old_type.is_pyobject:
2220 code.putln("if (%s) {" % arg.hdr_cname)
2222 code.putln("assert(%s); {" % arg.hdr_cname)
2223 self.generate_arg_conversion_from_pyobject(arg, code)
2225 elif new_type.is_pyobject:
2226 self.generate_arg_conversion_to_pyobject(arg, code)
2228 if new_type.assignable_from(old_type):
2230 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2233 "Cannot convert 1 argument from '%s' to '%s'" %
2234 (old_type, new_type))
2236 def generate_arg_conversion_from_pyobject(self, arg, code):
2238 func = new_type.from_py_function
2239 # copied from CoerceFromPyTypeNode
2241 code.putln("%s = %s(%s); %s" % (
2245 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2248 "Cannot convert Python object argument to type '%s'"
2251 def generate_arg_conversion_to_pyobject(self, arg, code):
2252 old_type = arg.hdr_type
2253 func = old_type.to_py_function
2255 code.putln("%s = %s(%s); %s" % (
2259 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2262 "Cannot convert argument of type '%s' to Python object"
2265 def generate_argument_type_tests(self, code):
2266 # Generate type tests for args whose signature
2267 # type is PyObject * and whose declared type is
2268 # a subtype thereof.
2269 for arg in self.args:
2270 if arg.needs_type_test:
2271 self.generate_arg_type_test(arg, code)
2273 def generate_arg_type_test(self, arg, code):
2274 # Generate type test for one argument.
2275 if arg.type.typeobj_is_available():
2276 typeptr_cname = arg.type.typeptr_cname
2277 arg_code = "((PyObject *)%s)" % arg.entry.cname
2279 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2284 arg.type.is_builtin_type,
2285 code.error_goto(arg.pos)))
2287 error(arg.pos, "Cannot test type of extern C class "
2288 "without type object name specification")
2290 def error_value(self):
2291 return self.entry.signature.error_value
2293 def caller_will_check_exceptions(self):
2296 class OverrideCheckNode(StatNode):
2297 # A Node for dispatching to the def method if it
2306 child_attrs = ['body']
2310 def analyse_expressions(self, env):
2311 self.args = env.arg_entries
2312 if self.py_func.is_module_scope:
2317 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2318 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2319 call_node = ExprNodes.SimpleCallNode(self.pos,
2320 function=self.func_node,
2321 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2322 self.body = ReturnStatNode(self.pos, value=call_node)
2323 self.body.analyse_expressions(env)
2325 def generate_execution_code(self, code):
2326 # Check to see if we are an extension type
2327 if self.py_func.is_module_scope:
2328 self_arg = "((PyObject *)%s)" % Naming.module_cname
2330 self_arg = "((PyObject *)%s)" % self.args[0].cname
2331 code.putln("/* Check if called by wrapper */")
2332 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2333 code.putln("/* Check if overriden in Python */")
2334 if self.py_func.is_module_scope:
2335 code.putln("else {")
2337 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2338 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2339 # need to get attribute manually--scope would return cdef method
2340 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2341 # It appears that this type is not anywhere exposed in the Python/C API
2342 is_builtin_function_or_method = '(strcmp(Py_TYPE(%s)->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result()
2343 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2344 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2345 self.body.generate_execution_code(code)
2347 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2350 class ClassDefNode(StatNode, BlockNode):
2353 class PyClassDefNode(ClassDefNode):
2354 # A Python class definition.
2356 # name EncodedString Name of the class
2357 # doc string or None
2358 # body StatNode Attribute definition code
2359 # entry Symtab.Entry
2360 # scope PyClassScope
2362 # The following subnodes are constructed internally:
2364 # dict DictNode Class dictionary
2365 # classobj ClassNode Class object
2366 # target NameNode Variable to assign class object to
2368 child_attrs = ["body", "dict", "classobj", "target"]
2370 def __init__(self, pos, name, bases, doc, body):
2371 StatNode.__init__(self, pos)
2376 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2377 if self.doc and Options.docstrings:
2378 doc = embed_position(self.pos, self.doc)
2379 doc_node = ExprNodes.StringNode(pos, value = doc)
2382 self.classobj = ExprNodes.ClassNode(pos, name = name,
2383 bases = bases, dict = self.dict, doc = doc_node)
2384 self.target = ExprNodes.NameNode(pos, name = name)
2386 def as_cclass(self):
2388 Return this node as if it were declared as an extension class
2390 bases = self.classobj.bases.args
2392 base_class_name = None
2393 base_class_module = None
2394 elif len(bases) == 1:
2397 from ExprNodes import AttributeNode, NameNode
2398 while isinstance(base, AttributeNode):
2399 path.insert(0, base.attribute)
2401 if isinstance(base, NameNode):
2402 path.insert(0, base.name)
2403 base_class_name = path[-1]
2405 base_class_module = u'.'.join(path[:-1])
2407 base_class_module = None
2409 error(self.classobj.bases.args.pos, "Invalid base class")
2411 error(self.classobj.bases.args.pos, "C class may only have one base class")
2414 return CClassDefNode(self.pos,
2415 visibility = 'private',
2417 class_name = self.name,
2418 base_class_module = base_class_module,
2419 base_class_name = base_class_name,
2424 def create_scope(self, env):
2426 while env.is_py_class_scope or env.is_c_class_scope:
2427 env = env.outer_scope
2428 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2431 def analyse_declarations(self, env):
2432 self.target.analyse_target_declaration(env)
2433 cenv = self.create_scope(env)
2434 cenv.class_obj_cname = self.target.entry.cname
2435 self.body.analyse_declarations(cenv)
2437 def analyse_expressions(self, env):
2438 self.dict.analyse_expressions(env)
2439 self.classobj.analyse_expressions(env)
2440 genv = env.global_scope()
2442 cenv.class_dict_cname = self.dict.result()
2443 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2444 self.body.analyse_expressions(cenv)
2445 self.target.analyse_target_expression(env, self.classobj)
2446 self.dict.release_temp(env)
2447 #self.classobj.release_temp(env)
2448 #self.target.release_target_temp(env)
2450 def generate_function_definitions(self, env, code):
2451 self.generate_py_string_decls(self.scope, code)
2452 self.body.generate_function_definitions(self.scope, code)
2454 def generate_execution_code(self, code):
2455 self.dict.generate_evaluation_code(code)
2456 self.classobj.generate_evaluation_code(code)
2457 self.body.generate_execution_code(code)
2458 self.target.generate_assignment_code(self.classobj, code)
2459 self.dict.generate_disposal_code(code)
2460 self.dict.free_temps(code)
2463 class CClassDefNode(ClassDefNode):
2464 # An extension type definition.
2466 # visibility 'private' or 'public' or 'extern'
2467 # typedef_flag boolean
2469 # module_name string or None For import of extern type objects
2470 # class_name string Unqualified name of class
2471 # as_name string or None Name to declare as in this scope
2472 # base_class_module string or None Module containing the base class
2473 # base_class_name string or None Name of the base class
2474 # objstruct_name string or None Specified C name of object struct
2475 # typeobj_name string or None Specified C name of type object
2476 # in_pxd boolean Is in a .pxd file
2477 # doc string or None
2478 # body StatNode or None
2479 # entry Symtab.Entry
2480 # base_type PyExtensionType or None
2481 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2482 # buffer_defaults_pos
2484 child_attrs = ["body"]
2485 buffer_defaults_node = None
2486 buffer_defaults_pos = None
2487 typedef_flag = False
2489 objstruct_name = None
2492 def analyse_declarations(self, env):
2493 #print "CClassDefNode.analyse_declarations:", self.class_name
2494 #print "...visibility =", self.visibility
2495 #print "...module_name =", self.module_name
2498 if self.buffer_defaults_node:
2499 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2500 env, [], self.buffer_defaults_node,
2501 need_complete=False)
2503 buffer_defaults = None
2505 if env.in_cinclude and not self.objstruct_name:
2506 error(self.pos, "Object struct name specification required for "
2507 "C class defined in 'extern from' block")
2508 self.base_type = None
2509 # Now that module imports are cached, we need to
2510 # import the modules for extern classes.
2511 if self.module_name:
2513 for module in env.cimported_modules:
2514 if module.name == self.module_name:
2515 self.module = module
2516 if self.module is None:
2517 self.module = ModuleScope(self.module_name, None, env.context)
2518 self.module.has_extern_class = 1
2519 env.cimported_modules.append(self.module)
2521 if self.base_class_name:
2522 if self.base_class_module:
2523 base_class_scope = env.find_module(self.base_class_module, self.pos)
2525 base_class_scope = env
2526 if self.base_class_name == 'object':
2527 # extension classes are special and don't need to inherit from object
2528 if base_class_scope is None or base_class_scope.lookup('object') is None:
2529 self.base_class_name = None
2530 self.base_class_module = None
2531 base_class_scope = None
2532 if base_class_scope:
2533 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2534 if base_class_entry:
2535 if not base_class_entry.is_type:
2536 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2537 elif not base_class_entry.type.is_extension_type:
2538 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2539 elif not base_class_entry.type.is_complete():
2540 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2542 self.base_type = base_class_entry.type
2543 has_body = self.body is not None
2544 if self.module_name and self.visibility != 'extern':
2545 module_path = self.module_name.split(".")
2546 home_scope = env.find_imported_module(module_path, self.pos)
2551 self.entry = home_scope.declare_c_class(
2552 name = self.class_name,
2554 defining = has_body and self.in_pxd,
2555 implementing = has_body and not self.in_pxd,
2556 module_name = self.module_name,
2557 base_type = self.base_type,
2558 objstruct_cname = self.objstruct_name,
2559 typeobj_cname = self.typeobj_name,
2560 visibility = self.visibility,
2561 typedef_flag = self.typedef_flag,
2563 buffer_defaults = buffer_defaults)
2564 if home_scope is not env and self.visibility == 'extern':
2565 env.add_imported_entry(self.class_name, self.entry, pos)
2566 scope = self.entry.type.scope
2568 if self.doc and Options.docstrings:
2569 scope.doc = embed_position(self.pos, self.doc)
2572 self.body.analyse_declarations(scope)
2576 scope.implemented = 1
2577 env.allocate_vtable_names(self.entry)
2579 def analyse_expressions(self, env):
2581 scope = self.entry.type.scope
2582 self.body.analyse_expressions(scope)
2584 def generate_function_definitions(self, env, code):
2585 self.generate_py_string_decls(self.entry.type.scope, code)
2587 self.body.generate_function_definitions(
2588 self.entry.type.scope, code)
2590 def generate_execution_code(self, code):
2591 # This is needed to generate evaluation code for
2592 # default values of method arguments.
2594 self.body.generate_execution_code(code)
2596 def annotate(self, code):
2598 self.body.annotate(code)
2601 class PropertyNode(StatNode):
2602 # Definition of a property in an extension type.
2605 # doc EncodedString or None Doc string
2608 child_attrs = ["body"]
2610 def analyse_declarations(self, env):
2611 entry = env.declare_property(self.name, self.doc, self.pos)
2613 if self.doc and Options.docstrings:
2614 doc_entry = env.get_string_const(
2615 self.doc, identifier = False)
2616 entry.doc_cname = doc_entry.cname
2617 self.body.analyse_declarations(entry.scope)
2619 def analyse_expressions(self, env):
2620 self.body.analyse_expressions(env)
2622 def generate_function_definitions(self, env, code):
2623 self.body.generate_function_definitions(env, code)
2625 def generate_execution_code(self, code):
2628 def annotate(self, code):
2629 self.body.annotate(code)
2632 class GlobalNode(StatNode):
2633 # Global variable declaration.
2639 def analyse_declarations(self, env):
2640 for name in self.names:
2641 env.declare_global(name, self.pos)
2643 def analyse_expressions(self, env):
2646 def generate_execution_code(self, code):
2650 class ExprStatNode(StatNode):
2651 # Expression used as a statement.
2655 child_attrs = ["expr"]
2657 def analyse_declarations(self, env):
2659 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2660 func = self.expr.function.as_cython_attribute()
2661 if func == u'declare':
2662 args, kwds = self.expr.explicit_args_kwds()
2664 error(self.expr.pos, "Variable names must be specified.")
2665 for var, type_node in kwds.key_value_pairs:
2666 type = type_node.analyse_as_type(env)
2668 error(type_node.pos, "Unknown type")
2670 env.declare_var(var.value, type, var.pos, is_cdef = True)
2671 self.__class__ = PassStatNode
2673 def analyse_expressions(self, env):
2674 self.expr.analyse_expressions(env)
2675 self.expr.release_temp(env)
2677 def generate_execution_code(self, code):
2678 self.expr.generate_evaluation_code(code)
2679 if not self.expr.is_temp and self.expr.result():
2680 code.putln("%s;" % self.expr.result())
2681 self.expr.generate_disposal_code(code)
2682 self.expr.free_temps(code)
2684 def annotate(self, code):
2685 self.expr.annotate(code)
2688 class AssignmentNode(StatNode):
2689 # Abstract base class for assignment nodes.
2691 # The analyse_expressions and generate_execution_code
2692 # phases of assignments are split into two sub-phases
2693 # each, to enable all the right hand sides of a
2694 # parallel assignment to be evaluated before assigning
2695 # to any of the left hand sides.
2697 def analyse_expressions(self, env):
2698 self.analyse_types(env)
2699 self.allocate_rhs_temps(env)
2700 self.allocate_lhs_temps(env)
2702 # def analyse_expressions(self, env):
2703 # self.analyse_expressions_1(env)
2704 # self.analyse_expressions_2(env)
2706 def generate_execution_code(self, code):
2707 self.generate_rhs_evaluation_code(code)
2708 self.generate_assignment_code(code)
2711 class SingleAssignmentNode(AssignmentNode):
2712 # The simplest case:
2716 # lhs ExprNode Left hand side
2717 # rhs ExprNode Right hand side
2718 # first bool Is this guaranteed the first assignment to lhs?
2720 child_attrs = ["lhs", "rhs"]
2722 declaration_only = False
2724 def analyse_declarations(self, env):
2727 # handle declarations of the form x = cython.foo()
2728 if isinstance(self.rhs, ExprNodes.CallNode):
2729 func_name = self.rhs.function.as_cython_attribute()
2731 args, kwds = self.rhs.explicit_args_kwds()
2733 if func_name in ['declare', 'typedef']:
2734 if len(args) > 2 or kwds is not None:
2735 error(rhs.pos, "Can only declare one type at a time.")
2737 type = args[0].analyse_as_type(env)
2739 error(args[0].pos, "Unknown type")
2742 if func_name == 'declare':
2743 if isinstance(lhs, ExprNodes.NameNode):
2744 vars = [(lhs.name, lhs.pos)]
2745 elif isinstance(lhs, ExprNodes.TupleNode):
2746 vars = [(var.name, var.pos) for var in lhs.args]
2748 error(lhs.pos, "Invalid declaration")
2750 for var, pos in vars:
2751 env.declare_var(var, type, pos, is_cdef = True)
2756 self.declaration_only = True
2758 self.declaration_only = True
2759 if not isinstance(lhs, ExprNodes.NameNode):
2760 error(lhs.pos, "Invalid declaration.")
2761 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2763 elif func_name in ['struct', 'union']:
2764 self.declaration_only = True
2765 if len(args) > 0 or kwds is None:
2766 error(rhs.pos, "Struct or union members must be given by name.")
2769 for member, type_node in kwds.key_value_pairs:
2770 type = type_node.analyse_as_type(env)
2772 error(type_node.pos, "Unknown type")
2774 members.append((member.value, type, member.pos))
2775 if len(members) < len(kwds.key_value_pairs):
2777 if not isinstance(self.lhs, ExprNodes.NameNode):
2778 error(self.lhs.pos, "Invalid declaration.")
2779 name = self.lhs.name
2780 scope = StructOrUnionScope(name)
2781 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2782 for member, type, pos in members:
2783 scope.declare_var(member, type, pos)
2785 if self.declaration_only:
2788 self.lhs.analyse_target_declaration(env)
2790 def analyse_types(self, env, use_temp = 0):
2791 self.rhs.analyse_types(env)
2792 self.lhs.analyse_target_types(env)
2793 self.lhs.gil_assignment_check(env)
2794 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2796 self.rhs = self.rhs.coerce_to_temp(env)
2798 def allocate_rhs_temps(self, env):
2799 self.rhs.allocate_temps(env)
2801 def allocate_lhs_temps(self, env):
2802 self.lhs.allocate_target_temps(env, self.rhs)
2803 #self.lhs.release_target_temp(env)
2804 #self.rhs.release_temp(env)
2806 # def analyse_expressions_1(self, env, use_temp = 0):
2807 # self.rhs.analyse_types(env)
2808 # self.lhs.analyse_target_types(env)
2809 # self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2811 # self.rhs = self.rhs.coerce_to_temp(env)
2812 # self.rhs.allocate_temps(env)
2814 # def analyse_expressions_2(self, env):
2815 # self.lhs.allocate_target_temps(env)
2816 # self.lhs.release_target_temp(env)
2817 # self.rhs.release_temp(env)
2819 def generate_rhs_evaluation_code(self, code):
2820 self.rhs.generate_evaluation_code(code)
2822 def generate_assignment_code(self, code):
2823 self.lhs.generate_assignment_code(self.rhs, code)
2825 def annotate(self, code):
2826 self.lhs.annotate(code)
2827 self.rhs.annotate(code)
2830 class CascadedAssignmentNode(AssignmentNode):
2831 # An assignment with multiple left hand sides:
2835 # lhs_list [ExprNode] Left hand sides
2836 # rhs ExprNode Right hand sides
2840 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2842 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2843 coerced_rhs_list = None
2845 def analyse_declarations(self, env):
2846 for lhs in self.lhs_list:
2847 lhs.analyse_target_declaration(env)
2849 def analyse_types(self, env, use_temp = 0):
2850 self.rhs.analyse_types(env)
2852 self.rhs = self.rhs.coerce_to_temp(env)
2854 self.rhs = self.rhs.coerce_to_simple(env)
2855 from ExprNodes import CloneNode
2856 self.coerced_rhs_list = []
2857 for lhs in self.lhs_list:
2858 lhs.analyse_target_types(env)
2859 lhs.gil_assignment_check(env)
2860 rhs = CloneNode(self.rhs)
2861 rhs = rhs.coerce_to(lhs.type, env)
2862 self.coerced_rhs_list.append(rhs)
2864 def allocate_rhs_temps(self, env):
2865 self.rhs.allocate_temps(env)
2867 def allocate_lhs_temps(self, env):
2868 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2869 rhs.allocate_temps(env)
2870 lhs.allocate_target_temps(env, rhs)
2871 #lhs.release_target_temp(env)
2872 #rhs.release_temp(env)
2873 self.rhs.release_temp(env)
2875 # def analyse_expressions_1(self, env, use_temp = 0):
2876 # self.rhs.analyse_types(env)
2878 # self.rhs = self.rhs.coerce_to_temp(env)
2880 # self.rhs = self.rhs.coerce_to_simple(env)
2881 # self.rhs.allocate_temps(env)
2883 # def analyse_expressions_2(self, env):
2884 # from ExprNodes import CloneNode
2885 # self.coerced_rhs_list = []
2886 # for lhs in self.lhs_list:
2887 # lhs.analyse_target_types(env)
2888 # rhs = CloneNode(self.rhs)
2889 # rhs = rhs.coerce_to(lhs.type, env)
2890 # self.coerced_rhs_list.append(rhs)
2891 # rhs.allocate_temps(env)
2892 # lhs.allocate_target_temps(env)
2893 # lhs.release_target_temp(env)
2894 # rhs.release_temp(env)
2895 # self.rhs.release_temp(env)
2897 def generate_rhs_evaluation_code(self, code):
2898 self.rhs.generate_evaluation_code(code)
2900 def generate_assignment_code(self, code):
2901 for i in range(len(self.lhs_list)):
2902 lhs = self.lhs_list[i]
2903 rhs = self.coerced_rhs_list[i]
2904 rhs.generate_evaluation_code(code)
2905 lhs.generate_assignment_code(rhs, code)
2906 # Assignment has disposed of the cloned RHS
2907 self.rhs.generate_disposal_code(code)
2908 self.rhs.free_temps(code)
2910 def annotate(self, code):
2911 for i in range(len(self.lhs_list)):
2912 lhs = self.lhs_list[i].annotate(code)
2913 rhs = self.coerced_rhs_list[i].annotate(code)
2914 self.rhs.annotate(code)
2917 class ParallelAssignmentNode(AssignmentNode):
2918 # A combined packing/unpacking assignment:
2922 # This has been rearranged by the parser into
2924 # a = d ; b = e ; c = f
2926 # but we must evaluate all the right hand sides
2927 # before assigning to any of the left hand sides.
2929 # stats [AssignmentNode] The constituent assignments
2931 child_attrs = ["stats"]
2933 def analyse_declarations(self, env):
2934 for stat in self.stats:
2935 stat.analyse_declarations(env)
2937 def analyse_expressions(self, env):
2938 for stat in self.stats:
2939 stat.analyse_types(env, use_temp = 1)
2940 stat.allocate_rhs_temps(env)
2941 for stat in self.stats:
2942 stat.allocate_lhs_temps(env)
2944 # def analyse_expressions(self, env):
2945 # for stat in self.stats:
2946 # stat.analyse_expressions_1(env, use_temp = 1)
2947 # for stat in self.stats:
2948 # stat.analyse_expressions_2(env)
2950 def generate_execution_code(self, code):
2951 for stat in self.stats:
2952 stat.generate_rhs_evaluation_code(code)
2953 for stat in self.stats:
2954 stat.generate_assignment_code(code)
2956 def annotate(self, code):
2957 for stat in self.stats:
2961 class InPlaceAssignmentNode(AssignmentNode):
2962 # An in place arithmatic operand:
2968 # lhs ExprNode Left hand side
2969 # rhs ExprNode Right hand side
2970 # op char one of "+-*/%^&|"
2971 # dup (ExprNode) copy of lhs used for operation (auto-generated)
2973 # This code is a bit tricky because in order to obey Python
2974 # semantics the sub-expressions (e.g. indices) of the lhs must
2975 # not be evaluated twice. So we must re-use the values calculated
2976 # in evaluation phase for the assignment phase as well.
2977 # Fortunately, the type of the lhs node is fairly constrained
2978 # (it must be a NameNode, AttributeNode, or IndexNode).
2980 child_attrs = ["lhs", "rhs"]
2983 def analyse_declarations(self, env):
2984 self.lhs.analyse_target_declaration(env)
2986 def analyse_types(self, env):
2987 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
2988 self.rhs.analyse_types(env)
2989 self.lhs.analyse_target_types(env)
2990 if Options.incref_local_binop and self.dup.type.is_pyobject:
2991 self.dup = self.dup.coerce_to_temp(env)
2993 def allocate_rhs_temps(self, env):
2995 if self.lhs.type.is_pyobject:
2996 self.rhs = self.rhs.coerce_to_pyobject(env)
2997 elif self.rhs.type.is_pyobject:
2998 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2999 if self.lhs.type.is_pyobject:
3000 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3001 self.result_value.allocate_temps(env)
3003 # self.rhs = self.rhs.coerce_to_temp(env)
3004 self.rhs.allocate_temps(env)
3005 self.dup.allocate_subexpr_temps(env)
3006 self.dup.allocate_temp(env)
3008 def allocate_lhs_temps(self, env):
3009 self.lhs.allocate_target_temps(env, self.rhs)
3010 # self.lhs.release_target_temp(env)
3011 self.dup.release_temp(env)
3012 if self.dup.is_temp:
3013 self.dup.release_subexpr_temps(env)
3014 # self.rhs.release_temp(env)
3015 if self.lhs.type.is_pyobject:
3016 self.result_value.release_temp(env)
3018 def generate_execution_code(self, code):
3019 self.rhs.generate_evaluation_code(code)
3020 self.dup.generate_subexpr_evaluation_code(code)
3021 # self.dup.generate_result_code is run only if it is not buffer access
3022 if self.operator == "**":
3027 if self.lhs.type.is_pyobject:
3028 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3029 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3030 self.dup.generate_result_code(code)
3032 "%s = %s(%s, %s%s); %s" % (
3033 self.result_value.result(),
3034 self.py_operation_function(),
3035 self.dup.py_result(),
3036 self.rhs.py_result(),
3038 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3039 self.result_value.generate_evaluation_code(code) # May be a type check...
3040 self.rhs.generate_disposal_code(code)
3041 self.rhs.free_temps(code)
3042 self.dup.generate_disposal_code(code)
3043 self.dup.free_temps(code)
3044 self.lhs.generate_assignment_code(self.result_value, code)
3046 c_op = self.operator
3050 if self.lhs.type.is_int and self.rhs.type.is_int:
3051 error(self.pos, "** with two C int types is ambiguous")
3053 error(self.pos, "No C inplace power operator")
3054 # have to do assignment directly to avoid side-effects
3055 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3056 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3058 self.dup.generate_result_code(code)
3059 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3060 self.rhs.generate_disposal_code(code)
3061 self.rhs.free_temps(code)
3062 if self.dup.is_temp:
3063 self.dup.generate_subexpr_disposal_code(code)
3064 self.dup.free_subexpr_temps(code)
3066 def create_dup_node(self, env):
3069 self.dup.analyse_types(env)
3070 if isinstance(self.lhs, ExprNodes.NameNode):
3071 target_lhs = ExprNodes.NameNode(self.dup.pos,
3072 name = self.dup.name,
3073 is_temp = self.dup.is_temp,
3074 entry = self.dup.entry)
3075 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3076 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3077 obj = ExprNodes.CloneNode(self.lhs.obj),
3078 attribute = self.dup.attribute,
3079 is_temp = self.dup.is_temp)
3080 elif isinstance(self.lhs, ExprNodes.IndexNode):
3082 index = ExprNodes.CloneNode(self.lhs.index)
3085 if self.lhs.indices:
3086 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3089 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3090 base = ExprNodes.CloneNode(self.dup.base),
3093 is_temp = self.dup.is_temp)
3096 self.lhs = target_lhs
3099 def py_operation_function(self):
3100 return self.py_functions[self.operator]
3103 "|": "PyNumber_InPlaceOr",
3104 "^": "PyNumber_InPlaceXor",
3105 "&": "PyNumber_InPlaceAnd",
3106 "+": "PyNumber_InPlaceAdd",
3107 "-": "PyNumber_InPlaceSubtract",
3108 "*": "PyNumber_InPlaceMultiply",
3109 "/": "PyNumber_InPlaceDivide",
3110 "%": "PyNumber_InPlaceRemainder",
3111 "<<": "PyNumber_InPlaceLshift",
3112 ">>": "PyNumber_InPlaceRshift",
3113 "**": "PyNumber_InPlacePower",
3114 "//": "PyNumber_InPlaceFloorDivide",
3117 def annotate(self, code):
3118 self.lhs.annotate(code)
3119 self.rhs.annotate(code)
3120 self.dup.annotate(code)
3123 class PrintStatNode(StatNode):
3126 # arg_tuple TupleNode
3127 # append_newline boolean
3129 child_attrs = ["arg_tuple"]
3131 def analyse_expressions(self, env):
3132 self.arg_tuple.analyse_expressions(env)
3133 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3134 self.arg_tuple.release_temp(env)
3135 env.use_utility_code(printing_utility_code)
3138 gil_message = "Python print statement"
3140 def generate_execution_code(self, code):
3141 self.arg_tuple.generate_evaluation_code(code)
3143 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3144 self.arg_tuple.py_result(),
3145 self.append_newline,
3146 code.error_goto(self.pos)))
3147 self.arg_tuple.generate_disposal_code(code)
3148 self.arg_tuple.free_temps(code)
3150 def annotate(self, code):
3151 self.arg_tuple.annotate(code)
3154 class ExecStatNode(StatNode):
3159 child_attrs = ["args"]
3161 def analyse_expressions(self, env):
3162 for i, arg in enumerate(self.args):
3163 arg.analyse_expressions(env)
3164 arg = arg.coerce_to_pyobject(env)
3165 arg.release_temp(env)
3167 self.temp_result = env.allocate_temp_pyobject()
3168 env.release_temp(self.temp_result)
3169 env.use_utility_code(Builtin.pyexec_utility_code)
3172 gil_message = "Python exec statement"
3174 def generate_execution_code(self, code):
3176 for arg in self.args:
3177 arg.generate_evaluation_code(code)
3178 args.append( arg.py_result() )
3179 args = tuple(args + ['0', '0'][:3-len(args)])
3180 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3181 (self.temp_result,) + args))
3182 for arg in self.args:
3183 arg.generate_disposal_code(code)
3184 arg.free_temps(code)
3186 code.error_goto_if_null(self.temp_result, self.pos))
3187 code.put_decref_clear(self.temp_result, py_object_type)
3189 def annotate(self, code):
3190 for arg in self.args:
3194 class DelStatNode(StatNode):
3199 child_attrs = ["args"]
3201 def analyse_declarations(self, env):
3202 for arg in self.args:
3203 arg.analyse_target_declaration(env)
3205 def analyse_expressions(self, env):
3206 for arg in self.args:
3207 arg.analyse_target_expression(env, None)
3208 if arg.type.is_pyobject:
3211 error(arg.pos, "Deletion of non-Python object")
3212 #arg.release_target_temp(env)
3214 gil_message = "Deleting Python object"
3216 def generate_execution_code(self, code):
3217 for arg in self.args:
3218 if arg.type.is_pyobject:
3219 arg.generate_deletion_code(code)
3220 # else error reported earlier
3222 def annotate(self, code):
3223 for arg in self.args:
3227 class PassStatNode(StatNode):
3232 def analyse_expressions(self, env):
3235 def generate_execution_code(self, code):
3239 class BreakStatNode(StatNode):
3243 def analyse_expressions(self, env):
3246 def generate_execution_code(self, code):
3247 if not code.break_label:
3248 error(self.pos, "break statement not inside loop")
3253 code.put_goto(code.break_label)
3256 class ContinueStatNode(StatNode):
3260 def analyse_expressions(self, env):
3263 def generate_execution_code(self, code):
3264 if code.funcstate.in_try_finally:
3265 error(self.pos, "continue statement inside try of try...finally")
3266 elif not code.continue_label:
3267 error(self.pos, "continue statement not inside loop")
3269 code.put_goto(code.continue_label)
3272 class ReturnStatNode(StatNode):
3275 # value ExprNode or None
3276 # return_type PyrexType
3277 # temps_in_use [Entry] Temps in use at time of return
3279 child_attrs = ["value"]
3281 def analyse_expressions(self, env):
3282 return_type = env.return_type
3283 self.return_type = return_type
3284 self.temps_in_use = env.temps_in_use()
3286 error(self.pos, "Return not inside a function body")
3289 self.value.analyse_types(env)
3290 if return_type.is_void or return_type.is_returncode:
3291 error(self.value.pos,
3292 "Return with value in void function")
3294 self.value = self.value.coerce_to(env.return_type, env)
3295 self.value.allocate_temps(env)
3296 self.value.release_temp(env)
3298 if (not return_type.is_void
3299 and not return_type.is_pyobject
3300 and not return_type.is_returncode):
3301 error(self.pos, "Return value required")
3302 if return_type.is_pyobject:
3305 gil_message = "Returning Python object"
3307 def generate_execution_code(self, code):
3308 code.mark_pos(self.pos)
3309 if not self.return_type:
3310 # error reported earlier
3313 self.value.generate_evaluation_code(code)
3314 self.value.make_owned_reference(code)
3317 Naming.retval_cname,
3318 self.value.result_as(self.return_type)))
3319 self.value.generate_post_assignment_code(code)
3320 self.value.free_temps(code)
3322 if self.return_type.is_pyobject:
3323 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3324 elif self.return_type.is_returncode:
3327 Naming.retval_cname,
3328 self.return_type.default_value))
3329 # free temps the old way
3330 for entry in self.temps_in_use:
3331 code.put_var_decref_clear(entry)
3332 # free temps the new way
3333 for cname, type in code.funcstate.temps_holding_reference():
3334 code.put_decref_clear(cname, type)
3337 # code.return_label)
3338 code.put_goto(code.return_label)
3340 def annotate(self, code):
3342 self.value.annotate(code)
3345 class RaiseStatNode(StatNode):
3348 # exc_type ExprNode or None
3349 # exc_value ExprNode or None
3350 # exc_tb ExprNode or None
3352 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3354 def analyse_expressions(self, env):
3356 self.exc_type.analyse_types(env)
3357 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3358 self.exc_type.allocate_temps(env)
3360 self.exc_value.analyse_types(env)
3361 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3362 self.exc_value.allocate_temps(env)
3364 self.exc_tb.analyse_types(env)
3365 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3366 self.exc_tb.allocate_temps(env)
3368 self.exc_type.release_temp(env)
3370 self.exc_value.release_temp(env)
3372 self.exc_tb.release_temp(env)
3373 env.use_utility_code(raise_utility_code)
3374 env.use_utility_code(restore_exception_utility_code)
3377 gil_message = "Raising exception"
3379 def generate_execution_code(self, code):
3381 self.exc_type.generate_evaluation_code(code)
3382 type_code = self.exc_type.py_result()
3386 self.exc_value.generate_evaluation_code(code)
3387 value_code = self.exc_value.py_result()
3391 self.exc_tb.generate_evaluation_code(code)
3392 tb_code = self.exc_tb.py_result()
3395 if self.exc_type or self.exc_value or self.exc_tb:
3397 "__Pyx_Raise(%s, %s, %s);" % (
3404 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3406 obj.generate_disposal_code(code)
3407 obj.free_temps(code)
3409 code.error_goto(self.pos))
3411 def annotate(self, code):
3413 self.exc_type.annotate(code)
3415 self.exc_value.annotate(code)
3417 self.exc_tb.annotate(code)
3420 class ReraiseStatNode(StatNode):
3424 def analyse_expressions(self, env):
3426 env.use_utility_code(raise_utility_code)
3427 env.use_utility_code(restore_exception_utility_code)
3429 gil_message = "Raising exception"
3431 def generate_execution_code(self, code):
3432 vars = code.funcstate.exc_vars
3434 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3435 code.putln(code.error_goto(self.pos))
3437 error(self.pos, "Reraise not inside except clause")
3440 class AssertStatNode(StatNode):
3444 # value ExprNode or None
3446 child_attrs = ["cond", "value"]
3448 def analyse_expressions(self, env):
3449 self.cond = self.cond.analyse_boolean_expression(env)
3451 self.value.analyse_types(env)
3452 self.value = self.value.coerce_to_pyobject(env)
3453 self.value.allocate_temps(env)
3454 self.cond.release_temp(env)
3456 self.value.release_temp(env)
3458 #env.recycle_pending_temps() # TEMPORARY
3460 gil_message = "Raising exception"
3462 def generate_execution_code(self, code):
3463 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3464 self.cond.generate_evaluation_code(code)
3466 "if (unlikely(!%s)) {" %
3469 self.value.generate_evaluation_code(code)
3471 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3472 self.value.py_result())
3473 self.value.generate_disposal_code(code)
3474 self.value.free_temps(code)
3477 "PyErr_SetNone(PyExc_AssertionError);")
3479 code.error_goto(self.pos))
3482 self.cond.generate_disposal_code(code)
3483 self.cond.free_temps(code)
3484 code.putln("#endif")
3486 def annotate(self, code):
3487 self.cond.annotate(code)
3489 self.value.annotate(code)
3492 class IfStatNode(StatNode):
3495 # if_clauses [IfClauseNode]
3496 # else_clause StatNode or None
3498 child_attrs = ["if_clauses", "else_clause"]
3500 def analyse_control_flow(self, env):
3501 env.start_branching(self.pos)
3502 for if_clause in self.if_clauses:
3503 if_clause.analyse_control_flow(env)
3504 env.next_branch(if_clause.end_pos())
3505 if self.else_clause:
3506 self.else_clause.analyse_control_flow(env)
3507 env.finish_branching(self.end_pos())
3509 def analyse_declarations(self, env):
3510 for if_clause in self.if_clauses:
3511 if_clause.analyse_declarations(env)
3512 if self.else_clause:
3513 self.else_clause.analyse_declarations(env)
3515 def analyse_expressions(self, env):
3516 for if_clause in self.if_clauses:
3517 if_clause.analyse_expressions(env)
3518 if self.else_clause:
3519 self.else_clause.analyse_expressions(env)
3521 def generate_execution_code(self, code):
3522 code.mark_pos(self.pos)
3523 end_label = code.new_label()
3524 for if_clause in self.if_clauses:
3525 if_clause.generate_execution_code(code, end_label)
3526 if self.else_clause:
3527 code.putln("/*else*/ {")
3528 self.else_clause.generate_execution_code(code)
3530 code.put_label(end_label)
3532 def annotate(self, code):
3533 for if_clause in self.if_clauses:
3534 if_clause.annotate(code)
3535 if self.else_clause:
3536 self.else_clause.annotate(code)
3539 class IfClauseNode(Node):
3540 # if or elif clause in an if statement
3542 # condition ExprNode
3545 child_attrs = ["condition", "body"]
3547 def analyse_control_flow(self, env):
3548 self.body.analyse_control_flow(env)
3550 def analyse_declarations(self, env):
3551 self.condition.analyse_declarations(env)
3552 self.body.analyse_declarations(env)
3554 def analyse_expressions(self, env):
3556 self.condition.analyse_temp_boolean_expression(env)
3557 self.condition.release_temp(env)
3558 self.body.analyse_expressions(env)
3560 def generate_execution_code(self, code, end_label):
3561 self.condition.generate_evaluation_code(code)
3564 self.condition.result())
3565 self.condition.generate_disposal_code(code)
3566 self.condition.free_temps(code)
3567 self.body.generate_execution_code(code)
3571 code.put_goto(end_label)
3574 def annotate(self, code):
3575 self.condition.annotate(code)
3576 self.body.annotate(code)
3579 class SwitchCaseNode(StatNode):
3580 # Generated in the optimization of an if-elif-else node
3582 # conditions [ExprNode]
3585 child_attrs = ['conditions', 'body']
3587 def generate_execution_code(self, code):
3588 for cond in self.conditions:
3589 code.putln("case %s:" % cond.calculate_result_code())
3590 self.body.generate_execution_code(code)
3591 code.putln("break;")
3593 def annotate(self, code):
3594 for cond in self.conditions:
3596 self.body.annotate(code)
3598 class SwitchStatNode(StatNode):
3599 # Generated in the optimization of an if-elif-else node
3602 # cases [SwitchCaseNode]
3603 # else_clause StatNode or None
3605 child_attrs = ['test', 'cases', 'else_clause']
3607 def generate_execution_code(self, code):
3608 code.putln("switch (%s) {" % self.test.calculate_result_code())
3609 for case in self.cases:
3610 case.generate_execution_code(code)
3611 if self.else_clause is not None:
3612 code.putln("default:")
3613 self.else_clause.generate_execution_code(code)
3614 code.putln("break;")
3617 def annotate(self, code):
3618 self.test.annotate(code)
3619 for case in self.cases:
3621 if self.else_clause is not None:
3622 self.else_clause.annotate(code)
3626 def analyse_control_flow(self, env):
3627 env.start_branching(self.pos)
3628 self.body.analyse_control_flow(env)
3629 env.next_branch(self.body.end_pos())
3630 if self.else_clause:
3631 self.else_clause.analyse_control_flow(env)
3632 env.finish_branching(self.end_pos())
3635 class WhileStatNode(LoopNode, StatNode):
3638 # condition ExprNode
3640 # else_clause StatNode
3642 child_attrs = ["condition", "body", "else_clause"]
3644 def analyse_declarations(self, env):
3645 self.body.analyse_declarations(env)
3646 if self.else_clause:
3647 self.else_clause.analyse_declarations(env)
3649 def analyse_expressions(self, env):
3651 self.condition.analyse_temp_boolean_expression(env)
3652 self.condition.release_temp(env)
3653 #env.recycle_pending_temps() # TEMPORARY
3654 self.body.analyse_expressions(env)
3655 if self.else_clause:
3656 self.else_clause.analyse_expressions(env)
3658 def generate_execution_code(self, code):
3659 old_loop_labels = code.new_loop_labels()
3662 self.condition.generate_evaluation_code(code)
3663 self.condition.generate_disposal_code(code)
3666 self.condition.result())
3667 self.condition.free_temps(code)
3668 self.body.generate_execution_code(code)
3669 code.put_label(code.continue_label)
3671 break_label = code.break_label
3672 code.set_loop_labels(old_loop_labels)
3673 if self.else_clause:
3674 code.putln("/*else*/ {")
3675 self.else_clause.generate_execution_code(code)
3677 code.put_label(break_label)
3679 def annotate(self, code):
3680 self.condition.annotate(code)
3681 self.body.annotate(code)
3682 if self.else_clause:
3683 self.else_clause.annotate(code)
3686 def ForStatNode(pos, **kw):
3687 if kw.has_key('iterator'):
3688 return ForInStatNode(pos, **kw)
3690 return ForFromStatNode(pos, **kw)
3692 class ForInStatNode(LoopNode, StatNode):
3696 # iterator IteratorNode
3698 # else_clause StatNode
3699 # item NextNode used internally
3701 child_attrs = ["target", "iterator", "body", "else_clause"]
3704 def analyse_declarations(self, env):
3705 self.target.analyse_target_declaration(env)
3706 self.body.analyse_declarations(env)
3707 if self.else_clause:
3708 self.else_clause.analyse_declarations(env)
3710 def analyse_expressions(self, env):
3712 self.target.analyse_target_types(env)
3713 self.iterator.analyse_expressions(env)
3714 self.item = ExprNodes.NextNode(self.iterator, env)
3715 self.item = self.item.coerce_to(self.target.type, env)
3716 self.item.allocate_temps(env)
3717 self.target.allocate_target_temps(env, self.item)
3718 #self.item.release_temp(env)
3719 #self.target.release_target_temp(env)
3720 self.body.analyse_expressions(env)
3721 if self.else_clause:
3722 self.else_clause.analyse_expressions(env)
3723 self.iterator.release_temp(env)
3725 def generate_execution_code(self, code):
3726 old_loop_labels = code.new_loop_labels()
3727 self.iterator.allocate_counter_temp(code)
3728 self.iterator.generate_evaluation_code(code)
3731 self.item.generate_evaluation_code(code)
3732 self.target.generate_assignment_code(self.item, code)
3733 self.body.generate_execution_code(code)
3734 code.put_label(code.continue_label)
3737 break_label = code.break_label
3738 code.set_loop_labels(old_loop_labels)
3739 if self.else_clause:
3740 code.putln("/*else*/ {")
3741 self.else_clause.generate_execution_code(code)
3743 code.put_label(break_label)
3744 self.iterator.release_counter_temp(code)
3745 self.iterator.generate_disposal_code(code)
3746 self.iterator.free_temps(code)
3748 def annotate(self, code):
3749 self.target.annotate(code)
3750 self.iterator.annotate(code)
3751 self.body.annotate(code)
3752 if self.else_clause:
3753 self.else_clause.annotate(code)
3754 self.item.annotate(code)
3757 class ForFromStatNode(LoopNode, StatNode):
3758 # for name from expr rel name rel expr
3765 # step ExprNode or None
3767 # else_clause StatNode or None
3772 # loopvar_node ExprNode (usually a NameNode or temp node)
3773 # py_loopvar_node PyTempNode or None
3774 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3776 is_py_target = False
3778 py_loopvar_node = None
3780 def analyse_declarations(self, env):
3781 self.target.analyse_target_declaration(env)
3782 self.body.analyse_declarations(env)
3783 if self.else_clause:
3784 self.else_clause.analyse_declarations(env)
3786 def analyse_expressions(self, env):
3788 self.target.analyse_target_types(env)
3789 self.bound1.analyse_types(env)
3790 self.bound2.analyse_types(env)
3791 if self.target.type.is_numeric:
3792 self.bound1 = self.bound1.coerce_to(self.target.type, env)
3793 self.bound2 = self.bound2.coerce_to(self.target.type, env)
3795 self.bound1 = self.bound1.coerce_to_integer(env)
3796 self.bound2 = self.bound2.coerce_to_integer(env)
3797 if self.step is not None:
3798 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3799 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3800 self.step.analyse_types(env)
3801 self.step = self.step.coerce_to_integer(env)
3802 if not (self.bound2.is_name or self.bound2.is_literal):
3803 self.bound2 = self.bound2.coerce_to_temp(env)
3804 target_type = self.target.type
3805 if not (target_type.is_pyobject or target_type.is_numeric):
3806 error(self.target.pos,
3807 "Integer for-loop variable must be of type int or Python object")
3808 #if not (target_type.is_pyobject
3809 # or target_type.assignable_from(PyrexTypes.c_int_type)):
3810 # error(self.target.pos,
3811 # "Cannot assign integer to variable of type '%s'" % target_type)
3812 if target_type.is_numeric:
3813 self.is_py_target = 0
3814 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3815 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3816 self.loopvar_node = self.target
3817 self.py_loopvar_node = None
3819 self.is_py_target = 1
3820 c_loopvar_node = ExprNodes.TempNode(self.pos,
3821 PyrexTypes.c_long_type, env)
3822 c_loopvar_node.allocate_temps(env)
3823 self.loopvar_node = c_loopvar_node
3824 self.py_loopvar_node = \
3825 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3826 self.bound1.allocate_temps(env)
3827 self.bound2.allocate_temps(env)
3828 if self.step is not None:
3829 self.step.allocate_temps(env)
3830 if self.is_py_target:
3831 self.py_loopvar_node.allocate_temps(env)
3832 self.target.allocate_target_temps(env, self.py_loopvar_node)
3833 #self.target.release_target_temp(env)
3834 #self.py_loopvar_node.release_temp(env)
3835 self.body.analyse_expressions(env)
3836 if self.is_py_target:
3837 c_loopvar_node.release_temp(env)
3838 if self.else_clause:
3839 self.else_clause.analyse_expressions(env)
3840 self.bound1.release_temp(env)
3841 self.bound2.release_temp(env)
3842 if self.step is not None:
3843 self.step.release_temp(env)
3845 def generate_execution_code(self, code):
3846 old_loop_labels = code.new_loop_labels()
3847 self.bound1.generate_evaluation_code(code)
3848 self.bound2.generate_evaluation_code(code)
3849 offset, incop = self.relation_table[self.relation1]
3850 if self.step is not None:
3851 self.step.generate_evaluation_code(code)
3852 incop = "%s=%s" % (incop[0], self.step.result())
3853 loopvar_name = self.loopvar_node.result()
3855 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3857 self.bound1.result(), offset,
3858 loopvar_name, self.relation2, self.bound2.result(),
3859 loopvar_name, incop))
3860 if self.py_loopvar_node:
3861 self.py_loopvar_node.generate_evaluation_code(code)
3862 self.target.generate_assignment_code(self.py_loopvar_node, code)
3863 self.body.generate_execution_code(code)
3864 code.put_label(code.continue_label)
3866 break_label = code.break_label
3867 code.set_loop_labels(old_loop_labels)
3868 if self.else_clause:
3869 code.putln("/*else*/ {")
3870 self.else_clause.generate_execution_code(code)
3872 code.put_label(break_label)
3873 self.bound1.generate_disposal_code(code)
3874 self.bound1.free_temps(code)
3875 self.bound2.generate_disposal_code(code)
3876 self.bound2.free_temps(code)
3877 if self.step is not None:
3878 self.step.generate_disposal_code(code)
3879 self.step.free_temps(code)
3882 # {relop : (initial offset, increment op)}
3889 def annotate(self, code):
3890 self.target.annotate(code)
3891 self.bound1.annotate(code)
3892 self.bound2.annotate(code)
3894 self.bound2.annotate(code)
3895 self.body.annotate(code)
3896 if self.else_clause:
3897 self.else_clause.annotate(code)
3900 class WithStatNode(StatNode):
3902 Represents a Python with statement.
3904 This is only used at parse tree level; and is not present in
3905 analysis or generation phases.
3907 # manager The with statement manager object
3908 # target Node (lhs expression)
3910 child_attrs = ["manager", "target", "body"]
3912 class TryExceptStatNode(StatNode):
3913 # try .. except statement
3916 # except_clauses [ExceptClauseNode]
3917 # else_clause StatNode or None
3918 # cleanup_list [Entry] temps to clean up on error
3920 child_attrs = ["body", "except_clauses", "else_clause"]
3922 def analyse_control_flow(self, env):
3923 env.start_branching(self.pos)
3924 self.body.analyse_control_flow(env)
3925 successful_try = env.control_flow # grab this for later
3926 env.next_branch(self.body.end_pos())
3927 env.finish_branching(self.body.end_pos())
3929 env.start_branching(self.except_clauses[0].pos)
3930 for except_clause in self.except_clauses:
3931 except_clause.analyse_control_flow(env)
3932 env.next_branch(except_clause.end_pos())
3934 # the else cause it executed only when the try clause finishes
3935 env.control_flow.incoming = successful_try
3936 if self.else_clause:
3937 self.else_clause.analyse_control_flow(env)
3938 env.finish_branching(self.end_pos())
3940 def analyse_declarations(self, env):
3941 self.body.analyse_declarations(env)
3942 for except_clause in self.except_clauses:
3943 except_clause.analyse_declarations(env)
3944 if self.else_clause:
3945 self.else_clause.analyse_declarations(env)
3947 env.use_utility_code(reset_exception_utility_code)
3949 def analyse_expressions(self, env):
3950 self.body.analyse_expressions(env)
3951 self.cleanup_list = env.free_temp_entries[:]
3952 default_clause_seen = 0
3953 for except_clause in self.except_clauses:
3954 except_clause.analyse_expressions(env)
3955 if default_clause_seen:
3956 error(except_clause.pos, "default 'except:' must be last")
3957 if not except_clause.pattern:
3958 default_clause_seen = 1
3959 self.has_default_clause = default_clause_seen
3960 if self.else_clause:
3961 self.else_clause.analyse_expressions(env)
3964 gil_message = "Try-except statement"
3966 def generate_execution_code(self, code):
3967 old_return_label = code.return_label
3968 old_error_label = code.new_error_label()
3969 our_error_label = code.error_label
3970 except_end_label = code.new_label('exception_handled')
3971 except_error_label = code.new_label('except_error')
3972 except_return_label = code.new_label('except_return')
3973 try_end_label = code.new_label('try')
3976 code.putln("PyObject %s;" %
3977 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
3978 code.putln("__Pyx_ExceptionSave(%s);" %
3979 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
3982 self.body.generate_execution_code(code)
3985 code.error_label = except_error_label
3986 code.return_label = except_return_label
3987 if self.else_clause:
3990 self.else_clause.generate_execution_code(code)
3993 for var in Naming.exc_save_vars:
3994 code.put_xdecref_clear(var, py_object_type)
3995 code.put_goto(try_end_label)
3996 code.put_label(our_error_label)
3997 code.put_var_xdecrefs_clear(self.cleanup_list)
3998 for except_clause in self.except_clauses:
3999 except_clause.generate_handling_code(code, except_end_label)
4001 error_label_used = code.label_used(except_error_label)
4002 if error_label_used or not self.has_default_clause:
4003 if error_label_used:
4004 code.put_label(except_error_label)
4005 for var in Naming.exc_save_vars:
4006 code.put_xdecref(var, py_object_type)
4007 code.put_goto(old_error_label)
4009 if code.label_used(except_return_label):
4010 code.put_label(except_return_label)
4011 code.putln("__Pyx_ExceptionReset(%s);" %
4012 ', '.join(Naming.exc_save_vars))
4013 code.put_goto(old_return_label)
4015 if code.label_used(except_end_label):
4016 code.put_label(except_end_label)
4017 code.putln("__Pyx_ExceptionReset(%s);" %
4018 ', '.join(Naming.exc_save_vars))
4019 code.put_label(try_end_label)
4022 code.return_label = old_return_label
4023 code.error_label = old_error_label
4025 def annotate(self, code):
4026 self.body.annotate(code)
4027 for except_node in self.except_clauses:
4028 except_node.annotate(code)
4029 if self.else_clause:
4030 self.else_clause.annotate(code)
4033 class ExceptClauseNode(Node):
4034 # Part of try ... except statement.
4037 # target ExprNode or None
4039 # excinfo_target NameNode or None optional target for exception info
4040 # match_flag string result of exception match
4041 # exc_value ExcValueNode used internally
4042 # function_name string qualified name of enclosing function
4043 # exc_vars (string * 3) local exception variables
4045 # excinfo_target is never set by the parser, but can be set by a transform
4046 # in order to extract more extensive information about the exception as a
4047 # sys.exc_info()-style tuple into a target variable
4049 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4052 excinfo_target = None
4054 def analyse_declarations(self, env):
4056 self.target.analyse_target_declaration(env)
4057 if self.excinfo_target is not None:
4058 self.excinfo_target.analyse_target_declaration(env)
4059 self.body.analyse_declarations(env)
4061 def analyse_expressions(self, env):
4063 genv = env.global_scope()
4064 self.function_name = env.qualified_name
4066 self.pattern.analyse_expressions(env)
4067 self.pattern = self.pattern.coerce_to_pyobject(env)
4068 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4069 self.pattern.release_temp(env)
4070 env.release_temp(self.match_flag)
4071 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4073 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4074 self.exc_value.allocate_temps(env)
4075 self.target.analyse_target_expression(env, self.exc_value)
4076 if self.excinfo_target is not None:
4078 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4079 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4080 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4081 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4083 self.excinfo_tuple.analyse_expressions(env)
4084 self.excinfo_tuple.allocate_temps(env)
4085 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4087 self.body.analyse_expressions(env)
4088 for var in self.exc_vars:
4089 env.release_temp(var)
4090 env.use_utility_code(get_exception_utility_code)
4091 env.use_utility_code(restore_exception_utility_code)
4093 def generate_handling_code(self, code, end_label):
4094 code.mark_pos(self.pos)
4096 self.pattern.generate_evaluation_code(code)
4098 "%s = PyErr_ExceptionMatches(%s);" % (
4100 self.pattern.py_result()))
4101 self.pattern.generate_disposal_code(code)
4102 self.pattern.free_temps(code)
4107 code.putln("/*except:*/ {")
4108 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4109 # We always have to fetch the exception value even if
4110 # there is no target, because this also normalises the
4111 # exception and stores it in the thread state.
4112 exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
4113 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4114 code.error_goto(self.pos)))
4116 self.exc_value.generate_evaluation_code(code)
4117 self.target.generate_assignment_code(self.exc_value, code)
4118 if self.excinfo_target is not None:
4119 self.excinfo_tuple.generate_evaluation_code(code)
4120 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4122 old_exc_vars = code.funcstate.exc_vars
4123 code.funcstate.exc_vars = self.exc_vars
4124 self.body.generate_execution_code(code)
4125 code.funcstate.exc_vars = old_exc_vars
4126 for var in self.exc_vars:
4127 code.putln("Py_DECREF(%s); %s = 0;" % (var, var))
4128 code.put_goto(end_label)
4132 def annotate(self, code):
4134 self.pattern.annotate(code)
4136 self.target.annotate(code)
4137 self.body.annotate(code)
4140 class TryFinallyStatNode(StatNode):
4141 # try ... finally statement
4144 # finally_clause StatNode
4146 # cleanup_list [Entry] temps to clean up on error
4148 # The plan is that we funnel all continue, break
4149 # return and error gotos into the beginning of the
4150 # finally block, setting a variable to remember which
4151 # one we're doing. At the end of the finally block, we
4152 # switch on the variable to figure out where to go.
4153 # In addition, if we're doing an error, we save the
4154 # exception on entry to the finally block and restore
4157 child_attrs = ["body", "finally_clause"]
4159 preserve_exception = 1
4161 disallow_continue_in_try_finally = 0
4162 # There doesn't seem to be any point in disallowing
4163 # continue in the try block, since we have no problem
4166 def create_analysed(pos, env, body, finally_clause):
4167 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4168 node.cleanup_list = []
4170 create_analysed = staticmethod(create_analysed)
4172 def analyse_control_flow(self, env):
4173 env.start_branching(self.pos)
4174 self.body.analyse_control_flow(env)
4175 env.next_branch(self.body.end_pos())
4176 env.finish_branching(self.body.end_pos())
4177 self.finally_clause.analyse_control_flow(env)
4179 def analyse_declarations(self, env):
4180 self.body.analyse_declarations(env)
4181 self.finally_clause.analyse_declarations(env)
4183 def analyse_expressions(self, env):
4184 self.body.analyse_expressions(env)
4185 self.cleanup_list = env.free_temp_entries[:]
4186 self.finally_clause.analyse_expressions(env)
4189 gil_message = "Try-finally statement"
4191 def generate_execution_code(self, code):
4192 old_error_label = code.error_label
4193 old_labels = code.all_new_labels()
4194 new_labels = code.get_all_labels()
4195 new_error_label = code.error_label
4196 catch_label = code.new_label()
4199 if self.disallow_continue_in_try_finally:
4200 was_in_try_finally = code.funcstate.in_try_finally
4201 code.funcstate.in_try_finally = 1
4202 self.body.generate_execution_code(code)
4203 if self.disallow_continue_in_try_finally:
4204 code.funcstate.in_try_finally = was_in_try_finally
4210 error_label_used = 0
4211 for i, new_label in enumerate(new_labels):
4212 if new_label in code.labels_used:
4213 cases_used.append(i)
4214 if new_label == new_error_label:
4215 error_label_used = 1
4216 error_label_case = i
4220 if error_label_used and self.preserve_exception:
4222 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4224 "int %s;" % Naming.exc_lineno_name)
4225 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4226 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4227 code.putln(exc_var_init_zero)
4229 exc_var_init_zero = None
4230 code.use_label(catch_label)
4232 "__pyx_why = 0; goto %s;" % catch_label)
4233 for i in cases_used:
4234 new_label = new_labels[i]
4235 #if new_label and new_label != "<try>":
4236 if new_label == new_error_label and self.preserve_exception:
4237 self.put_error_catcher(code,
4238 new_error_label, i+1, catch_label)
4240 code.put('%s: ' % new_label)
4241 if exc_var_init_zero:
4242 code.putln(exc_var_init_zero)
4243 code.putln("__pyx_why = %s; goto %s;" % (
4246 code.put_label(catch_label)
4247 code.set_all_labels(old_labels)
4248 if error_label_used:
4249 code.new_error_label()
4250 finally_error_label = code.error_label
4251 self.finally_clause.generate_execution_code(code)
4252 if error_label_used:
4253 if finally_error_label in code.labels_used and self.preserve_exception:
4254 over_label = code.new_label()
4255 code.put_goto(over_label);
4256 code.put_label(finally_error_label)
4257 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4258 for var in Naming.exc_vars:
4259 code.putln("Py_XDECREF(%s);" % var)
4261 code.put_goto(old_error_label)
4262 code.put_label(over_label)
4263 code.error_label = old_error_label
4266 "switch (__pyx_why) {")
4267 for i in cases_used:
4268 old_label = old_labels[i]
4269 if old_label == old_error_label and self.preserve_exception:
4270 self.put_error_uncatcher(code, i+1, old_error_label)
4272 code.use_label(old_label)
4274 "case %s: goto %s;" % (
4282 def put_error_catcher(self, code, error_label, i, catch_label):
4283 code.globalstate.use_utility_code(restore_exception_utility_code)
4290 code.put_var_xdecrefs_clear(self.cleanup_list)
4292 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4296 Naming.exc_lineno_name, Naming.lineno_cname))
4300 code.put_goto(catch_label)
4304 def put_error_uncatcher(self, code, i, error_label):
4305 code.globalstate.use_utility_code(restore_exception_utility_code)
4310 "__Pyx_ErrRestore(%s, %s, %s);" %
4314 Naming.lineno_cname, Naming.exc_lineno_name))
4315 for var in Naming.exc_vars:
4319 code.put_goto(error_label)
4323 def annotate(self, code):
4324 self.body.annotate(code)
4325 self.finally_clause.annotate(code)
4328 class GILStatNode(TryFinallyStatNode):
4329 # 'with gil' or 'with nogil' statement
4331 # state string 'gil' or 'nogil'
4335 preserve_exception = 0
4337 def __init__(self, pos, state, body):
4339 TryFinallyStatNode.__init__(self, pos,
4341 finally_clause = GILExitNode(pos, state = state))
4343 def analyse_expressions(self, env):
4344 was_nogil = env.nogil
4346 TryFinallyStatNode.analyse_expressions(self, env)
4347 env.nogil = was_nogil
4349 def gil_check(self, env):
4352 def generate_execution_code(self, code):
4353 code.putln("/*with %s:*/ {" % self.state)
4354 if self.state == 'gil':
4355 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
4357 code.putln("PyThreadState *_save;")
4358 code.putln("Py_UNBLOCK_THREADS")
4359 TryFinallyStatNode.generate_execution_code(self, code)
4363 class GILExitNode(StatNode):
4364 # Used as the 'finally' block in a GILStatNode
4366 # state string 'gil' or 'nogil'
4370 def analyse_expressions(self, env):
4373 def generate_execution_code(self, code):
4374 if self.state == 'gil':
4375 code.putln("PyGILState_Release();")
4377 code.putln("Py_BLOCK_THREADS")
4380 class CImportStatNode(StatNode):
4383 # module_name string Qualified name of module being imported
4384 # as_name string or None Name specified in "as" clause, if any
4388 def analyse_declarations(self, env):
4389 if not env.is_module_scope:
4390 error(self.pos, "cimport only allowed at module level")
4392 module_scope = env.find_module(self.module_name, self.pos)
4393 if "." in self.module_name:
4394 names = [EncodedString(name) for name in self.module_name.split(".")]
4396 top_module_scope = env.context.find_submodule(top_name)
4397 module_scope = top_module_scope
4398 for name in names[1:]:
4399 submodule_scope = module_scope.find_submodule(name)
4400 module_scope.declare_module(name, submodule_scope, self.pos)
4401 module_scope = submodule_scope
4403 env.declare_module(self.as_name, module_scope, self.pos)
4405 env.declare_module(top_name, top_module_scope, self.pos)
4407 name = self.as_name or self.module_name
4408 env.declare_module(name, module_scope, self.pos)
4410 def analyse_expressions(self, env):
4413 def generate_execution_code(self, code):
4417 class FromCImportStatNode(StatNode):
4418 # from ... cimport statement
4420 # module_name string Qualified name of module
4421 # imported_names [(pos, name, as_name, kind)] Names to be imported
4425 def analyse_declarations(self, env):
4426 if not env.is_module_scope:
4427 error(self.pos, "cimport only allowed at module level")
4429 module_scope = env.find_module(self.module_name, self.pos)
4430 env.add_imported_module(module_scope)
4431 for pos, name, as_name, kind in self.imported_names:
4433 for local_name, entry in module_scope.entries.items():
4434 env.add_imported_entry(local_name, entry, pos)
4436 entry = module_scope.lookup(name)
4438 if kind and not self.declaration_matches(entry, kind):
4439 entry.redeclared(pos)
4441 if kind == 'struct' or kind == 'union':
4442 entry = module_scope.declare_struct_or_union(name,
4443 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4444 elif kind == 'class':
4445 entry = module_scope.declare_c_class(name, pos = pos,
4446 module_name = self.module_name)
4448 error(pos, "Name '%s' not declared in module '%s'"
4449 % (name, self.module_name))
4452 local_name = as_name or name
4453 env.add_imported_entry(local_name, entry, pos)
4455 def declaration_matches(self, entry, kind):
4456 if not entry.is_type:
4460 if not type.is_extension_type:
4463 if not type.is_struct_or_union:
4465 if kind <> type.kind:
4469 def analyse_expressions(self, env):
4472 def generate_execution_code(self, code):
4476 class FromImportStatNode(StatNode):
4477 # from ... import statement
4480 # items [(string, NameNode)]
4481 # interned_items [(string, NameNode)]
4482 # item PyTempNode used internally
4483 # import_star boolean used internally
4485 child_attrs = ["module"]
4488 def analyse_declarations(self, env):
4489 for name, target in self.items:
4491 if not env.is_module_scope:
4492 error(self.pos, "import * only allowed at module level")
4494 env.has_import_star = 1
4495 self.import_star = 1
4497 target.analyse_target_declaration(env)
4499 def analyse_expressions(self, env):
4501 self.module.analyse_expressions(env)
4502 self.item = ExprNodes.PyTempNode(self.pos, env)
4503 self.item.allocate_temp(env)
4504 self.interned_items = []
4505 for name, target in self.items:
4507 for _, entry in env.entries.items():
4508 if not entry.is_type and entry.type.is_extension_type:
4509 env.use_utility_code(ExprNodes.type_test_utility_code)
4512 entry = env.lookup(target.name)
4513 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4514 continue # already cimported
4515 self.interned_items.append(
4516 (env.intern_identifier(name), target))
4517 target.analyse_target_expression(env, None)
4518 #target.release_target_temp(env) # was release_temp ?!?
4519 self.module.release_temp(env)
4520 self.item.release_temp(env)
4522 def generate_execution_code(self, code):
4523 self.module.generate_evaluation_code(code)
4524 if self.import_star:
4526 'if (%s(%s) < 0) %s;' % (
4528 self.module.py_result(),
4529 code.error_goto(self.pos)))
4530 for cname, target in self.interned_items:
4532 '%s = PyObject_GetAttr(%s, %s); %s' % (
4534 self.module.py_result(),
4536 code.error_goto_if_null(self.item.result(), self.pos)))
4537 target.generate_assignment_code(self.item, code)
4538 self.module.generate_disposal_code(code)
4539 self.module.free_temps(code)
4543 #------------------------------------------------------------------------------------
4545 # Runtime support code
4547 #------------------------------------------------------------------------------------
4549 utility_function_predeclarations = \
4552 #define INLINE __inline__
4554 #define INLINE __inline
4559 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4563 static int %(skip_dispatch_cname)s = 0;
4565 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4567 if Options.gcc_branch_hints:
4568 branch_prediction_macros = \
4571 /* Test for GCC > 2.95 */
4572 #if __GNUC__ > 2 || \
4573 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4574 #define likely(x) __builtin_expect(!!(x), 1)
4575 #define unlikely(x) __builtin_expect(!!(x), 0)
4576 #else /* __GNUC__ > 2 ... */
4577 #define likely(x) (x)
4578 #define unlikely(x) (x)
4579 #endif /* __GNUC__ > 2 ... */
4580 #else /* __GNUC__ */
4581 #define likely(x) (x)
4582 #define unlikely(x) (x)
4583 #endif /* __GNUC__ */
4586 branch_prediction_macros = \
4588 #define likely(x) (x)
4589 #define unlikely(x) (x)
4592 #get_name_predeclaration = \
4593 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4595 #get_name_interned_predeclaration = \
4596 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4598 #------------------------------------------------------------------------------------
4600 printing_utility_code = UtilityCode(
4602 static int __Pyx_Print(PyObject *, int); /*proto*/
4603 #if PY_MAJOR_VERSION >= 3
4604 static PyObject* %s = 0;
4605 static PyObject* %s = 0;
4607 """ % (Naming.print_function, Naming.print_function_kwargs),
4609 #if PY_MAJOR_VERSION < 3
4610 static PyObject *__Pyx_GetStdout(void) {
4611 PyObject *f = PySys_GetObject((char *)"stdout");
4613 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4618 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4623 if (!(f = __Pyx_GetStdout()))
4625 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4626 if (PyFile_SoftSpace(f, 1)) {
4627 if (PyFile_WriteString(" ", f) < 0)
4630 v = PyTuple_GET_ITEM(arg_tuple, i);
4631 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4633 if (PyString_Check(v)) {
4634 char *s = PyString_AsString(v);
4635 Py_ssize_t len = PyString_Size(v);
4637 isspace(Py_CHARMASK(s[len-1])) &&
4639 PyFile_SoftSpace(f, 0);
4643 if (PyFile_WriteString("\n", f) < 0)
4645 PyFile_SoftSpace(f, 0);
4650 #else /* Python 3 has a print function */
4651 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4652 PyObject* kwargs = 0;
4653 PyObject* result = 0;
4654 PyObject* end_string;
4655 if (!%(PRINT_FUNCTION)s) {
4656 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4657 if (!%(PRINT_FUNCTION)s)
4661 if (!%(PRINT_KWARGS)s) {
4662 %(PRINT_KWARGS)s = PyDict_New();
4663 if (!%(PRINT_KWARGS)s)
4665 end_string = PyUnicode_FromStringAndSize(" ", 1);
4668 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4669 Py_DECREF(end_string);
4672 Py_DECREF(end_string);
4674 kwargs = %(PRINT_KWARGS)s;
4676 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4683 """ % {'BUILTINS' : Naming.builtins_cname,
4684 'PRINT_FUNCTION' : Naming.print_function,
4685 'PRINT_KWARGS' : Naming.print_function_kwargs}
4688 #------------------------------------------------------------------------------------
4690 # The following function is based on do_raise() from ceval.c.
4692 raise_utility_code = UtilityCode(
4694 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4697 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4701 /* First, check the traceback argument, replacing None with NULL. */
4702 if (tb == Py_None) {
4706 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4707 PyErr_SetString(PyExc_TypeError,
4708 "raise: arg 3 must be a traceback or None");
4711 /* Next, replace a missing value with None */
4712 if (value == NULL) {
4716 #if PY_VERSION_HEX < 0x02050000
4717 if (!PyClass_Check(type))
4719 if (!PyType_Check(type))
4722 /* Raising an instance. The value should be a dummy. */
4723 if (value != Py_None) {
4724 PyErr_SetString(PyExc_TypeError,
4725 "instance exception may not have a separate value");
4728 /* Normalize to raise <class>, <instance> */
4731 #if PY_VERSION_HEX < 0x02050000
4732 if (PyInstance_Check(type)) {
4733 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4738 PyErr_SetString(PyExc_TypeError,
4739 "raise: exception must be an old-style class or instance");
4743 type = (PyObject*) Py_TYPE(type);
4745 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4746 PyErr_SetString(PyExc_TypeError,
4747 "raise: exception class must be a subclass of BaseException");
4752 __Pyx_ErrRestore(type, value, tb);
4762 #------------------------------------------------------------------------------------
4764 reraise_utility_code = UtilityCode(
4766 static void __Pyx_ReRaise(void); /*proto*/
4769 static void __Pyx_ReRaise(void) {
4770 PyThreadState *tstate = PyThreadState_Get();
4771 PyObject *type = tstate->exc_type;
4772 PyObject *value = tstate->exc_value;
4773 PyObject *tb = tstate->exc_traceback;
4777 __Pyx_ErrRestore(type, value, tb);
4781 #------------------------------------------------------------------------------------
4783 arg_type_test_utility_code = UtilityCode(
4785 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4786 const char *name, int exact); /*proto*/
4789 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4790 const char *name, int exact)
4793 PyErr_Format(PyExc_SystemError, "Missing type object");
4796 if (none_allowed && obj == Py_None) return 1;
4798 if (Py_TYPE(obj) == type) return 1;
4801 if (PyObject_TypeCheck(obj, type)) return 1;
4803 PyErr_Format(PyExc_TypeError,
4804 "Argument '%s' has incorrect type (expected %s, got %s)",
4805 name, type->tp_name, Py_TYPE(obj)->tp_name);
4810 #------------------------------------------------------------------------------------
4812 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
4813 # many or too few positional arguments were found. This handles
4814 # Py_ssize_t formatting correctly.
4816 raise_argtuple_invalid_utility_code = UtilityCode(
4818 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
4819 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
4822 static void __Pyx_RaiseArgtupleInvalid(
4823 const char* func_name,
4827 Py_ssize_t num_found)
4829 Py_ssize_t num_expected;
4830 const char *number, *more_or_less;
4832 if (num_found < num_min) {
4833 num_expected = num_min;
4834 more_or_less = "at least";
4836 num_expected = num_max;
4837 more_or_less = "at most";
4840 more_or_less = "exactly";
4842 number = (num_expected == 1) ? "" : "s";
4843 PyErr_Format(PyExc_TypeError,
4844 #if PY_VERSION_HEX < 0x02050000
4845 "%s() takes %s %d positional argument%s (%d given)",
4847 "%s() takes %s %zd positional argument%s (%zd given)",
4849 func_name, more_or_less, num_expected, number, num_found);
4853 raise_keyword_required_utility_code = UtilityCode(
4855 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
4858 static INLINE void __Pyx_RaiseKeywordRequired(
4859 const char* func_name,
4862 PyErr_Format(PyExc_TypeError,
4863 #if PY_MAJOR_VERSION >= 3
4864 "%s() needs keyword-only argument %U", func_name, kw_name);
4866 "%s() needs keyword-only argument %s", func_name,
4867 PyString_AS_STRING(kw_name));
4872 raise_double_keywords_utility_code = UtilityCode(
4874 static void __Pyx_RaiseDoubleKeywordsError(
4875 const char* func_name, PyObject* kw_name); /*proto*/
4878 static void __Pyx_RaiseDoubleKeywordsError(
4879 const char* func_name,
4882 PyErr_Format(PyExc_TypeError,
4883 #if PY_MAJOR_VERSION >= 3
4884 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
4886 "%s() got multiple values for keyword argument '%s'", func_name,
4887 PyString_AS_STRING(kw_name));
4892 #------------------------------------------------------------------------------------
4894 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
4895 # were passed to a function, or if any keywords were passed to a
4896 # function that does not accept them.
4898 keyword_string_check_utility_code = UtilityCode(
4900 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
4901 const char* function_name, int kw_allowed); /*proto*/
4904 static INLINE int __Pyx_CheckKeywordStrings(
4906 const char* function_name,
4911 while (PyDict_Next(kwdict, &pos, &key, 0)) {
4912 #if PY_MAJOR_VERSION < 3
4913 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
4915 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
4917 goto invalid_keyword_type;
4919 if ((!kw_allowed) && unlikely(key))
4920 goto invalid_keyword;
4922 invalid_keyword_type:
4923 PyErr_Format(PyExc_TypeError,
4924 "%s() keywords must be strings", function_name);
4927 PyErr_Format(PyExc_TypeError,
4928 #if PY_MAJOR_VERSION < 3
4929 "%s() got an unexpected keyword argument '%s'",
4930 function_name, PyString_AsString(key));
4932 "%s() got an unexpected keyword argument '%U'",
4933 function_name, key);
4939 #------------------------------------------------------------------------------------
4941 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
4942 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
4943 # keywords will raise an invalid keyword error.
4945 # Three kinds of errors are checked: 1) non-string keywords, 2)
4946 # unexpected keywords and 3) overlap with positional arguments.
4948 # If num_posargs is greater 0, it denotes the number of positional
4949 # arguments that were passed and that must therefore not appear
4950 # amongst the keywords as well.
4952 # This method does not check for required keyword arguments.
4955 parse_keywords_utility_code = UtilityCode(
4957 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
4958 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
4959 const char* function_name); /*proto*/
4962 static int __Pyx_ParseOptionalKeywords(
4964 PyObject **argnames[],
4967 Py_ssize_t num_pos_args,
4968 const char* function_name)
4970 PyObject *key = 0, *value = 0;
4973 PyObject*** first_kw_arg = argnames + num_pos_args;
4975 while (PyDict_Next(kwds, &pos, &key, &value)) {
4976 name = first_kw_arg;
4977 while (*name && (**name != key)) name++;
4979 values[name-argnames] = value;
4981 #if PY_MAJOR_VERSION < 3
4982 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
4984 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
4986 goto invalid_keyword_type;
4988 for (name = first_kw_arg; *name; name++) {
4989 #if PY_MAJOR_VERSION >= 3
4990 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
4991 PyUnicode_Compare(**name, key) == 0) break;
4993 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
4994 strcmp(PyString_AS_STRING(**name),
4995 PyString_AS_STRING(key)) == 0) break;
4999 values[name-argnames] = value;
5001 /* unexpected keyword found */
5002 for (name=argnames; name != first_kw_arg; name++) {
5003 if (**name == key) goto arg_passed_twice;
5004 #if PY_MAJOR_VERSION >= 3
5005 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5006 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5008 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5009 strcmp(PyString_AS_STRING(**name),
5010 PyString_AS_STRING(key)) == 0) goto arg_passed_twice;
5014 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5016 goto invalid_keyword;
5024 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5026 invalid_keyword_type:
5027 PyErr_Format(PyExc_TypeError,
5028 "%s() keywords must be strings", function_name);
5031 PyErr_Format(PyExc_TypeError,
5032 #if PY_MAJOR_VERSION < 3
5033 "%s() got an unexpected keyword argument '%s'",
5034 function_name, PyString_AsString(key));
5036 "%s() got an unexpected keyword argument '%U'",
5037 function_name, key);
5044 #------------------------------------------------------------------------------------
5046 unraisable_exception_utility_code = UtilityCode(
5048 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5051 static void __Pyx_WriteUnraisable(const char *name) {
5052 PyObject *old_exc, *old_val, *old_tb;
5054 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5055 #if PY_MAJOR_VERSION < 3
5056 ctx = PyString_FromString(name);
5058 ctx = PyUnicode_FromString(name);
5060 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5062 PyErr_WriteUnraisable(Py_None);
5064 PyErr_WriteUnraisable(ctx);
5070 #------------------------------------------------------------------------------------
5072 traceback_utility_code = UtilityCode(
5074 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5077 #include "compile.h"
5078 #include "frameobject.h"
5079 #include "traceback.h"
5081 static void __Pyx_AddTraceback(const char *funcname) {
5082 PyObject *py_srcfile = 0;
5083 PyObject *py_funcname = 0;
5084 PyObject *py_globals = 0;
5085 PyObject *empty_string = 0;
5086 PyCodeObject *py_code = 0;
5087 PyFrameObject *py_frame = 0;
5089 #if PY_MAJOR_VERSION < 3
5090 py_srcfile = PyString_FromString(%(FILENAME)s);
5092 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5094 if (!py_srcfile) goto bad;
5096 #if PY_MAJOR_VERSION < 3
5097 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5099 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5103 #if PY_MAJOR_VERSION < 3
5104 py_funcname = PyString_FromString(funcname);
5106 py_funcname = PyUnicode_FromString(funcname);
5109 if (!py_funcname) goto bad;
5110 py_globals = PyModule_GetDict(%(GLOBALS)s);
5111 if (!py_globals) goto bad;
5112 #if PY_MAJOR_VERSION < 3
5113 empty_string = PyString_FromStringAndSize("", 0);
5115 empty_string = PyBytes_FromStringAndSize("", 0);
5117 if (!empty_string) goto bad;
5118 py_code = PyCode_New(
5119 0, /*int argcount,*/
5120 #if PY_MAJOR_VERSION >= 3
5121 0, /*int kwonlyargcount,*/
5124 0, /*int stacksize,*/
5126 empty_string, /*PyObject *code,*/
5127 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5128 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5129 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5130 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5131 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5132 py_srcfile, /*PyObject *filename,*/
5133 py_funcname, /*PyObject *name,*/
5134 %(LINENO)s, /*int firstlineno,*/
5135 empty_string /*PyObject *lnotab*/
5137 if (!py_code) goto bad;
5138 py_frame = PyFrame_New(
5139 PyThreadState_GET(), /*PyThreadState *tstate,*/
5140 py_code, /*PyCodeObject *code,*/
5141 py_globals, /*PyObject *globals,*/
5142 0 /*PyObject *locals*/
5144 if (!py_frame) goto bad;
5145 py_frame->f_lineno = %(LINENO)s;
5146 PyTraceBack_Here(py_frame);
5148 Py_XDECREF(py_srcfile);
5149 Py_XDECREF(py_funcname);
5150 Py_XDECREF(empty_string);
5151 Py_XDECREF(py_code);
5152 Py_XDECREF(py_frame);
5155 'FILENAME': Naming.filename_cname,
5156 'LINENO': Naming.lineno_cname,
5157 'CFILENAME': Naming.cfilenm_cname,
5158 'CLINENO': Naming.clineno_cname,
5159 'GLOBALS': Naming.module_cname,
5160 'EMPTY_TUPLE' : Naming.empty_tuple,
5163 restore_exception_utility_code = UtilityCode(
5165 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5166 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5169 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5170 PyObject *tmp_type, *tmp_value, *tmp_tb;
5171 PyThreadState *tstate = PyThreadState_GET();
5173 tmp_type = tstate->curexc_type;
5174 tmp_value = tstate->curexc_value;
5175 tmp_tb = tstate->curexc_traceback;
5176 tstate->curexc_type = type;
5177 tstate->curexc_value = value;
5178 tstate->curexc_traceback = tb;
5179 Py_XDECREF(tmp_type);
5180 Py_XDECREF(tmp_value);
5184 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5185 PyThreadState *tstate = PyThreadState_GET();
5186 *type = tstate->curexc_type;
5187 *value = tstate->curexc_value;
5188 *tb = tstate->curexc_traceback;
5190 tstate->curexc_type = 0;
5191 tstate->curexc_value = 0;
5192 tstate->curexc_traceback = 0;
5197 #------------------------------------------------------------------------------------
5199 set_vtable_utility_code = UtilityCode(
5201 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5204 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5205 PyObject *pycobj = 0;
5208 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5211 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5224 #------------------------------------------------------------------------------------
5226 get_vtable_utility_code = UtilityCode(
5228 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5231 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5235 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5238 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5239 if (!*(void **)vtabptr)
5252 #------------------------------------------------------------------------------------
5254 init_string_tab_utility_code = UtilityCode(
5256 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5259 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5261 #if PY_MAJOR_VERSION < 3
5262 if (t->is_unicode && (!t->is_identifier)) {
5263 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5264 } else if (t->intern) {
5265 *t->p = PyString_InternFromString(t->s);
5267 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5269 #else /* Python 3+ has unicode identifiers */
5270 if (t->is_identifier || (t->is_unicode && t->intern)) {
5271 *t->p = PyUnicode_InternFromString(t->s);
5272 } else if (t->is_unicode) {
5273 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5275 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5286 #------------------------------------------------------------------------------------
5288 get_exception_utility_code = UtilityCode(
5290 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5293 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5294 PyObject *tmp_type, *tmp_value, *tmp_tb;
5295 PyThreadState *tstate = PyThreadState_GET();
5296 __Pyx_ErrFetch(type, value, tb);
5297 PyErr_NormalizeException(type, value, tb);
5298 if (PyErr_Occurred())
5303 tmp_type = tstate->exc_type;
5304 tmp_value = tstate->exc_value;
5305 tmp_tb = tstate->exc_traceback;
5306 tstate->exc_type = *type;
5307 tstate->exc_value = *value;
5308 tstate->exc_traceback = *tb;
5309 /* Make sure tstate is in a consistent state when we XDECREF
5310 these objects (XDECREF may run arbitrary code). */
5311 Py_XDECREF(tmp_type);
5312 Py_XDECREF(tmp_value);
5324 #------------------------------------------------------------------------------------
5326 reset_exception_utility_code = UtilityCode(
5328 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5329 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5332 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5333 PyThreadState *tstate = PyThreadState_GET();
5334 *type = tstate->exc_type;
5335 *value = tstate->exc_value;
5336 *tb = tstate->exc_traceback;
5342 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5343 PyObject *tmp_type, *tmp_value, *tmp_tb;
5344 PyThreadState *tstate = PyThreadState_GET();
5345 tmp_type = tstate->exc_type;
5346 tmp_value = tstate->exc_value;
5347 tmp_tb = tstate->exc_traceback;
5348 tstate->exc_type = type;
5349 tstate->exc_value = value;
5350 tstate->exc_traceback = tb;
5351 Py_XDECREF(tmp_type);
5352 Py_XDECREF(tmp_value);
5357 #------------------------------------------------------------------------------------